我无法解决我认为应该是微不足道的事情。我修改了 PLY 的 calc 示例以包含一些函数调用,以及一个可以接受一个或多个表达式的参数列表(表达式是名称、数字或文字)。问题是我的实现是不确定的,有时多行参数正确,有时则不正确。
例如,我在运行时输入:
currentDoc(2,5)
有时如果我运行它,它会产生这个:
calc > currentDoc(2,5)
p_expression_number
p_expression_number
p_expression_function
its in there: [2, 5]
其他时候我运行程序,它会产生这个(我想避免):
calc > currentDoc(2,5)
Syntax error at ','
p_expression_number
解析器两次都进入正确的规则(p_expression_number),但有时它选择了错误的东西。有一半时间它似乎只是简化为表达式(忽略逗号),然后抱怨它不理解下一个参数,即逗号。其他时候还好。
我该如何解决这个问题?我已经尝试了几件事,并且查找了示例,但我无法弄清楚。
这是我的代码:
tokens = ( 'NAME','NUMBER', 'EQUALS', 'COMMA', 'DOT', 'LITERAL', 'LPAREN','RPAREN', )
t_EQUALS = r'='
t_LPAREN = r'\('
t_RPAREN = r'\)'
t_COMMA = r','
t_DOT = r'.'
t_LITERAL = r'(\'[^\']*\'|"[^"]*")'
t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'
functions = {
'currentDoc',
}
def t_NUMBER(t):
r'\d+'
try:
t.value = int(t.value)
except ValueError:
print("Integer value too large %d", t.value)
t.value = 0
return t
t_ignore = " \t"
def t_newline(t):
r'\n+'
t.lexer.lineno += t.value.count("\n")
def t_error(t):
print("Illegal character '%s'" % t.value[0])
t.lexer.skip(1)
import ply.lex as lex
lex.lex()
names = {}
def p_statement_assign(t):
'statement : NAME EQUALS expression'
print("p_statement_assign")
names[t[1]] = t[3]
def p_statement_expr(t):
'statement : expression'
print("p_statement_expr")
print(t[1])
def p_parameters(t):
'''
parameters : expression
| parameters COMMA expression
'''
if len(t) == 2:
t[0] = [t[1]]
else:
t[0] = t[1]
t[0].append(t[3])
def p_expression_function(t):
'''
statement : NAME LPAREN parameters RPAREN
statement : NAME DOT NAME LPAREN parameters RPAREN
'''
print("p_expression_function")
if t[2] is ".":
print('tis dot')
if t[1] in functions:
print("its in there:", t[3])
else:
print("Function '%s' not defined" % t[1])
def p_expression_literal(t):
'expression : LITERAL'
print("p_literal")
t[0] = t[1][1:-1]
def p_expression_number(t):
'expression : NUMBER'
print("p_expression_number")
t[0] = t[1]
def p_expression_name(t):
'expression : NAME'
print("p_expression_name")
try:
t[0] = names[t[1]]
except LookupError:
print("Undefined name '%s'" % t[1])
t[0] = 0
def p_error(t):
if t:
print("Syntax error at '%s'" % t.value)
import ply.yacc as yacc
yacc.yacc()
while 1:
try: s = input('calc > ')
except EOFError:
break
yacc.parse(s)