我一直试图用PLY解析一些给定的文本一段时间,但我无法弄明白。我定义了这些令牌:
tokens = ['ID', 'INT', 'ASSIGNMENT']
我想把我发现的词分类到这些令牌中。例如,如果给出扫描仪:
var = 5
应打印出来:
ID : 'var'
ASSIGNMENT : '='
INT : 5
这很好用。问题是当程序给出以下文本时:
9var = 5
这个的输出是:
INT : 9
ID : 'var'
ASSIGNMENT : '='
INT : 5
这是出错的地方。它应该将9var作为ID,并且根据ID正则表达式,这不是ID的有效名称。这些是我的正则表达式:
def t_ID(t):
r'[a-zA-Z_][a-zA-Z_0-9]*'
return t
def t_INT(t):
r'\d+'
t.value = int(t.value)
return t
t_ASSIGNMENT = r'\='
我该如何解决这个问题?
您的帮助将不胜感激!
答案 0 :(得分:3)
你说:“它应该以{{1}}作为ID”。但是你指出9var
与ID正则表达式模式不匹配。那么为什么要将9var
扫描为ID?
如果您希望9var
成为ID,则可以很容易地将正则表达式从9var
更改为[a-zA-Z_][a-zA-Z_0-9]*
。 (这也将匹配纯整数,因此您需要确保首先应用INT模式。或者,您可以使用[a-zA-Z_0-9]+
。)
我怀疑你真正想要的是[a-zA-Z_0-9]*[a-zA-Z_][a-zA-Z_0-9]*
被识别为词法错误而不是解析错误。但是如果它在任何情况下都会被识别为错误,那么它是一个词法错误还是一个语法错误真的很重要吗?
值得一提的是,Python词法分析器的工作方式与词法分子的工作方式完全相同:它会将9var
扫描为两个标记,稍后会产生语法错误。
当然,在您的语言中,可能存在一些语法正确的结构,其中ID可以直接跟随INT。或者,如果不是,关键字可以直接跟随INT,例如Python表达式9var
。 (同样,如果您将其写为3 if x else 2
,Python不会抱怨。)
因此,如果您真的坚持要为以数字开头并继续使用非数字的令牌标记扫描程序错误,您可以插入另一个模式,例如3if x else 2
,并在其中引发错误动作。