【发布时间】:2018-11-21 02:18:05
【问题描述】:
我正在使用PLY 来解析自定义定义文件的命令。每行定义一个命令,每个命令都应以保留关键字开头,后跟多个字符串。我已经成功地为语法编写了一个词法分析器和解析器,但是我在从生产中提出 SyntaxError 时遇到了问题。
根据PLY's documentation,这可以简单地通过从解析器规则的主体中抛出SyntaxError:
如有必要,生产规则可以手动强制解析器进入错误恢复。这是通过像这样引发 SyntaxError 异常来完成的:
def p_production(p): 'production : some production ...' raise SyntaxError
当我的代码遇到无效语法时,我的代码会在产品中引发SyntaxError,但是当我运行程序时不会引发此错误。这是一个最小的工作示例:
from ply import lex, yacc
class Parser(object):
# reserved keyword tokens
reserved = {
"r": "R"
}
# top level tokens
tokens = [
'CHUNK',
'NEWLINE'
]
# add reserved tokens
tokens += reserved.values()
# ignore spaces and tabs
t_ignore = ' \t'
def __init__(self):
# lexer and parser handlers
self.lexer = lex.lex(module=self)
self.parser = yacc.yacc(module=self)
def parse(self, text):
# pass text to yacc
self.parser.parse(text, lexer=self.lexer)
# detect new lines
def t_newline(self, t):
r'\n+'
# generate newline token
t.type = "NEWLINE"
return t
def t_CHUNK(self, t):
r'[a-zA-Z0-9_=.:]+'
# check if chunk is a keyword
t.type = self.reserved.get(t.value.lower(), 'CHUNK')
return t
def t_error(self, t):
raise SyntaxError("token error")
def p_instruction_list(self, p):
'''instruction_list : instruction
| instruction_list instruction'''
pass
# match instruction on their own lines
def p_instruction(self, p):
'''instruction : command NEWLINE
| NEWLINE'''
pass
def p_command(self, p):
'''command : R CHUNK CHUNK CHUNK CHUNK'''
# parse command
if p[2] not in ["a", "b"]:
raise SyntaxError("invalid thing")
def p_error(self, p):
raise SyntaxError("parsing error")
if __name__ == "__main__":
parser = Parser()
parser.parse("""
r a text text text
r c text text text
r b text text text
""")
上面的示例运行时没有输出任何内容,这意味着它已经成功解析了文本,即使由于r c text text text 行应该在p_command 中引发语法错误(第二个标记c 无效;仅a 或 b 有效)。
我做错了什么?
【问题讨论】:
标签: python parsing grammar lexer ply