Нужна помощь в отношении одного LALR(1) анализа
Я пытаюсь разобрать контекстно-свободный язык, называемый Context Free Art. Я создал его парсер в Javascript, используя YACC-подобный генератор парсеров JS LALR(1) JSCC.
Возьмите пример следующего кода CFA (Context Free Art). Этот код является действующим CFA.
startshape A
rule A { CIRCLE { s 1} }
Обратите внимание на A
а также s
в выше. s
это команда для масштабирования CIRCLE
, но A
это просто название этого правила. В грамматике языка я установил s
как знак SCALE
а также A
под маркой STRING
(У меня есть регулярное выражение для совпадения со строкой, и оно находится внизу всех токенов).
Это работает нормально, но в приведенном ниже случае это ломается.
startshape s
rule s { CIRCLE { s 1} }
Это тоже совершенно правильный код, но так как мой анализатор отмечает s
после rule
как SCALE
токен, поэтому он ошибается, говоря, что он ожидал STRING
,
Теперь мой вопрос: есть ли способ переписать правила производства парсера, чтобы учесть это? Связанное правило производства:
rule:
RULE STRING '{' buncha_replacements '}' [* rule(%2, 1) *]
|
RULE STRING RATIONAL '{' buncha_replacements '}' [* rule(%2, 1*%3) *]
;
Одно простое решение, о котором я могу подумать, это создать копию вышеуказанного правила с STRING
заменен на SCALE
, но это только одно из многих подобных правил, которые требуют такого исправления. Кроме того, есть много других терминалов, которые могут быть согласованы с STRING
, Так что это значит слишком много правил!
1 ответ
Да! Наконец решение моей проблемы ударило меня. Все, что мне нужно сделать, это изменить мою вышеупомянутую продукцию, чтобы:-
rule:
RULE user_string '{' buncha_replacements '}' [* rule(%2, 1) *]
|
RULE user_string RATIONAL '{' buncha_replacements '}' [* rule(%2, 1*%3) *]
;
user_string:
STRING | SCALE ;
Это довольно элегантное решение по сравнению с тем, что я упомянул в своем тексте проблемы. Если у кого-то есть лучшее решение, пожалуйста, оставьте комментарий.