有关使用YACC解析正则表达式(实际上,我使用PLY)的思想,有些规则是这样的:yacc - 没有运算符的规则的优先级?
expr : expr expr
expr : expr '|' expr
expr : expr '*'
的问题是,第一条规则(串联)必须优先于第二条规则,但不是第三条。
但是,并置规则中没有操作符。
如何在这种情况下正确指定优先顺序?
谢谢!
编辑:
我修改了规则,以避免这个问题,但我仍然好奇,是什么问题。
这里是源代码:
tokens = ['PLEFT', 'PRIGHT', 'BAR', 'ASTERISK', 'NORMAL']
t_PLEFT = r'\('
t_PRIGHT = r'\)'
t_BAR = r'\|'
t_ASTERISK = '\*'
t_NORMAL = r'[a-zA-Z0-9]'
lex.lex()
precedence = (
('left', 'BAR'),
('left', 'CONCAT'),
('left', 'ASTERISK'),
)
def p_normal(p):
'''expr : NORMAL'''
p[0] = p[1]
def p_par(p):
'''expr : PLEFT expr PRIGHT'''
p[0] = p[2]
def p_or(p):
'''expr : expr BAR expr'''
p[0] = ('|', p[1], p[3])
def p_concat(p):
'''expr : expr expr %prec CONCAT'''
p[0] = ('CONCAT', p[1], p[2])
def p_repeat(p):
'''expr : expr ASTERISK'''
p[0] = ('*', p[1])
yacc.yacc()
其的'ab|cd*'
解析结果是('CONCAT', ('|', ('CONCAT', 'a', 'b'), 'c'), ('*', 'd'))
。
谢谢你的回答! – noname
我试过%prec,我不确定为什么,但是用这个,'ab | cd'就像'((ab)| c)d',而不是'(ab)|(cd)'。没有转变/减少冲突的警告。 – noname
@noname优先权可能会非常棘手;除非你发表你的实际语法,否则我不能说出什么是错的。如果通过优先级解决冲突,Ply/yacc不会报告冲突,即使它以您认为不正确的方式解决(因为它假设您写了你的意思)。但恕我直言,明确的语法清晰且毫无问题。 – rici