Устранение левой рекурсии при синтаксическом анализе вызова функции

#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 .