如何在python中设置ply的yacc的优先级?
问题描述:
我需要使用ply从正则表达式创建AST。例如,如果RE是(a | b *)abc,我想将一个缩减的元组作为(':',(':',(':',('|','a',(' *','b')),'a'),'b'),'c')< - ':'表示只是将字符串分成两部分。如何在python中设置ply的yacc的优先级?
这是我的代码。
tokens = (
"SYMBOL",
"LBRACKET",
"RBRACKET",
"STAR",
"UNION"
)
t_ignore = ' \t\n'
t_SYMBOL = r'[a-zA-Z0-9]'
t_LBRACKET = r'\('
t_RBRACKET = r'\)'
t_STAR = r'\*'
t_UNION = r'\|'
def t_error(t):
raise TypeError("Unknown text '%s'" % t.value)
def p_multiple(p) :
'''string : SYMBOL SYMBOL
| string SYMBOL
| string string'''
p[0] = (':', p[1], p[2])
def p_union(p) :
'''string : string UNION string'''
p[0] = ('|', p[1], p[3])
def p_star(p) :
'''string : string STAR'''
p[0] = ('*', p[1])
def p_brackets(p) :
'''string : LBRACKET string RBRACKET'''
p[0] = p[2]
def p_symbol(p) :
'''string : SYMBOL'''
p[0] = p[1]
def p_error(p):
print ("Syntax error at '%s'" % p.value)
lex.lex()
yacc.yacc()
lex.input("(a|b*)abc")
parsed = yacc.parse(RE)
答
我无法直接回答你的问题。不过,你也许可以考虑使用greenery。
>>> from greenery.lego import parse
>>> thingy = parse('(a|b*)abc')
>>> thingy.to_fsm()
fsm(alphabet = {'b', 'c', anything_else, 'a'}, states = {0, 1, 2, 3, 4, 5}, initial = 0, finals = {5}, map = {0: {'b': 2, 'a': 1}, 1: {'b': 4, 'a': 3}, 2: {'b': 2, 'a': 3}, 3: {'b': 4}, 4: {'c': 5}, 5: {}})
我想你可以恢复你想要的东西在地图从每个决赛状态向后递归步进。
如果你反对票,请说明原因。
答
要重新生成此问题,ply允许您设置包含符号优先级的优先级变量。例如:
precedence = (
('left', 'PLUS', 'MINUS'),
('left', 'TIMES', 'DIVIDE'),
)
你可以找到一个完整的教程和文档在这里: http://www.dabeaz.com/ply/ply.html#ply_nn27(我不得不使用寻找合适的地方找到的功能)
[YACC的可能的复制 - 无规则的优先级操作者?](http://*.com/questions/40754644/yacc-precedence-of-a-rule-with-no-operator) – rici