Как я должен изменить грамматику, чтобы разрешить необязательное выражение без возврата

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

filling = fill? align
fill = .
align = [<>=^]

и оно должно соответствовать следующему:

<
0<
<<

Тем не менее, PEG.js не позволяет откат и fill просто потребляется < персонаж:

<    (does not work)
0<   (works)
<<   (works)

Как мне изменить грамматику, чтобы она работала?

1 ответ

Решение

PEG.js не позволяет вернуться

Это не совсем верно. Следующий код работает так, как вы хотите:

filling = fill align / align

Причина того, что это работает, и версия с ? не означает, что возврат осуществляется только по альтернативам в рамках одного правила. То есть, если один из вариантов потерпит неудачу, синтаксический анализатор откатывает и пробует следующий вариант до тех пор, пока альтернатива не совпадет или все альтернативы не будут исчерпаны. Однако парсер не пытается использовать другие альтернативы в подправиле, которое уже успешно выполнено. Так в fill? align, если fill? успешно сопоставляя <, он не будет пытаться найти альтернативу совпадению с пустой строкой, когда align не соответствует потом. Но в fail align / align, если fail align не удается, потому что align терпит неудачу, он пробует следующую альтернативу, которая затем успешна.

Такое поведение означает, что вы можете часто возвращаться назад, вставляя подчиненные правила или, как в этом случае, "встраивая" такие операторы, как ?,

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