Pregunta

Perdóname, soy completamente nuevo en el análisis y lex / yacc, y probablemente estoy muy por encima de mi cabeza, pero no obstante:

Estoy escribiendo una calculadora bastante básica con PLY, pero su entrada puede no ser siempre una ecuación, y necesito determinar si es o no al analizar. Los extremos de la entrada serían algo que se evalúa perfectamente como una ecuación, que analiza y calcula bien, o algo que no se parece en nada a una ecuación, que falla el análisis y también está bien.

El área gris es una entrada que tiene partes similares a ecuaciones, de las cuales el analizador tomará y resolverá. Esto no es lo que quiero: necesito saber si partes de la cadena no se recogieron y se tokenizaron para poder devolver un error, pero no tengo idea de cómo hacerlo.

¿Alguien sabe cómo puedo definir, básicamente, un token 'atrapar todo lo que queda'? ¿O hay una mejor manera de manejar esto?

¿Fue útil?

Solución

Hay un token error incorporado en yacc. Normalmente haría algo como:

línea: goodline | badline;

badline: error '\ n' / * Acción de manejo de errores, si es necesario * /

goodline: ecuación '\ n';

Cualquier línea que no coincida con la ecuación será manejada por badline .

Es posible que desee utilizar yyerrok en la acción de manejo de errores para garantizar que el procesamiento de errores se restablezca para la siguiente línea.

Otros consejos

Defina un token (final de entrada) y haga que su lexer lo envíe al final de la entrada.

Entonces, antes, si tuviera estos tokens:

'1' 'PLUS' '1'

Ahora tendrá:

'1' 'PLUS' '1' 'END_OF_INPUT'

Ahora, puede definir su regla de nivel superior en su analizador. En lugar de (por ejemplo):

Equation ::= EXPRESSION

Tendrás

Equation ::= EXPRESSION END_OF_INPUT

Obviamente, tendrá que volver a escribirlos en la sintaxis PLY, pero esto debería ayudarlo la mayor parte del camino.

Normalmente uso un 'lector de comandos' separado para obtener un comando completo, probablemente una línea en su caso, en una cadena variable de host, y luego organizo para que el analizador léxico analice la cadena, incluido el decirme cuándo no t llegar al final. Esto es difícil de configurar, pero facilita algunas clases de informes de errores. Uno de los lugares en los que he usado esta técnica rutinariamente tiene comandos de varias líneas con 3 convenciones de comentarios, dos conjuntos de cadenas entre comillas y algunas otras cosas desagradables para poner los dientes al límite (tokenización sensible al contexto, ¡qué asco!).

De lo contrario, el consejo de Don con el token 'error' de Yacc es bueno.

Parece que ya ha encontrado una solución, pero agregaré otra sugerencia en caso de que usted u otros estén interesados ??en un enfoque alternativo.

¿Dices que estás usando PLY pero es porque quieres que el compilador se ejecute en un entorno Python? Si es así, podría considerar otras herramientas también. Para tales trabajos, a menudo uso ANTLR ( http://www.antlr.org ) que tiene un generador de código Python . ANTLR tiene muchos trucos para hacer cosas como comer un montón de información a nivel lexer para que el analizador nunca lo vea (por ejemplo, comentarios), la capacidad de llamar una sub-regla (por ejemplo, ecuación) dentro de una gramática más grande (que debería terminar una vez que la regla se ha emparejado sin procesar más entradas ... suena un poco como lo que quieres hacer) y un muy buen algoritmo de factorización a la izquierda.

Capacidad de análisis ANTLRs combinada con el uso de StringTemplate ( http://www.stringtemplate.org ) motor hace una buena combinación y ambos admiten Python (entre muchos otros).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top