Desidero che il mio yylex()
analizzi una stringa anziché un file o uno standard input. Come posso farlo con Lex e Yacc forniti con Solaris?Come rendere YY_INPUT puntare a una stringa anziché a stdin in Lex & Yacc (Solaris)
risposta
Se si utilizza il vero lex
e non flex
io credo che si può semplicemente definire il proprio
int input(void);
Questo può tornare caratteri da una stringa o quello che volete.
In alternativa, credo che si possa scrivere la stringa in un file e aprire il file nello stream yyin
. Sospetto che ciò funzionerebbe con entrambe le implementazioni.
Se si utilizza Flex, allora penso che si ridefinisce il YY_INPUT()
macro,
Qui è qualcosa che dovrebbe funzionare con qualsiasi applicazione, anche se rischiosa usando 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]
Come è stato detto prima che possa essere fatto attraverso la ridefinizione del input()
- ho usato su AIX, HP-UX e Solaris.
O un altro approccio che uso anch'io è creare una pipe e utilizzare fdopen()
-ed FILE*
come yyin
.
Ridefinire YY_INPUT. Ecco un esempio di lavoro, compilazione ed esecuzione con i comandi
yacc -d parser.y
lex lexer.l
gcc -o myparser *.c
L'input viene letto da globalInputText. È possibile modificare questo esempio in modo che il testo di input globale sia quello che si desidera o da qualsiasi sorgente di input desiderata.
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;
}
un altro approccio è quello di utilizzare yy_scan_string come già accennato nelle risposte legate
- 1. Lex/Yacc per C#?
- 2. Lex e Yacc in PHP
- 3. Utilizzando Yacc e Lex in Xcode
- 4. Motivi per usare le alternative lex/yacc?
- 5. Cerchi una grammatica Java in formato lex/yacc
- 6. Strumenti di analisi haskell - yacc: lex :: happy :?
- 7. come usare yy_scan_string in lex
- 8. Qual è la differenza tra lex/yacc e fslex/fsyacc?
- 9. Qual è la differenza tra Flex/Lex e Yacc/Bison?
- 10. qual è la differenza tra lex e yacc
- 11. come posso puntare PHP glob a una directory specifica?
- 12. Come posso leggere il contenuto di stdin (fino a EOF) in una stringa in PHP?
- 13. Creazione di un progetto C++ in CodeBlocks/Eclipse che utilizza yacc e lex
- 14. La tabella TAGS di Emacs è confusa dalla direttiva #line nei file lex/yacc
- 15. Come faccio a puntare Crystal Reports su un nuovo database
- 16. Un puntatore vuoto può puntare a una funzione lambda?
- 17. Buon generatore di parser (si pensi a lex/yacc o antlr) per .NET? Costruisci solo il tempo?
- 18. Windows equivalente a "/ dev/stdin"?
- 19. Rendere YACC in uscita un AST (token tree)
- 20. Come faccio a forzare eof su stdin?
- 21. Un puntatore può alternativamente puntare a una classe const const o a una classe non const?
- 22. Come puntare ApiGateway a uno specifico alias Lambda
- 23. Come rendere DataReader ricominciare a leggere dall'inizio a una condizione?
- 24. come rendere più stringhe di linea a stringa singola riga?
- 25. Come posso passare una stringa a git log -S anziché solo una parola?
- 26. in lex come far sì che yyin punti ad un file con la funzione principale in yacc?
- 27. reindirizzare a una determinata pagina anziché:
- 28. Come puntare il puntatore a due o più celle consecutive
- 29. Stringa di tubi in data GNU per la conversione: come si fa a leggere da stdin?
- 30. Dove impostare LD_LIBRARY_PATH su Solaris?
Vedere anche [Come analizzare da una stringa ra ther than a file] (http://stackoverflow.com/questions/1909166/how-to-parse-from-a-string-rather-than-a-file). –
Vedere anche http://stackoverflow.com/q/1907847/15168. –