Line 1: | Line 1: | ||
This example implements a simple calculator. The calculator has an unspecified number of integer variables and the common binary integer operators (namely, addition, subtraction, multiplication, division, and modulus), and unary integer operators (+ and -). | This example implements a simple calculator. The calculator has an unspecified number of integer variables and the common binary integer operators (namely, addition, subtraction, multiplication, division, and modulus), and unary integer operators (+ and -). | ||
+ | |||
+ | The language will contain the following concepts (tokens): '''VAR''' (a variable: the corresponding '''s''' attribute will contain its name); '''INT''' (an integer: the corresponding '''i''' attribute contains its value); and the operators (see below). | ||
== The Lexical Analyzer (Flex) Specification == | == The Lexical Analyzer (Flex) Specification == | ||
Line 5: | Line 7: | ||
The lexical analyzer is very simple and limited to recognizing variable names, integers numbers, and the operators themselves. | The lexical analyzer is very simple and limited to recognizing variable names, integers numbers, and the operators themselves. | ||
<text> | <text> | ||
+ | %option noyywrap | ||
+ | %{ | ||
+ | #include <cstdlib> | ||
+ | #include <string> | ||
+ | #include "y.tab.h" | ||
+ | %} | ||
+ | %% | ||
+ | [_[:alpha:]][_[:alnum:]]* yylval.s = new std::string(yytext); return VAR; | ||
+ | [[:digit:]]+ yylval.i = strtol(yytext, NULL, 10); return INT; | ||
+ | [-+*/%=^:,] return *yytext; | ||
+ | .|\n ; /* ignore all the rest */ | ||
+ | %% | ||
</text> | </text> | ||
This example implements a simple calculator. The calculator has an unspecified number of integer variables and the common binary integer operators (namely, addition, subtraction, multiplication, division, and modulus), and unary integer operators (+ and -).
The language will contain the following concepts (tokens): VAR (a variable: the corresponding s attribute will contain its name); INT (an integer: the corresponding i attribute contains its value); and the operators (see below).
The lexical analyzer is very simple and limited to recognizing variable names, integers numbers, and the operators themselves. <text> %option noyywrap %{
%} %% [_[:alpha:]][_[:alnum:]]* yylval.s = new std::string(yytext); return VAR; digit:+ yylval.i = strtol(yytext, NULL, 10); return INT; [-+*/%=^:,] return *yytext; .|\n ; /* ignore all the rest */ %% </text>
The syntactic analyzer will be built to immediately compute the expressions in a syntax-directed fashion as they occur. It is, thus, important to use trees that build nodes as the expressions occur (left-recursive grammars). If the grammar were right-recursive, the last node would be the first to be built and the (syntax-directed) evaluation would be from the last expression to the first.
The first task is to define the grammar itself (without worrying with semantics). <text> </text>