Сдвиг / уменьшение конфликта с аргами и кваргами - PLY

Я пишу парсер для Python-подобного языка, который позволяет передавать функции двух типов аргументов (позиционные и именованные). И, как и в Python, именованный аргумент должен передаваться после позиционного. Я написал для нее грамматику, но в ней есть конфликты сдвига / уменьшения, и я даже не представляю, как написать ее по-другому.

Вот моя грамматика:

optionalcomma : COMMA
              | empty

arguments : posargs
         | posargs COMMA kwargs
         | kwargs
         | empty

posargs : optionalnl languageitem
        | optionalnl languageitem COMMA posargs

kwargs : optionalnl varassign optionalcomma
       | optionalnl varassign COMMA kwargs

Вот, optionalnl необязательный перевод строки, languageitem является базовым объектом, который может быть передан в качестве позиционного аргумента, и varassign это правило присваивания переменной, равное передаче именованного аргумента в функцию. Парсер перебирает аргументы для первой запятой и не знает, какой элемент (kwarg или posarg) будет следовать за запятой; Это проблема. И я полностью застрял здесь, не могу написать правильную грамматику.

Я использую синтаксический анализатор LALR(1) PLY, поэтому советы по использованию синтаксического анализа GLR мне мало помогут.

1 ответ

Решение

Если нет ничего необычного в остальной части вашей грамматики, написание posargs обычным леворекурсивным способом не приведет к конфликту сдвига / уменьшения:

posargs : optionalnl languageitem
        | posargs ',' optionalnl languageitem

Лично я бы написал kwargs влево-рекурсивно.

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