首页 > 解决方案 > PLY - 添加第二条类似行时出现解析错误

问题描述

我正在使用包含以下内容的简单 .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

标签: pythonparsingply

解决方案


您的语法只能识别一个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成为开始符号。


推荐阅读