├── README.md ├── example1.l ├── example2.l ├── example3.l ├── example3.txt ├── example4.l ├── example4.y ├── example5.l ├── example5.y ├── example6.l ├── example6.txt ├── example6.y ├── example7.l └── example7.y /README.md: -------------------------------------------------------------------------------- 1 | # Lex and YACC examples 2 | 3 | Practice code for examples in [Lex and YACC primer/HOWTO](https://ds9a.nl/lex-yacc/cvs/output/lexyacc.html) of myself. 4 | 5 | ### Compile Guide 6 | 7 | #### Example1 8 | ``` 9 | lex example1.l 10 | cc lex.yy.c -o example1 -ll 11 | ``` 12 | 13 | #### Example2 14 | ``` 15 | lex example2.l 16 | cc lex.yy.c -o example2 -ll 17 | ``` 18 | 19 | #### Example3 20 | ``` 21 | lex example3.l 22 | cc lex.yy.c -o example3 -ll 23 | 24 | cat example3.txt | ./example3 25 | ``` 26 | 27 | #### Example4 28 | ``` 29 | lex example4.l 30 | yacc -d example4.y 31 | cc lex.yy.c y.tab.c -o example4 32 | ``` 33 | 34 | #### Example5 35 | ``` 36 | lex example5.l 37 | yacc -d example5.y 38 | cc lex.yy.c y.tab.c -o example5 39 | ``` 40 | 41 | #### Example6 42 | ``` 43 | lex example6.l 44 | yacc -d example6.y 45 | cc lex.yy.c y.tab.c -o example6 46 | 47 | cat example6.txt | ./example6 48 | ``` 49 | 50 | #### Example7 51 | ``` 52 | lex example7.l 53 | yacc -d example7.y 54 | cc lex.yy.c y.tab.c -o example7 55 | ``` -------------------------------------------------------------------------------- /example1.l: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | %} 4 | %% 5 | stop printf("Stop command received\n"); 6 | start printf("Start command received\n"); 7 | %% 8 | -------------------------------------------------------------------------------- /example2.l: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | %} 4 | %% 5 | [0-9]+ printf("NUMBER\n"); 6 | [a-zA-Z][a-zA-Z0-9]* printf("WORD\n"); 7 | %% 8 | -------------------------------------------------------------------------------- /example3.l: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | %} 4 | 5 | %% 6 | [a-zA-Z][a-zA-Z0-9]* printf("WORD "); 7 | [a-zA-Z0-9\/.-]+ printf("FILENAME "); 8 | \" printf("QUOTE "); 9 | \{ printf("OBRACE "); 10 | \} printf("EBRACE "); 11 | ; printf("SEMICOLON "); 12 | \n printf("\n"); 13 | [ \t]+ /* ignore whitespace */; 14 | %% -------------------------------------------------------------------------------- /example3.txt: -------------------------------------------------------------------------------- 1 | logging { 2 | category lame-servers { null; }; 3 | category cname { null; }; 4 | }; 5 | 6 | zone "." { 7 | type hint; 8 | file "/etc/bind/db.root"; 9 | }; -------------------------------------------------------------------------------- /example4.l: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | #include "y.tab.h" 4 | %} 5 | %% 6 | [0-9]+ return NUMBER; 7 | heat return TOKHEAT; 8 | on|off return STATE; 9 | target return TOKTARGET; 10 | temperature return TOKTEMPERATURE; 11 | \n /* ignore end of line */; 12 | [ \t]+ /* ignore whitespace */; 13 | %% -------------------------------------------------------------------------------- /example4.y: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | #include 4 | 5 | void yyerror(const char *str) 6 | { 7 | fprintf(stderr, "error: %s\n", str); 8 | } 9 | 10 | int yywrap() 11 | { 12 | return 1; 13 | } 14 | 15 | main() 16 | { 17 | yyparse(); 18 | } 19 | 20 | %} 21 | 22 | %token NUMBER TOKHEAT STATE TOKTARGET TOKTEMPERATURE 23 | 24 | %% 25 | 26 | commands: /* empty */ 27 | |commands command 28 | ; 29 | 30 | command: 31 | heat_switch 32 | | 33 | target_set 34 | ; 35 | 36 | heat_switch: 37 | TOKHEAT STATE 38 | { 39 | printf("\tHeat turned on or off\n"); 40 | } 41 | ; 42 | 43 | target_set: 44 | TOKTARGET TOKTEMPERATURE NUMBER 45 | { 46 | printf("\tTemperature set\n"); 47 | } 48 | ; -------------------------------------------------------------------------------- /example5.l: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | #include "y.tab.h" 4 | %} 5 | %% 6 | [0-9]+ yylval=atoi(yytext);return NUMBER; 7 | heat return TOKHEAT; 8 | on|off yylval=!strcmp(yytext,"on");return STATE; 9 | target return TOKTARGET; 10 | temperature return TOKTEMPERATURE; 11 | \n /* ignore end of line */; 12 | [\t]+ /* ignore whitespace */; 13 | %% 14 | -------------------------------------------------------------------------------- /example5.y: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | #include 4 | 5 | void yyerror(const char *str) 6 | { 7 | fprintf(stderr, "error: %s\n", str); 8 | } 9 | 10 | int yywrap() 11 | { 12 | return 1; 13 | } 14 | 15 | main() 16 | { 17 | yyparse(); 18 | } 19 | 20 | %} 21 | 22 | %token NUMBER TOKHEAT STATE TOKTARGET TOKTEMPERATURE 23 | 24 | %% 25 | 26 | commands: /* empty */ 27 | |commands command 28 | ; 29 | 30 | command: 31 | heat_switch 32 | | 33 | target_set 34 | ; 35 | 36 | heat_switch: 37 | TOKHEAT STATE 38 | { 39 | if ($2) 40 | printf("\tHeat turned on\n"); 41 | else 42 | printf("\tHeat turned off\n"); 43 | } 44 | ; 45 | 46 | target_set: 47 | TOKTARGET TOKTEMPERATURE NUMBER 48 | { 49 | printf("\tTemperature set to %d\n", $3); 50 | } 51 | ; -------------------------------------------------------------------------------- /example6.l: -------------------------------------------------------------------------------- 1 | %{ 2 | #define YYSTYPE char * 3 | 4 | #include 5 | #include "y.tab.h" 6 | %} 7 | 8 | %% 9 | 10 | zone return ZONETOK; 11 | file return FILETOK; 12 | [a-zA-Z][a-zA-Z0-9]* yylval=strdup(yytext);return WORD; 13 | [a-zA-Z0-9\/.-]+ yylval=strdup(yytext);return FILENAME; 14 | \" return QUOTE; 15 | \{ return OBRACE; 16 | \} return EBRACE; 17 | ; return SEMICOLON; 18 | \n /* ignore EOL */; 19 | [ \t]+ /* ignore whitespace */; 20 | %% 21 | -------------------------------------------------------------------------------- /example6.txt: -------------------------------------------------------------------------------- 1 | zone "." { 2 | type hint; 3 | file "/etc/bind/db.root"; 4 | }; -------------------------------------------------------------------------------- /example6.y: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | #include 4 | 5 | #define YYSTYPE char * 6 | 7 | int yydebug=0; 8 | 9 | void yyerror(const char *str) 10 | { 11 | fprintf(stderr, "error: %s\n", str); 12 | } 13 | 14 | int yywrap() 15 | { 16 | return 1; 17 | } 18 | 19 | main() 20 | { 21 | yyparse(); 22 | } 23 | 24 | %} 25 | 26 | %token ZONETOK FILETOK WORD FILENAME QUOTE OBRACE EBRACE SEMICOLON 27 | 28 | %% 29 | 30 | commands: 31 | | 32 | commands command SEMICOLON 33 | ; 34 | 35 | command: 36 | zone_set 37 | ; 38 | 39 | zone_set: 40 | ZONETOK quotedname zonecontent 41 | { 42 | printf("Complete zone for '%s' found\n", $2); 43 | } 44 | ; 45 | 46 | zonecontent: 47 | OBRACE zonestatements EBRACE 48 | ; 49 | 50 | quotedname: 51 | QUOTE FILENAME QUOTE 52 | { 53 | $$=$2; 54 | } 55 | ; 56 | 57 | zonestatements: 58 | | 59 | zonestatements zonestatement SEMICOLON 60 | ; 61 | 62 | zonestatement: 63 | statements 64 | | 65 | FILETOK quotedname 66 | { 67 | printf("A zonefile name '%s' was encountered\n", $2); 68 | } 69 | ; 70 | 71 | block: 72 | OBRACE zonestatements EBRACE SEMICOLON 73 | ; 74 | 75 | statements: 76 | | statements statement 77 | ; 78 | 79 | statement: WORD | block | quotedname 80 | -------------------------------------------------------------------------------- /example7.l: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | #include 4 | #include "y.tab.h" 5 | %} 6 | %% 7 | [0-9]+ yylval.number=atoi(yytext);return NUMBER; 8 | heater return TOKHEATER; 9 | heat return TOKHEAT; 10 | on|off yylval.number=!strcmp(yytext,"on");return STATE; 11 | target return TOKTARGET; 12 | temperature return TOKTEMPERATURE; 13 | [a-z0-9]+ yylval.string=strdup(yytext);return WORD; 14 | \n /* ignore end of line */; 15 | [ \t]+ /* ignore whitespace */; 16 | %% -------------------------------------------------------------------------------- /example7.y: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | #include 4 | 5 | void yyerror(const char *str) 6 | { 7 | fprintf(stderr,"error: %s\n",str); 8 | } 9 | 10 | int yywrap() 11 | { 12 | return 1; 13 | } 14 | 15 | main() 16 | { 17 | yyparse(); 18 | } 19 | 20 | char *heater="default"; 21 | 22 | %} 23 | 24 | %token TOKHEATER TOKHEAT TOKTARGET TOKTEMPERATURE 25 | 26 | %union 27 | { 28 | int number; 29 | char *string; 30 | } 31 | 32 | %token STATE 33 | %token NUMBER 34 | %token WORD 35 | 36 | %% 37 | 38 | commands: 39 | | commands command 40 | ; 41 | 42 | command: 43 | heat_switch | target_set | heater_select 44 | 45 | heat_switch: 46 | TOKHEAT STATE 47 | { 48 | if($2) 49 | printf("\tHeater '%s' turned on\n", heater); 50 | else 51 | printf("\tHeat '%s' turned off\n", heater); 52 | } 53 | ; 54 | 55 | target_set: 56 | TOKTARGET TOKTEMPERATURE NUMBER 57 | { 58 | printf("\tHeater '%s' temperature set to %d\n", heater, $3); 59 | } 60 | ; 61 | 62 | heater_select: 63 | TOKHEATER WORD 64 | { 65 | printf("\tSelected heater '%s'\n", $2); 66 | heater=$2; 67 | } 68 | ; --------------------------------------------------------------------------------