PLY - 添加第二条相似行时出现解析错误

PLY - Parsing error when adding a second similar line

我正在使用包含以下内容的简单 .txt 文件测试 ply:value = 0.4。解析器按预期工作,但是当我向该文件添加第二行时出现错误:

错误:解析'LexToken(VALUE_KEY,'value',1,15)'

时出现语法错误

我的解析器:

from ply import lex
from ply import yacc
from sys import argv

tokens = ('PROBABILITY',
          'EQUALS',
          'VALUE_KEY',
          'NAME')

t_ignore = ' \t'
t_EQUALS = r'='

reserved = {'value' : 'VALUE_KEY'}

def t_KEYWORD(t):
    r':?[a-zA-z_][a-zA-Z_0-9\-]*'
    t.type = reserved.get(t.value, 'NAME')
    return t

def t_NAME(t):
    r'[a-zA-z_][a-zA-Z_0-9\-]*'
    return t

def t_PROBABILITY(t):
    r'[0-1]\.\d+'
    t.value = float(t.value)
    return t

def t_newline(t):
    r'\n+'
    t.lineno += len(t.value)

def t_error(t):
    print("Error: illegal character '{}'".format(t))
    t.lexer.skip(1)


# build the lexer
lex.lex()

def p_prob_def(p):
    '''prob_def : VALUE_KEY EQUALS PROBABILITY'''
    p[0] = p[3]

def p_error(p):
    print("Error: syntax error when parsing '{}'".format(p))

# build parser
yacc.yacc()

class ToyParser(object):

    @classmethod
    def parse(cls, filename):
        with open(filename, 'r') as file:
            data = ''
            for line in file:
                data += '\n' + line
        return yacc.parse(data)

if __name__=='__main__':
    test = ToyParser.parse(argv[1])
    print(test)

产生错误的输入文件:

value = 0.4 
value = 0.7

您的语法只能识别一个 prob_def。 Ply 解析器,就像许多解析器生成器生成的解析器一样,坚持语法中的起始符号与整个输入匹配(否则,尾随的垃圾将不会被正确识别为错误)。

如果要语法解析多个对象,需要写一个明确的规则:

def p_empty(p):
    '''program :'''
    p[0] = []

def p_program(p): 
    '''program : program prob_def '''
    p[0] = p[1]
    p[0].append(p[2])

那些需要放在prob_def的定义之前,这样program就成为开始符号。