有關使用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