Зубр распознает разные жетоны до и после сокращения - PullRequest
1 голос
/ 27 апреля 2020

RELOP может быть: == | != | < | > | <= | >=

и у меня есть это правило в зубрах, которое должно быть распознано:

??? → ??? ????? ??? 

Это часть кода в папке LEX:

=           {return ASSIGN;}
[<=|>=]                         {return RELOP1;}
[<|>]                           {return RELOP3;}

Это код в моей папке ypp:

%right    ASSIGN
%left     RELOP2
%left     BINOP2
%nonassoc RELOP1
%nonassoc RELOP3

Exp: Exp RELOP1 Exp { output::printProductionRule(46);}
        | Exp RELOP3 Exp { output::printProductionRule(46);}
        | Exp RELOP2 Exp { output::printProductionRule(46);}

Это тест:

int bar() {
    if (bar <= bar >= bar) {
        print("Then you got your associativity wrong");
    }
}

Как вы можете видеть на прикрепленном скриншоте, bison распознает первый '<=' (RELOP1) в IF, прежде чем выполнять уменьшение, но во второй раз он распознает только присвоение! Что вызвало бы это? бизон </p>

спасибо:)

1 Ответ

3 голосов
/ 27 апреля 2020

[<=|>=] - это класс символов , который соответствует только одному символу, в этом случае, если этот символ является одним из <, =, | или >. (Помещение одного и того же символа дважды - =, в данном случае - внутри класса символов разрешено, но безрезультатно.)

Вы хотели "<="|">=".

Если два шаблона соответствуют одной и той же самой длинной строке, flex всегда возвращает первый в определении сканера. Таким образом, первый токен, созданный flex, был <, что соответствует RELOP1, потому что RELOP3 появляется позже в файле; затем он соответствует = как ASSIGN, потому что это происходит раньше.

Я уверен, что Flex выдал предупреждение о том, что правило RELOP3 не может ничего соответствовать. Это предупреждение никогда не следует игнорировать; это почти всегда указывает на ошибку в ваших шаблонах.

Обратите также внимание, что правило RELOP3 также соответствует |, что, вероятно, не то, что вам нужно.

Пожалуйста, прочтите документацию на (f) лекс шаблонов .

...