Грамматика выражения с различными типами данных - PullRequest
1 голос
/ 30 января 2020

Я пишу переводчик для небольшого языка, который имеет дело с векторами. Я использую Flex и Bison.

Векторы объявлены в следующей записи:

v: = <1.4, -2.2, 7>

Таким образом, их компоненты могут также включают отрицательные числа. Поддерживаются операции над этими векторами: сложение, вычитание и скалярное умножение. Таким образом, вы не можете добавить вектор и скаляр, вы не можете вычесть вектор и скаляр, но вы можете умножить вектор и скаляр.

Поскольку отрицательные числа поддерживаются, мой лексический анализатор использует следующее регулярное выражение для сопоставления числа:

[+-]?[0-9]+([.][0-9]+)? {yylval.somedub = atof(yytext); return NUMBER;}

Проблема возникает, когда необходимо проанализировать выражение следующего формата (конечно, та же самая проблема с плюсом):

v-2*v

Способ, которым это должно быть проанализировано это: vector minus (number times vector). Но как только flex видит -2, он интерпретирует его как число, поэтому я получаю vector (number) times vector, что, конечно, не имеет смысла. С другой стороны, если вы напишите v - 2*v, все будет работать нормально, поскольку между - и 2 есть пробел. Часть выражения моей грамматики выглядит следующим образом (я не собираюсь копировать весь код, потому что он довольно большой):

expression:
    expression '+' level_1
    | expression '-' level_1
    | level_1

level_1:
    NUMBER '*' level_1
    | level_1 '*' NUMBER
    | level_2

level_2:
    '(' expression ')'
    | vector //parses the whole <a, b, c, ..> notation, irrelevant for the problem

Я также объявил +, - и * как левоассоциативное, используя

%left '+' '-'
%left '*'

Так как же мне go решить эту проблему? Я не знаю, нужно ли мне как-то изменить ассоциативность или, возможно, восстановить всю грамматику.

Есть идеи?

Спасибо.

1 Ответ

2 голосов
/ 31 января 2020

Если -2 распознается как один токен NUMBER, это означает, что парсер будет видеть v-2 как имя, за которым следует число, и в этот момент на самом деле вы ничего не можете сделать, чтобы получить анализ, который вы хотеть. Поэтому вместо -2 следует распознавать как два токена: знак минуса, за которым следует число.

Чтобы достичь этого, вы можете просто удалить [+-]? из своего регулярного выражения для чисел (я предполагаю, что у вас уже есть правило распознавать + и - самостоятельно).

Теперь вам нужно только настроить грамматику так, чтобы - или + сопровождался числом (или любым выражением, если вы также хотите разрешить что-то вроде -v или -(2+3)).

...