REPL для интерпретатора с использованием Flex / Bison

Я написал интерпретатор для C-подобного языка, используя Flex и Bison для сканера / парсера. Он отлично работает при выполнении полных программных файлов.

Теперь я пытаюсь реализовать REPL в интерпретаторе для интерактивного использования. Я хочу, чтобы он работал как интерпретаторы командной строки в Ruby или ML:

  1. Показать подсказку
  2. Принять одно или несколько операторов в строке
  3. Если выражение является неполным
    1. отображать подсказку о продолжении
    2. , позволяющую пользователю продолжить ввод строк
  4. Когда строка заканчивается полным выражением
    1. отобразить результат вычисления последнего выражения
    2. показать главное приглашение

Моя грамматика начинается с продукции 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 и добавить несколько действий в грамматику Bison. Кроме того, я использую стандартные Flex 2.5.35 и Bison 2.3, которые поставляются с Xcode.)

10
задан lesmana 6 May 2013 в 11:18
поделиться