@hirthwork

Тег jflex в блоге hirthwork

hirthwork

Давайте я вам расскажу как я переизобрёл lookahead в jflex, а вы мне расскажете какой я мудак и как на самом деле надо было делать?
Итак, я решил реализовать калькулятор описанный в туториале по javacc (sic!)
БНФ примерно такая:

Expr        := Term ("+" Term | "-" Term)*
Term        := Exponent ("*" Exponent | "/" Exponent)*
Exponent    := Primary ("^" Primary)*
Primary     := NUMBER | "(" Expr ")" | "-" Primary

Но это для javacc. JavaСС умеет делать lookahead, т.е. если при разборе Term вместо умножения или деления встретили плюс или минус, то считаем что не случилось мэтча и нужно вернуться уровнем выше к разбору Expr.
JFlex так делать не умеет. У него всё straightforward и ты тупо получаешь поток токенов и ебись с ними как хочешь. Соответственно я себе завёл стек, куда возвращал токен, если не случилось мэтча, чтобы мэтчи попыталась выполнить предыдущая функция. Если стек пустой, то читаю токен от лексера, иначе — беру токен из стека.

Собственно весь код можно посмотреть здесь: https://gist.github.com/hir...229a58ec7dd0e833d9ca
Запустить вместе с тестами можно так:

$ java -jar jflex-1.6.1.jar -q --nobak Lexer.lex && javac *.java && java -cp . Calc '-(-(2))' '2+2*2' '2+2*2/2' '2+5*(1+2)-23/2' '2^3^2' '1+2^(3/2*2/3)+1+1+1' '--2' '2^2/2^2' '2^-2'
-(-(2)) = 2.0
2+2*2 = 6.0
2+2*2/2 = 4.0
2+5*(1+2)-23/2 = 5.5
2^3^2 = 64.0
1+2^(3/2*2/3)+1+1+1 = 6.0
--2 = 2.0
2^2/2^2 = 1.0
2^-2 = 0.25

А теперь расскажите мне, какой я мудак и как всё это нужно было делать "по правильному"

hirthwork

То ли я делаю что-то не так, то ли изобретать lookahead — это удел любого кто пытается написать простейший калькулятор на jflex

Добавить пост

Вы можете выбрать до 10 файлов общим размером не более 10 МБ.
Для форматирования текста используется Markdown.