Comportamento atual: 2 * 5 + SUM(1, 2, 3)
[
"2",
"*",
"5",
"+",
"SUM",
"(",
[
"1",
",",
"2",
",",
"3"
],
")"
]
Comportamento desejado : 2 * 5 + SUM(1, 2, 3)
[
"2",
" ",
"*",
" ",
"5",
" ",
"+",
" ",
"SUM",
"(",
[
"1",
",",
" ",
"2",
",",
" ",
"3"
],
")"
]
Gramática para copiar: https://pastebin.com/zpwqT6Uw
Playground PEG.js https://pegjs.org/online
o que estou perdendo?
@futagoza desculpe incomodá-lo, mas é a primeira vez que estou lidando com o PEG.js e esse problema é crítico para mim. Posso pedir-lhe uma pequena dica?
Cumprimentos,
Marek
Tentei analisar sua gramática (ontem e agora), mas como é muito difícil entendê-la (convenções de nomenclatura à parte, o formato, para ser honesto, está em todo lugar), demorei um pouco para encontrar uma solução:
const
retorna [left_space, cnst, right_space]
)[].concat.apply([], con)
Mesmo assim, para ser honesto com você, isso parece uma solução hacky para mim. Você tem um link para uma especificação ou algo assim? Ajudaria saber quais regras posso e não posso alterar para obter o resultado desejado sem a solução hacky acima.
Se não, contanto que você esteja disposto a dedicar um tempo e arrumar a gramática e renomear algumas regras (para que seja mais fácil descobrir o que você quer), então tentarei com prazer outra tentativa 😉
@marek-baranowski - Desculpe, não vi isso até agora. Espero que isso ainda seja útil para você
Se você quiser manter os espaços, apenas trate-os como conteúdo combinável.
Não está muito claro exatamente o que você deseja para dois espaços. Você pode ter uma string de dois espaços ou uma matriz de duas strings de um espaço. Normalmente eu esperaria o primeiro, mas... tudo o que você faz é por personagem
Além disso ... por que você quer caracteres perdidos como esse, exceto para a chamada de função? O analisador deve resumir isso para você.
De qualquer forma
Isto é o que você pediu:
Document = Expression*
Whitespace
= tx:[ \r\n]+ { return tx.join(''); }
Number
= str:[0-9]+ { return str.join(''); }
Oper
= '+'
/ '-'
/ '/'
/ '*'
/ ','
Label
= l:[a-zA-Z]+ { return l.join(''); }
Parens
= '(' Whitespace? ex:Expression* Whitespace? ')' { return ex; }
Expression
= Number
/ Oper
/ Whitespace
/ Label
/ Parens
/ [^()]+
A coisa é, eu não estou super convencido de que é realmente o que você quer. Por exemplo, você pode analisar os números e operadores e retornar uma forma de nó padronizada para cada um:
Document = Expression*
Whitespace
= tx:[ \r\n]+ { return {
ast: 'whitespace', value: tx.join('')
}; }
Number
= str:[0-9]+ { return {
ast: 'number', value: parseInt(str,10)
}; }
Oper
= '+' { return { ast: 'oper', value: 'add' }}
/ '-' { return { ast: 'oper', value: 'subtract' }}
/ '/' { return { ast: 'oper', value: 'divide' }}
/ '*' { return { ast: 'oper', value: 'multiply' }}
/ ',' { return { ast: 'oper', value: 'sequence' }}
Label
= l:[a-zA-Z]+ { return {
ast: 'label', value: l.join('')
}; }
Parens
= '(' Whitespace? ex:Expression* Whitespace? ')' {
return { ast: 'parens', value: ex
}; }
Expression
= Number
/ Oper
/ Whitespace
/ Label
/ Parens
/ [^()]+
Agora você ainda tem seu espaço em branco, mas também tem uma árvore analisada adequada e não precisa escrever um analisador para analisar a saída do analisador, e também é fácil agora começar a adicionar recursos regularizados como números de linha e assim por diante
@marek-baranowski - gostaria de reduzir um pouco o tamanho deste rastreador de problemas
Se o acima é o que você precisa, você consideraria fechar este problema? Obrigado 😄
Se não for, por favor, deixe-me saber por que, e eu vou tentar novamente
@marek-baranowski Outro ping suave :smiley_cat:
Além disso, escrevi um plugin PEG.js pegjs-syntactic-actions para facilitar a depuração de gramáticas e ver especificamente quais caracteres são capturados por qual regra independentemente das ações, que provavelmente é o seu problema aqui, conforme explicado por @StoneCypher.
O raciocínio deste plugin é: Eu acho que muitas vezes/às vezes é difícil entender o resultado global quando não é o que esperamos, porque resulta da combinação de muitas pequenas ações, e encontrar a ação que se comporta mal/estranhamente pode ser demorado. Com este plugin, vemos qual regra captura qual personagem e dá o nome da ação para agir.
oh wow isso é muito legal na verdade
Comentários muito úteis
@marek-baranowski Outro ping suave :smiley_cat:
Além disso, escrevi um plugin PEG.js pegjs-syntactic-actions para facilitar a depuração de gramáticas e ver especificamente quais caracteres são capturados por qual regra independentemente das ações, que provavelmente é o seu problema aqui, conforme explicado por @StoneCypher.
O raciocínio deste plugin é: Eu acho que muitas vezes/às vezes é difícil entender o resultado global quando não é o que esperamos, porque resulta da combinação de muitas pequenas ações, e encontrar a ação que se comporta mal/estranhamente pode ser demorado. Com este plugin, vemos qual regra captura qual personagem e dá o nome da ação para agir.