Думая о разборе регулярных выражений с помощью Yacc (я на самом деле с помощью корда), некоторые из правил будет иметь следующий вид:yacc - Приоритет правила без оператора?
expr : expr expr
expr : expr '|' expr
expr : expr '*'
Проблема, первое правило (конкатенация) должны иметь приоритет над второе правило, но не третье.
Однако в правиле конкатенации в нем нет оператора.
Как я могу правильно определить приоритет в этом случае?
Спасибо!
EDIT:
Я изменил правила, чтобы избежать проблемы, но я все еще интересно, в чем была проблема.
Вот исходный код:
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