#javascript #parsing #grammar #recursive-descent #left-recursion
#javascript #синтаксический анализ #грамматика #рекурсивный спуск #левая рекурсия
Вопрос:
Прежде всего, я знаю, что по этой теме уже доступно много ответов и ресурсов. Тем не менее, мне очень сложно понять грамматическую нотацию, которая часто используется в этих ответах. Поэтому я надеялся, что кто-нибудь сможет объяснить это более интуитивно понятным способом.
Я пытаюсь написать простой анализатор рекурсивного спуска для какого-то языка C-типа. Однако я сталкиваюсь с некоторыми проблемами при реализации вызова функции.
Я пытаюсь поддерживать следующий синтаксис:
a(b)
a(b, c)
a(b, c)()
a(b, c)(d)
Как я уже сказал, мне трудно понять часто используемую грамматическую нотацию, поэтому я покажу свою реализацию:
const functionCall = new Expression((parser) => {
parser.expect(expression)
parser.expect('(')
if (parser.optional(expression)) {
while (true) {
if (parser.optional(',')) {
parser.expect(expression)
} else {
break
}
}
}
parser.expect(')')
})
const expression = new Expression((parser) => {
parser.either([functionCall, literal])
})
const literal = new Expression((parser) => {
parser.either([{name: 'string_literal'}, {name: 'number_literal'}, {name: 'identifier'}])
})
Насколько я понимаю, моя грамматика (косвенно?) леворекурсивный, потому что первое, что может быть сопоставлено при вызове функции, может быть вызовом функции. Если это предположение верно, я бы не знал, как устранить эту рекурсию.
Комментарии:
1. Как вы выполняете (повторяющееся) добавление? Это не так уж и отличается.
2. @rici Я предполагаю, что я действительно столкнулся бы с теми же проблемами. Я не очень хорошо знаком с синтаксическим анализом. Я прочитал несколько статей о рекурсивном спуске, но не могу понять, как решать подобные проблемы.
3. В примере кода для анализатора удаленных рабочих столов в Википедии обратите внимание на
while
циклы вterm
иexpression
.