Yacc ist ein Framework, um eigene Interpreter zu erstellen. Prerequisites: * Download [[http://gnuwin32.sourceforge.net/downlinks/flex.php|Flex 2.5.4a]] * Download [[http://downloads.sourceforge.net/gnuwin32/bison-2.4.1-setup.exe|Bison 2.4.1]] * Download [[http://sourceforge.net/projects/dev-cpp/files/Binaries/Dev-C%2B%2B%204.9.9.2/devcpp-4.9.9.2_setup.exe/download?use_mirror=switch|DevC++]] * Install Flex at "C:\GnuWin32" * Install Bison at "C:\GnuWin32" * Install DevC++ at "C:\Dev-Cpp" * Open Environment Variables and dd "C:\GnuWin32\bin;C:\Dev-Cpp\bin;" to path. [[https://www.youtube.com/watch?v=54bo1qaHAfk|Youtube tutorial]] =====Example===== File: calc.l %{ #include "y.tab.h" void yyerror (char *s); int yylex(); %} %% "print" { return print; } "printr" { return printr; } "exit" { return exit_command; } [a-zA-Z] { yylval.id = yytext[0]; return identifier; } [0-9]+ { yylval.num = atoi(yytext); return number; } [0-9]+\.[0-9]+ { yylval.dec = atof(yytext); return decimal; } [ \t\n] ; [-+=;] { return yytext[0]; } . { ECHO; yyerror ("unexpected character"); } %% int yywrap (void) {return 1;} File: calc.y %{ void yyerror (char *s); int yylex(); #include /* C declarations used in actions */ #include #include int symbols[52]; int symbolVal(char symbol); void updateSymbolVal(char symbol, int val); float tof(int i); %} %union {int num; char id; float dec;} /* Yacc definitions */ %start line %token print %token printr %token exit_command %token number %token decimal %token identifier %type line exp term %type assignment %% /* descriptions of expected inputs corresponding actions (in C) */ line : assignment ';' { ; } | exit_command ';' { exit(EXIT_SUCCESS); } | print exp ';' { printf("Printing %d\n", $2); } | printr exp ';' { printf("Printing %f\n", $2); } | line assignment ';' { ; } | line print exp ';' { printf("Printing %d\n", $3); } | line printr exp ';' { printf("Printing %f\n", $3); } | line exit_command ';' { exit(EXIT_SUCCESS); } ; assignment : identifier '=' exp { updateSymbolVal($1,$3); } ; exp : term { $$ = $1;} | exp '+' term { $$ = $1 + $3; } | exp '-' term { $$ = $1 - $3; } ; term : number { $$ = $1; } | decimal { $$ = tof($1); } | identifier { $$ = symbolVal($1); } ; %% /* C code */ float tof(int i) { float f = i + 0.0; return f; } int computeSymbolIndex(char token) { int idx = -1; if(islower(token)) { idx = token - 'a' + 26; } else if(isupper(token)) { idx = token - 'A'; } return idx; } /* returns the value of a given symbol */ int symbolVal(char symbol) { int bucket = computeSymbolIndex(symbol); return symbols[bucket]; } /* updates the value of a given symbol */ void updateSymbolVal(char symbol, int val) { int bucket = computeSymbolIndex(symbol); symbols[bucket] = val; } int main (void) { /* init symbol table */ int i; for(i=0; i<52; i++) { symbols[i] = 0; } return yyparse ( ); } void yyerror (char *s) {fprintf (stderr, "%s\n", s);} Compilation flex calc.l bison -dy calc.y gcc -g lex.yy.c y.tab.c -o calc Example C:\> calc a = 1; b = 2; c = a + b; print c;