У меня есть следующая грамматика парсера (это небольшой пример):
expr:
ident assignop expr
{
$$ = new NAssignment(new NAssignmentIdentifier(*$1), $2, *$3);
} |
STAR expr %prec IDEREF
{
$$ = new NDereferenceOperator(*$2);
} |
STAR expr assignop expr %prec IDEREF
{
$$ = new NAssignment(new NAssignmentDereference(*$2), $3, *$4);
} |
... ;
...
assignop:
ASSIGN_EQUAL |
ASSIGN_ADD |
ASSIGN_SUBTRACT |
ASSIGN_MULTIPLY |
ASSIGN_DIVIDE ;
Теперь я пытаюсь разобрать любую из следующих строк:
*0x8000 = 0x7000;
*mem = 0x7000;
Однако Bison продолжает видеть «*mem» и сокращает правило «STAR expr» и не выполняет предварительный просмотр, чтобы увидеть, соответствует ли «STAR expr assignop...». Насколько я понимаю, Bison должен делать это с опережением. Мое ближайшее предположение состоит в том, что %prec отключает просмотр вперед или что-то в этом роде странное, но я не понимаю, почему это происходит (поскольку значения prec эквивалентны).
Как мне заставить его выполнять просмотр вперед в этом случае?
ИЗМЕНИТЬ:
Состояние, в которое он входит при встрече с «STAR expr», следующее:
state 45
28 expr: STAR expr .
29 | STAR expr . assignop expr
35 | expr . binaryop expr
$default reduce using rule 28 (expr)
assignop go to state 81
binaryop go to state 79
Поэтому я не понимаю, почему он выбирает $default, когда он может выбрать assignop (обратите внимание, что порядок правил в файле parser.y не влияет на то, какой из них он выбирает в этом случае; я пытался изменить порядок assignop выше стандартного «STAR expr»).