我正在阅读lexical parsing文档,以便我可以解析一些参数,并且我完全按照文档创建了一个解析器。这是整个代码:
#!/usr/bin/env python
#-*- coding: utf-8 -*-
import ply.lex as lex
args = ['[watashi]', '[anata]>500', '[kare]>400&&[kare]<800']
tokens = ('NUMBER', 'EXPRESSION', 'AND', 'LESS', 'MORE')
t_EXPRESSION = r'\[.*\]'
t_AND = r'&&'
t_LESS = r'<'
t_MORE = r'>'
t_ignore = '\t'
def t_NUMBER(t):
r'\d+'
t.value = int(t.value)
return t
def t_newline(t):
r'\n+'
t.lexer.lineno += len(t.value)
def t_error(t):
print 'Illegal character "%s"' % t.value[0]
t.lexer.skip(1)
lexer = lex.lex()
for i in args:
lexer.input(i)
while True:
tok = lexer.token()
if not tok: break
print tok
print '#############'
我只是创建了一个示例参数列表,我得到了这个输出:
LexToken(EXPRESSION,'[watashi]',1,0)
#############
LexToken(EXPRESSION,'[anata]',1,0)
LexToken(MORE,'>',1,7)
LexToken(NUMBER,500,1,8)
#############
LexToken(EXPRESSION,'[kare]>400&&[kare]',1,0)
LexToken(LESS,'<',1,18)
LexToken(NUMBER,800,1,19)
#############
第一个和第二个样本参数被正确解析,但第三个不是。第三个示例参数是EXPRESSION + LESS + NUMBER,而它必须是EXPRESSION + MORE + NUMBER + AND + EXPRESSION + LESS + NUMBER。所以我认为可能存在其中一个问题:
ply.lex只解析一个令牌:在上面的代码中,ply.lex无法解析两个单独的表达式,并返回最新的令牌作为其类型。 &#34; [KARE] GT; 400&安培;&安培; [KARE]&#34;是EXPRESSION,因为它以最新的EXPRESSION标记结束,该标记是第二个[kare]而800是NUMBER,因为它是最新的NUMBER标记。
!!!或!!! !!!
t_EXPRESSION变量出错:我将此变量定义为&#34; [。*]&#34;获取这两个括号中的所有字符([])。第三个样本参数的第一个标记是&#34; [kare]&gt; 400&amp;&amp; [kare]&#34;因为它只是以这些括号开头和结尾,并且包含。*(每个字符),但我认为解释器会因为第一个而停在第一个(])字符中。
所以我找不到解决方法但在这里问。
总的来说,这就是我正在努力的事情
lexer.input("[kare]>400&&[kare]<800")
while True:
tok = lexer.token()
if not tok: break
print tok
我得到了
LexToken(EXPRESSION,'[kare]>400&&[kare]',1,0)
LexToken(LESS,'<',1,18)
LexToken(NUMBER,800,1,19)
但我期待更像
的东西LexToken(EXPRESSION,'[kare]',1.0)
LexToken(LESS,'>',?)
LexToken(NUMBER,400,?)
LexToken(AND,'&&',?)
LexToken(EXPRESSION,'[kare]',1,0)
LexToken(LESS,'<',1,18)
LexToken(NUMBER,800,1,19)
答案 0 :(得分:2)
我想我看到了你的问题
t_EXPRESSION = r'\[.*\]'
是贪婪的,会匹配最大的匹配,即'[kare]>400&&[kare]'
而不是尝试
t_EXPRESSION = r'\[[^\]]*\]'
这只会匹配一个集,因为它找不到开括号([^\]]
)而不是任何东西(.
)
你也可以使用不贪心匹配
t_EXPRESSION = r'\[.*?\]'
?
使其匹配尽可能少的字符而不是最大