как насчет правой рекурсии: top_level = оператор top_level | заявление
исал переводчик для C-подобного языка, используя Flex и Bison для сканера / анализатора. Работает нормально при выполнении полных программных файлов.
Сейчас я пытаюсь реализовать REPL в интерпретаторе для интерактивного использования. Я хочу, чтобы он работал как интерпретаторы командной строки в Ruby или ML:
Показать подсказкуПринять одно или несколько утверждений на линииЕсли выражение неполноеотобразить подсказку продолженияразрешить пользователю продолжать вводить строкиКогда строка заканчивается полным выражениемповторить результат оценки последнего выраженияпоказать основной запросМоя грамматика начинается сtop_level
производство, которое представляет собой одно утверждение на языке. Лексер настроен для интерактивного режима на стандартный ввод. Я использую один и тот же сканер и грамматику как в режиме полного файла, так и в режиме REPL, потому что между двумя интерфейсами нет семантической разницы.
Мой основной цикл оценки построен следующим образом.
while (!interpreter.done) {
if (interpreter.repl)
printf(prompt);
int status = yyparse(interpreter);
if (status) {
if (interpreter.error)
report_error(interpreter);
}
else {
if (interpreter.repl)
puts(interpreter.result);
}
}
Это прекрасно работает, за исключением логики подсказок и эха. Если пользователь вводит несколько операторов в строке, этот цикл выводит лишние подсказки и выражения. И если выражение продолжается в несколько строк, этот код не выводит подсказки продолжения. Эти проблемы возникают из-за гранулярности логики подсказок / эхоtop_level
утверждение в грамматике, но логика чтения строк глубоко в лексере.
Каков наилучший способ реструктурировать цикл оценки для обработки запросов и ответов на запросы REPL? Это:
как я могу отобразить один запрос на строкукак я могу отобразить подсказку продолжения в нужное времякак я могу сказать, когда полное выражение является последним в строке(Я бы предпочел не менять язык сканера для передачи токенов новой строки, поскольку это серьезно изменит грамматику.YY_INPUT
и добавление нескольких действий к грамматике зубров было бы хорошо. Кроме того, я использую стандартные Flex 2.5.35 и Bison 2.3, которые поставляются с Xcode.)