This section describes how to use the Gentle system to construct a simple desk calculator. This calculator will read (from standard input or from a specified file) an expression according to the following syntax:
expression ::= expression "+" expr2 | expression "-" expr2 | expr2 expr2 ::= expr2 "*" expr3 | expr2 "/" expr3 | expr3 expr3 ::= Number | "-" expr3 | "+" expr3 | "(" expression ")"where the token Number represents a sequence of decimal digits. The program will calculate the value of the expression and print it on standard output.
Here is a Gentle specification of the calculator (file calc.g). This simply mirrors the above grammar, where each nonterminal has an output parameter that represents its value.
'root' expression(-> X) print(X) 'nonterm' expression(-> INT) 'rule' expression(-> X): expr2(-> X) 'rule' expression(-> X+Y): expression(-> X) "+" expr2(-> Y) 'rule' expression(-> X-Y): expression(-> X) "-" expr2(-> Y) 'nonterm' expr2(-> INT) 'rule' expr2(-> X): expr3(-> X) 'rule' expr2(-> X*Y): expr2(-> X) "*" expr3(-> Y) 'rule' expr2(-> X/Y): expr2(-> X) "/" expr3(-> Y) 'nonterm' expr3(-> INT) 'rule' expr3(-> X): Number(-> X) 'rule' expr3(-> - X): "-" expr3(-> X) 'rule' expr3(-> + X): "+" expr3(-> X) 'rule' expr3(-> X): "(" expression(-> X) ")" 'token' Number(-> INT)The representation of the token Number is not specified in the Gentle specification. Instead, we use a token description file from the reflex directory (file Number.t):
[0-9]+ { yylval.attr[1] = atoi(yytext); yysetpos(); return Number; }Assume that $GENTLE is the path name for the program gentle, $GRTS for the Gentle run time system grts.o, $REFLEX for the program reflex, and $LIB is the user library.
Then the command sequence
$GENTLE calc.g $REFLEX lex gen.l yacc gen.y cc -o calc \ calc.c \ lex.yy.c \ y.tab.c \ $LIB/errmsg.o \ $LIB/main.o \ $GRTScan be used to create the calculator program calc.
Here the command
$GENTLE calc.ginvokes the Gentle compiler, which translates the specification calc.g into a C file calc.c. In addition, it generates some files gen.*, which the user need not bother about.
The command
$REFLEXinvokes the program reflex. This creates a specification for the scanner generator Lex (from files created by gentle and files provided by the user such as Number.t).
The commands
lex gen.l yacc gen.yinvoke the scanner generator Lex and the parser generator Yacc respectively.
Finally, the C compiler creates the program calc:
cc -o calc \ calc.c \ lex.yy.c \ y.tab.c \ $LIB/errmsg.o \ $LIB/main.o \ $GRTSlex.yy.c and y.tab.c are C files created by Lex and Yacc. $LIB/errmsg.o and $LIB/main.o are modules from the user library. They provide an error message routine and and main function that invokes the code created by the Gentle compiler (a user may use these components as they are, or adapt them according to his or her needs).
If testfile contains the line
2+3*4then the command
calc testfileemits 14 .