Разбирать приложения в стиле лямбда-исчисления с помощью LL1-парсера

Я использую TinyPG, который является генератором парсера LL1, для разбора лямбда-исчисления. Я пытаюсь написать правило, которое будет анализировать функцию приложения, как (a b) или же (a b c) и так далее.

Пока что у меня есть это правило (немного упрощенное):

APPLICATION -> LPARENTHESES VARIABLE (SPACE+ VARIABLE)+ RPARENTHESES;

Но это не сможет проанализировать термин, который имеет пробелы после левых и перед правыми скобками: ( a b ), Я могу разрешить пробелы после открывающей скобки, как это:

APPLICATION -> LPARENTHESES SPACE* VARIABLE (SPACE+ VARIABLE)+ RPARENTHESES;

Но у меня возникли проблемы с настройкой, чтобы оставить пробелы перед закрывающей скобкой. Я пришел с этим, который, кажется, работает:

ARG_LIST        -> (RPARENTHESES | (SPACE+ (RPARENTHESES | (VARIABLE ARG_LIST))));
APPLICATION     -> LPARENTHESES SPACE* VARIABLE ARG_LIST;

Но он беспорядочный и рекурсивный, что затруднит чтение и компиляцию узлов. Есть ли нерекурсивный или хотя бы более простой способ разобрать это?

1 ответ

Решение

Нет смысла путать парсер с пробелами. Достаточно игнорировать его в сканере, используя [Skip] атрибут, как показано в руководстве:

[Skip] WHITESPACE -> @"\s+";

"Пропустить" не означает "удалить". Это означает, что сканер должен распознать токен, а затем проигнорировать его. Если пропустить пробел, пробел все равно будет отлично разделять буквенно-цифровые токены. Вам просто не нужно включать пробел в вашу грамматику, оставляя вас с:

APPLICATION -> LPARENTHESES VARIABLE VARIABLE+ RPARENTHESES;

(На самом деле, пустые списки приложений обычно разрешены, поэтому я бы написал это с * вместо +, Но это твой язык.)

Другие вопросы по тегам