Quiero que mi yylex()
analice una cadena en lugar de un archivo o una entrada estándar. ¿Cómo puedo hacerlo con Lex y Yacc con Solaris?Cómo hacer que YY_INPUT apunte a una cadena en lugar de stdin en Lex & Yacc (Solaris)
Respuesta
Si está utilizando el verdadero lex
y no flex
creo que simplemente puede definir su propio
int input(void);
Esto puede devolver caracteres de una cadena o como se quiera.
Como alternativa, creo que podría escribir la cadena en un archivo y abrir el archivo en la secuencia yyin
. Sospecho que esto funcionaría con cualquiera de las implementaciones.
Si se utiliza la flexión entonces creo que redefinir la YY_INPUT()
macro,
Aquí es algo que debería funcionar con cualquier aplicación, aunque arriesgada mediante el uso de popen.
$ cat a.l
%%
"abc" {printf("got ABC\n");}
"def" {printf("got DEF\n");}
. {printf("got [%s]\n", yytext);}
%%
int main(int argc, char **argv)
{
return(lex("abcdefxyz"));
}
lex(char *s)
{
FILE *fp;
char *cmd;
cmd=malloc(strlen(s)+16);
sprintf(cmd, "/bin/echo %s", s); // major vulnerability here ...
fp=popen(cmd, "r");
dup2(fileno(fp), 0);
return(yylex());
}
yywrap()
{
exit(0);
}
$ ./a
got ABC
got DEF
got [x]
got [y]
got [z]
Como se dijo antes de que pueda hacerse a través de la redefinición de la input()
- Lo he utilizado en AIX, HP-UX y Solaris.
O bien, otro enfoque que yo también uso es hacer una tubería, y use fdopen()
-ed FILE*
como yyin
.
Redefina YY_INPUT. Aquí hay un ejemplo de trabajo, compilar y ejecutar con los comandos
yacc -d parser.y
lex lexer.l
gcc -o myparser *.c
La entrada se lee de globalInputText. Puede modificar este ejemplo para que el texto de entrada global sea la cadena que desee o desde cualquier fuente de entrada que desee.
parser.y:
%{
#include <stdio.h>
extern void yyerror(char* s);
extern int yylex();
extern int readInputForLexer(char* buffer,int *numBytesRead,int maxBytesToRead);
%}
%token FUNCTION_PLUS FUNCTION_MINUS NUMBER
%%
expression:
NUMBER FUNCTION_PLUS NUMBER { printf("got expression! Yay!\n"); }
;
%%
lexer.l:
%{
#include "y.tab.h"
#include <stdio.h>
#undef YY_INPUT
#define YY_INPUT(b,r,s) readInputForLexer(b,&r,s)
%}
DIGIT [0-9]
%%
\+ { printf("got plus\n"); return FUNCTION_PLUS; }
\- { printf("got minus\n"); return FUNCTION_MINUS; }
{DIGIT}* { printf("got number\n"); return NUMBER; }
%%
void yyerror(char* s) {
printf("error\n");
}
int yywrap() {
return -1;
}
myparser.c:
#include <stdio.h>
#include <string.h>
int yyparse();
int readInputForLexer(char *buffer, int *numBytesRead, int maxBytesToRead);
static int globalReadOffset;
// Text to read:
static const char *globalInputText = "3+4";
int main() {
globalReadOffset = 0;
yyparse();
return 0;
}
int readInputForLexer(char *buffer, int *numBytesRead, int maxBytesToRead) {
int numBytesToRead = maxBytesToRead;
int bytesRemaining = strlen(globalInputText)-globalReadOffset;
int i;
if (numBytesToRead > bytesRemaining) { numBytesToRead = bytesRemaining; }
for (i = 0; i < numBytesToRead; i++) {
buffer[i] = globalInputText[globalReadOffset+i];
}
*numBytesRead = numBytesToRead;
globalReadOffset += numBytesToRead;
return 0;
}
otro enfoque es utilizar yy_scan_string como ya se ha mencionado en las respuestas vinculadas
- 1. en lex cómo hacer que yyin apunte a un archivo con la función principal en yacc?
- 2. Lex/Yacc para C#?
- 3. Lex y Yacc en PHP
- 4. Uso de Yacc y Lex en Xcode
- 5. yacc/lex o codificación manual?
- 6. Buscando una gramática de Java en formato lex/yacc
- 7. Haskell herramientas de análisis - yacc: lex :: feliz :?
- 8. Ventajas de Antlr (frente a decir, lex/yacc/bison)
- 9. ¿Hay algún Lex y Yacc IRC activo?
- 10. cómo usar yy_scan_string en lex
- 11. Creación de un proyecto de C++ en CodeBlocks/Eclipse que usa yacc y lex
- 12. Cadena de tuberías a GNU Fecha de conversión: ¿cómo hacer que se lea desde stdin?
- 13. ¿cuál es la diferencia entre la lex y yacc
- 14. Usos apropiados para yacc/byacc/bison y lex/flex
- 15. ¿Cuál es la diferencia entre Flex/Lex y Yacc/Bison?
- 16. Google App Engine: ¿puedo hacer que www.domain.com apunte a la versión X y beta.domain.com apunte a la versión Y?
- 17. La directiva #line confunde la tabla Emacs TAGS en archivos lex/yacc
- 18. Cambiar @RenderBody para que apunte a una vista diferente MVC3
- 19. ¿Cómo hacer que un mapa de google apunte de manera predeterminada a los EE. UU.?
- 20. Hacer que el cuadro de diálogo de selección de imágenes TinyMCE apunte a una carpeta predeterminada en Plone
- 21. ¿Es posible tener dos o más analizadores Lex/Yacc en la misma aplicación?
- 22. ¿Cómo hacer que STL arroje excepciones en lugar de aserciones?
- 23. Expresión regular para un literal de cadena en flex/lex
- 24. ¿Cómo escribo una coincidencia no codiciosa en LEX/FLEX?
- 25. ¿Dónde establecer LD_LIBRARY_PATH en Solaris?
- 26. Análisis YAML - ¿Lex o laminado a mano?
- 27. Calcule x/y apunte que 2 bolas en movimiento colisionarán
- 28. ¿Cómo convertir contenido STDIN a una matriz?
- 29. ¿Cómo hacer que Jersey use SLF4J en lugar de JUL?
- 30. Apunte varios dominios a un sitio web en IIS7
Ver también [Cómo analizar desde una cadena ra más que un archivo] (http://stackoverflow.com/questions/1909166/how-to-parse-from-a-string-rather-than-a-file). –
Vea también http://stackoverflow.com/q/1907847/15168. –