2011-07-09 26 views
5

¡Esto no es un duplicado de this question porque la solución no era usar un analizador!Interrelacionando un analizador Yacc/Bison con un programa C++

Tengo un analizador de Bison que puedo ejecutar haciendo ./parser < file_to_parse. Quiero llamar al analizador de Bison desde mi programa C++. Lo que no quiero es hacer system(./parser < file_to_parse) porque eso supondría que el analizador está precompilado y que entonces mi programa completo no sería independiente de la plataforma.

Si tengo una función:

void foo(file_name) { 
    // call parser on file_name 
} 

entonces, ¿cómo se puede hacer esto? ¿Algunas ideas? ¡Creo que es el caso de llamar a yyparse o algo así, pero no voy a conseguir nada con eso!

Gracias :).

Respuesta

1

Eso es precisamente lo que haces: llamas a yyparse(). Usted escribe yylex() de modo que su programa principal pueda especificar su entrada. Presumiblemente su yylex() actual llama a getchar() o algo para leer un caracter; en su lugar, presumiblemente necesitará escribirlo para tomar la información de algún lugar especificado por su programa principal.

+0

Gracias Ernest ... todavía estoy luchando, pero ojalá llegue allí. En realidad, no tengo un yylex() en mi Lexer - Flex crea uno predeterminado que probablemente haga el getchar(). Creo que necesito escribir el mío en el Lexer o algo así. – ale

2

¿Está utilizando una versión adaptada a C++?

Uso el de Alain Coetmeur.

Por el momento, solo tengo el código a mano para emplear flex ++, pero debería mostrar cómo funciona esto.

Cuando ejecuta flex ++, obtendrá un archivo de cabecera y un archivo de implementación para una nueva clase para realizar el análisis sintáctico. Añadir estos a su proyecto, a continuación, escribir:

// Construct new instance of parser 
::lex * plex = new lex(); 

// tell parser what file to parse 
plex->yyin = _wfopen(L"C:/Documents and Settings/All Users/Application Data/QuietWake/eCrew/new_rules_to_be_parsed.txt",L"r"); 

// run the parser 
int lex_return = plex->yylex(); 
+0

Gracias. De hecho, estoy usando el viejo Flex/Bison ... ¡Solo sabía que ayer había C++! ... Definitivamente habría sido mejor usar el que estás usando. Voy a tratar de resolverlo con mis herramientas y, si falla, las veré en C++. Gracias +1. – ale

+0

Recomiendo hacer el cambio ahora. Los nuevos analizadores son compatibles con los antiguos, por lo que no perderá ninguna inversión en scripting. Y la vida será mucho más fácil. – ravenspoint

+0

Estoy atascado así que voy a hacer exactamente eso :). Se marcará como solución si funciona. Gracias. – ale

1

Ésta es C Código pero supongo que será un caso indicativo para C++ también.
Cuando tuvimos que hacer un compilador en la universidad tuvimos que definir el YY_DECL en un archivo .l así:

 
#define YY_DECL int alpha_yylex(yylval_) void *yylval_; 

El int alpha_yylex(yylval_) es la función y la void *yylval es el tipo de parámetro.
Claramente, necesita esto para que el analizador sepa por dónde empezar, también conocido como qué función es la que debe realizar el análisis.

También necesita externar este prototipo de función (extern int alpha_yylex(void *yylval_);) en su archivo .y.
Después de eso, las utilidades Flex/Bison generarán automáticamente los archivos relevantes .c para usted.

En general, .l es para las reglas léxicas y .y es para las reglas gramaticales. Por lo tanto, si usted necesita para obtener el valor de algún lugar se debe definir una unión en .y como esto (un ejemplo):

%union { 

    union { 
     int Integer; 
     double Double; 
     char Character; 
     char* String; 
    } value; 

} 

Luego, dependiendo de las reglas sintácticas y, lo puede hacer yylval.value.String = strdup(yytext) en su .l file y, según sus reglas gramaticales, $$.Double = $1.Double + $3.Double en su archivo .y.

No recuerdo mucho, ya que ha pasado un tiempo que yo he hecho eso, pero supongo que se puede tratar y se puede hacer referencia a la documentación o pedir aquí :)

PS: (tenía una buenas preguntas frecuentes en algún lugar, pero no recuerdo dónde diablos está -> publicaré más tarde si tengo la suerte de encontrarlo xD: D xD)