0

我无法解决我认为应该是微不足道的事情。我修改了 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)
4

0 回答 0