我使用ply作为我的lex解析器。我的规格如下:
t_WHILE = r'while'
t_THEN = r'then'
t_ID = r'[a-zA-Z_][a-zA-Z0-9_]*'
t_NUMBER = r'\d+'
t_LESSEQUAL = r'<='
t_ASSIGN = r'='
t_ignore = r' \t' 当我尝试解析以下字符串时:
"while n <= 0 then h = 1"它提供以下输出:
LexToken(ID,'while',1,0)
LexToken(ID,'n',1,6)
LexToken(LESSEQUAL,'<=',1,8)
LexToken(NUMBER,'0',1,11)
LexToken(ID,'hen',1,14) ------> PROBLEM!
LexToken(ID,'h',1,18)
LexToken(ASSIGN,'=',1,20)
LexToken(NUMBER,'1',1,22) 然后,它不能识别令牌,而是将"hen“作为标识符。
有什么想法吗?
发布于 2011-02-17 19:18:44
这不起作用的原因与ply优先匹配令牌的方式有关,首先测试最长的令牌正则表达式。
防止此问题的最简单方法是匹配相同类型的标识符和保留字,并根据匹配选择适当的令牌类型。以下代码类似于ply documentation中的示例
import ply.lex
tokens = [ 'ID', 'NUMBER', 'LESSEQUAL', 'ASSIGN' ]
reserved = {
'while' : 'WHILE',
'then' : 'THEN'
}
tokens += reserved.values()
t_ignore = ' \t'
t_NUMBER = '\d+'
t_LESSEQUAL = '\<\='
t_ASSIGN = '\='
def t_ID(t):
r'[a-zA-Z_][a-zA-Z0-9_]*'
if t.value in reserved:
t.type = reserved[ t.value ]
return t
def t_error(t):
print 'Illegal character'
t.lexer.skip(1)
lexer = ply.lex.lex()
lexer.input("while n <= 0 then h = 1")
while True:
tok = lexer.token()
if not tok:
break
print tok发布于 2012-05-11 00:28:12
PLY根据最长的正则表达式对声明为简单字符串的标记进行优先排序,但声明为函数的标记具有优先顺序。
从文档中:
构建主正则表达式时,规则按以下顺序添加:
因此,另一种解决方案是简单地将您希望优先排序的标记指定为函数,而不是字符串,如下所示:
def t_WHILE(t): r'while'; return t
def t_THEN(t): r'then'; return t
t_ID = r'[a-zA-Z_][a-zA-Z0-9_]*'
t_NUMBER = r'\d+'
t_LESSEQUAL = r'<='
t_ASSIGN = r'='
t_ignore = ' \t'通过这种方式,WHILE和THEN将是第一个添加的规则,您将获得预期的行为。
顺便说一句,您对t_ignore使用了r' \t' (原始字符串),因此Python会将\视为反斜杠。它应该是一个简单的字符串,如上例所示。
https://stackoverflow.com/questions/5022129
复制相似问题