Некоторое время назад мне попалась грамматика lex+yacc для калькулятора комплексных чисел https://github.com/chpoon92/complex-number-calculator-flex-bison Это пример того, как НЕ НАДО использовать эти программы. Достаточно взглянуть в грамматике лексера на правило {ws}*[-]*{ws}*{number}{ws}*[+|-]{ws}*{number}{ws}*{im}{ws}*
На данный момент тут только 2 комбинации: действительная и мнимая часть числа могут идти в разном порядке. А что, если вместо комплексных чисел будут кватернионы, у которых три разновидности комплексных чисел и действительная часть. Мои знания комбинаторики подсказывают, что будет 4!=24 комбинации 😉
Грамматика для калькулятора комплексных чисел тут: https://github.com/dk2k/lex-yacc/tree/main/complex_numbers_calc
Команды для сборки:
lex complex.l
yacc -d complex.y
g++ lex.yy.c y.tab.c -lm
Результаты тестирования:
/home/user/complex/a.out
i + i
Token: I; Lexeme: i
Token and Lexeme: +
Token: I; Lexeme: i
Token and Lexeme:
0.000000 + 2.000000 i
freed 3 pointers
1 + i
Token: NUMBER; Lexeme: 1
Token and Lexeme: +
Token: I; Lexeme: i
Token and Lexeme:
1.000000 + 1.000000 i
freed 3 pointers
(1+i)/(1+i)
Token and Lexeme: (
Token: NUMBER; Lexeme: 1
Token and Lexeme: +
Token: I; Lexeme: i
Token and Lexeme: )
Token and Lexeme: /
Token and Lexeme: (
Token: NUMBER; Lexeme: 1
Token and Lexeme: +
Token: I; Lexeme: i
Token and Lexeme: )
Token and Lexeme:
1.000000 + 0.000000 i
freed 8 pointers
(1+i)*(1+i)
Token and Lexeme: (
Token: NUMBER; Lexeme: 1
Token and Lexeme: +
Token: I; Lexeme: i
Token and Lexeme: )
Token and Lexeme: *
Token and Lexeme: (
Token: NUMBER; Lexeme: 1
Token and Lexeme: +
Token: I; Lexeme: i
Token and Lexeme: )
Token and Lexeme:
0.000000 + 2.000000 i
freed 6 pointers
-i
Token and Lexeme: —
Token: I; Lexeme: i
Token and Lexeme:
-0.000000 + -1.000000 i
freed 2 pointers
-2i + 1
Token: NUMBER; Lexeme: -2
Token: I; Lexeme: i
Token and Lexeme: +
Token: NUMBER; Lexeme: 1
Token and Lexeme:
1.000000 + -2.000000 i
freed 3 pointers
-3i — 1
Token: NUMBER; Lexeme: -3
Token: I; Lexeme: i
Token and Lexeme: —
Token: NUMBER; Lexeme: 1
Token and Lexeme:
-1.000000 + -3.000000 i
freed 2 pointers
1/i
Token: NUMBER; Lexeme: 1
Token and Lexeme: /
Token: I; Lexeme: i
Token and Lexeme:
0.000000 + -1.000000 i
freed 4 pointers
-i -i
Token and Lexeme: —
Token: I; Lexeme: i
Token and Lexeme: —
Token: I; Lexeme: i
Token and Lexeme:
-0.000000 + -2.000000 i
freed 3 pointers
2i/(6+i)
Token: NUMBER; Lexeme: 2
Token: I; Lexeme: i
Token and Lexeme: /
Token and Lexeme: (
Token: NUMBER; Lexeme: 6
Token and Lexeme: +
Token: I; Lexeme: i
Token and Lexeme: )
Token and Lexeme:
0.054054 + 0.324324 i
freed 6 pointers
Строки вида «freed 6 pointers» напоминают о том, что надо чистить память при динамическом выделении с помощью malloc().