Я пишу грамматику для языка LUA, используя синтаксис Antlr, но я получаю ошибку взаимной левой рекурсии между exp_prefixo
, variavel
и chamada_de_funcao
. Я прочитал много решений, приведенных в других сообщениях, но не смог заставить его работать для моего конкретного случая, поскольку большинство из них являются прямыми рекурсиями или имеют только два взаимно рекурсивных правила.
Вот взаимно леворекурсивный набор правил:
exp_prefixo
: variavel
| chamada_de_funcao
| '(' expressao ')'
;
chamada_de_funcao
: exp_prefixo args
| exp_prefixo ':' NOME args
;
variavel
: NOME
| exp_prefixo '[' expressao ']'
| exp_prefixo '.' NOME
;
А это мой файл грамматики:
programa
: trecho
;
trecho
: (comando (';')?)* (ultimo_comando (';')?)?
;
bloco
: trecho
;
comando
: lista_variaveis '=' lista_expressoes
| chamada_de_funcao
| 'do' bloco 'end'
| 'while' expressao 'do' bloco 'end'
| 'repeat' bloco 'until' expressao
| 'if' expressao 'then' bloco ('elseif' expressao 'then' bloco)* ('else' bloco)? 'end'
| 'for' NOME '=' expressao ',' expressao (',' expressao)? 'do' bloco 'end'
| 'for' lista_de_nomes 'in' lista_expressoes 'do' bloco 'end'
| 'function' nome_da_funcao corpo_da_funcao
| 'local' 'function' NOME corpo_da_funcao
| 'local' lista_de_nomes ('=' lista_expressoes)?
;
ultimo_comando
: 'return' (lista_expressoes)?
| 'break'
;
nome_da_funcao
: NOME ('.' NOME)* (':' NOME)?
;
lista_variaveis
: variavel (',' variavel)*
;
variavel
: NOME
| exp_prefixo '[' expressao ']'
| exp_prefixo '.' NOME
;
lista_de_nomes
: NOME (',' NOME)*
;
lista_expressoes
: (expressao ',')* expressao
;
expressao
: 'nil'
| 'false'
| 'true'
| NUMERO
| CADEIA
| '...'
| funcao
| exp_prefixo
| construtor_tabela
| expressao opbin expressao
| opunaria expressao
;
exp_prefixo
: variavel
| chamada_de_funcao
| '(' expressao ')'
;
chamada_de_funcao
: exp_prefixo args
| exp_prefixo ':' NOME args
;
args
: '(' (lista_expressoes)? ')'
| construtor_tabela
| CADEIA
;
funcao
: 'function' corpo_da_funcao
;
corpo_da_funcao
: '(' (lista_par)? ')' bloco 'end'
;
lista_par
: lista_de_nomes (',' '...')?
| '...'
;
construtor_tabela
: '{' (lista_de_campos)? '}'
;
lista_de_campos
: campo (separador_de_campos campo)* (separador_de_campos)?
;
campo
: '[' expressao ']' '=' expressao
| NOME '=' expressao
| expressao
;
separador_de_campos
: ','
| ';'
;
opbin
: '+'
| '-'
| '*'
| '/'
| '^'
| '%'
| '..'
| '<'
| '<='
| '>'
| '>='
| '=='
| '~='
| 'and'
| 'or'
;
opunaria
: '-'
| 'not'
| '#'
;
Может ли кто-нибудь дать несколько советов с некоторыми начальными шагами о том, как устранить эту ошибку? Я уже понял "теоретическую" проблему. Я действительно изо всех сил пытаюсь реализовать решение.
Спасибо!