Comportamiento actual: 2 * 5 + SUM(1, 2, 3)
[
"2",
"*",
"5",
"+",
"SUM",
"(",
[
"1",
",",
"2",
",",
"3"
],
")"
]
Comportamiento deseado : 2 * 5 + SUM(1, 2, 3)
[
"2",
" ",
"*",
" ",
"5",
" ",
"+",
" ",
"SUM",
"(",
[
"1",
",",
" ",
"2",
",",
" ",
"3"
],
")"
]
Gramática para copiar: https://pastebin.com/zpwqT6Uw
Zona de juegos de PEG.js https://pegjs.org/online
¿Qué me estoy perdiendo?
@futagoza siento mucho molestarlo, pero es la primera vez que trato con PEG.js y este problema es fundamental para mí. ¿Puedo pedirte una pequeña pista?
Atentamente,
Marek
Traté de revisar su gramática (ayer y ahora) pero debido a que es realmente difícil de entender (dejando de lado las convenciones de nombres, el formato, para ser honesto, está por todas partes), me tomó un tiempo encontrar una solución:
const
devuelve [left_space, cnst, right_space]
)[].concat.apply([], con)
Aún así, para ser honesto contigo, esto me parece una solución engañosa. ¿Tienes un enlace a una especificación o algo así? Sería útil saber qué reglas puedo y no puedo cambiar para obtener el resultado deseado sin la solución hacky anterior.
Si no, mientras esté dispuesto a dedicar tiempo y ordenar la gramática y cambiar el nombre de algunas reglas (para que sea más fácil descubrir lo que quiere), entonces con gusto intentaré intentarlo de nuevo 😉
@marek-baranowski - Lo siento, no vi esto hasta ahora. Espero que esto todavía te sea útil.
Si desea mantener los espacios, simplemente trátelos como contenido compatible.
No está muy claro exactamente lo que querrías para dos espacios. Puede tener una cadena de dos espacios o una matriz de dos cadenas de un espacio. Normalmente esperaría lo primero, pero... todo lo tuyo es por personaje.
Además ... ¿por qué querrías personajes perdidos como esos, excepto por la llamada a la función? El analizador debería estar resumiéndolos por ti.
De todos modos
Esto es lo que pediste:
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
/ [^()]+
La cosa es que no estoy muy convencido de que sea realmente lo que quieres. Por ejemplo, en su lugar, podría analizar los números y operadores, y devolver una forma de nodo estandarizada para cada uno:
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
/ [^()]+
Ahora todavía tiene su espacio en blanco, pero también tiene un árbol analizado adecuado, y no necesita escribir un analizador para analizar la salida de su analizador, y ahora también es muy fácil comenzar a agregar funciones regularizadas como números de línea, etc.
@marek-baranowski: me gustaría reducir un poco el tamaño de este rastreador de problemas
Si lo anterior es lo que necesita, ¿consideraría cerrar este problema? Gracias 😄
Si no es así, dígame por qué y lo intentaré de nuevo.
@marek-baranowski Otro suave ping :smiley_cat:
Además, escribí un complemento de PEG.js pegjs-syntactic-actions para facilitar la depuración de gramáticas y ver específicamente qué caracteres son capturados por qué regla independientemente de las acciones, lo que probablemente sea su problema aquí, como lo explica @StoneCypher.
El razonamiento de este complemento es: a menudo/a veces es difícil entender el resultado global cuando no es lo que esperamos, porque resulta de la combinación de muchas acciones pequeñas, y encontrar la acción que se comporta mal/extrañamente podría ser pérdida de tiempo. Con este complemento, vemos qué regla captura qué carácter y proporciona el nombre de la acción sobre la que actuar.
oh wow, esto es realmente genial en realidad
Comentario más útil
@marek-baranowski Otro suave ping :smiley_cat:
Además, escribí un complemento de PEG.js pegjs-syntactic-actions para facilitar la depuración de gramáticas y ver específicamente qué caracteres son capturados por qué regla independientemente de las acciones, lo que probablemente sea su problema aquí, como lo explica @StoneCypher.
El razonamiento de este complemento es: a menudo/a veces es difícil entender el resultado global cuando no es lo que esperamos, porque resulta de la combinación de muchas acciones pequeñas, y encontrar la acción que se comporta mal/extrañamente podría ser pérdida de tiempo. Con este complemento, vemos qué regla captura qué carácter y proporciona el nombre de la acción sobre la que actuar.