как насчет правой рекурсии: 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.)

Ответы на вопрос(2)

Ваш ответ на вопрос