HOW TO CHECK YOUR GRAMMAR AND DFA

This is a sample tutorial describes how to check your grammar is in correct order or not and print the DFA states of your grammar using bison and flex in windows environment.

To describe the procedure I’ve got the “simple thermostat controller example” from the “Ivan’s Blog” at “http://ivan215.blogspot.com/2009/04/yacc-yet-another-compiler-compiler.html“.

First we must define our grammar in lex (*.l) and yacc (*.y) files. In this example I named them as “heat.l” and “heat.y” according to the “Ivan’s Blog” because these files are describes a process of heat equipment. (Figure 1)

6235-1 copy

Figure 1


heat.l

%{
#include <stdio.h>
#include "y.tab.h"
%}
%%
[0-9]+ yylval=atoi(yytext); return NUMBER;
heat return TOKHEAT;
on|off yylval=!strcmp(yytext,"on");return STATE;
target return TOKTARGET;
temperature return TOKTEMPERATURE;\n /*ignore end of line*/;
[\t]+ /*ignore whitespace*/;
%%
int yywrap(void)
{
 return 1;
}

 


 

heat.y

%{
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
int lineno =1;
void yyerror(char *str);
%}
%start commands
%token NUMBER TOKHEAT STATE TOKTARGET TOKTEMPERATURE
%%
commands :/*empty*/
|commands command
;
command :heat_switch
|target_set
;
heat_switch :TOKHEAT STATE
{
if($2)
   printf("\tHeat turned on \n");
else
   printf("\tHeat turned off \n");
}
;
target_set :TOKTARGET TOKTEMPERATURE NUMBER
{
   printf("\tTemperature set to %d\n",$3);
}
;
%%
void yyerror(char *str)
{
   fprintf(stderr,"line %d: %s\n",lineno,str);
}
main()
{
   yyparse();
}

 

Then open a terminal and type the following command only for “heat.y” file only (Figure 2)

>bison –dv heat.y   (here the –v parameter for more details type >bison –help)

6235-2 copy

Figure 2

This will generate following output file (Figure 3)

“heat.output”

6235-3 copy

Figure 3

When we open the file using a text editor the file includes the following data

  • Used and unused nonterminals.
  • Used and unused terminals.
  • Grammar rules.
  • And the states of the Finite Automata (DFA).

heat.output

Grammar
rule 1 commands -> /* empty */
rule 2 commands -> commands command
rule 3 command -> heat_switch
rule 4 command -> target_set
rule 5 heat_switch -> TOKHEAT STATE
rule 6 target_set -> TOKTARGET TOKTEMPERATURE NUMBER
Terminals, with rules where they appear
$ (-1)
error (256)
NUMBER (257) 6
TOKHEAT (258) 5
STATE (259) 5
TOKTARGET (260) 6
TOKTEMPERATURE (261) 6
Nonterminals, with rules where they appear
commands (8)
on left: 1 2, on right: 2
command (9)
on left: 3 4, on right: 2
heat_switch (10)
on left: 5, on right: 3
target_set (11)
on left: 6, on right: 4
state 0
$default reduce using rule 1 (commands)
commands go to state 1
state 1
commands -> commands . command (rule 2)
$ go to state 10
TOKHEAT shift, and go to state 2
TOKTARGETshift, and go to state 3
command go to state 4
heat_switch go to state 5
target_set go to state 6
state 2
heat_switch -> TOKHEAT . STATE (rule 5)
STATE shift, and go to state 7
state 3
target_set -> TOKTARGET . TOKTEMPERATURE NUMBER (rule 6)
TOKTEMPERATURE shift, and go to state 8
state 4
commands -> commands command . (rule 2)
$default reduce using rule 2 (commands)
state 5
command -> heat_switch . (rule 3)
$default reduce using rule 3 (command)
state 6
command -> target_set . (rule 4)
$default reduce using rule 4 (command)
state 7
heat_switch -> TOKHEAT STATE . (rule 5)
$default reduce using rule 5 (heat_switch)
state 8
target_set -> TOKTARGET TOKTEMPERATURE . NUMBER (rule 6)
NUMBER shift, and go to state 9
state 9
target_set -> TOKTARGET TOKTEMPERATURE NUMBER . (rule 6)
$default reduce using rule 6 (target_set)
state 10
$ go to state 11
state 11
$default accept

 

If there is an error it will show the errors in (*.output) file as a below (Figure 4)

6235-4 copy

Figure 4

This method is briefly described in page 6 of “LEX & YACC TUTORIAL” by Tom Niemann.

Thank you!

HOW TO CHECK YOUR GRAMMAR AND DFA