home *** CD-ROM | disk | FTP | other *** search
-
- /* Sample Yacc specification for simple desktop calculator; derived
- from a specification in Aho et al: Compilers. Principles, Techniques
- and Tools (sect. 4.9).
- Lexical analyzer is described by Lex specification in exprlex.l.
-
- To compile parser and lexical analyzer, issue the following commands:
- yacc expr
- lex exprlex
- tpc expr
-
- If you want to trace the actions executed by the parser, compile expr.pas
- with the command:
- tpc expr /Dyydebug
- (In this case, it may be useful to refer to the parser description generated
- by Yacc (file expr.lst).)
-
- Description: This program reads simple arithmetic expressions, constructed
- with real numbers, operators +, -, *, /, unary - and parentheses (operators
- have their usual precedence, unary minus is highest), from standard input
- (one per line) and prints the result on standard output.
- Variables are denoted by a single letter (no distinction between upper and
- lowercase letters); they are assigned values through an assignment of the
- form <var>=<expr>.
- To terminate the program, type ^Z or a period `.' at the beginning of a
- line. */
-
- %{
- uses LexLib, YaccLib;
- {$I exprlex} { lexical analyser }
- var var_table : array [1..26] of real;
- { variable table, initialized to zeros }
- %}
-
- %union {
- number : real;
- variable : integer;
- }
-
- %token <number> NUMBER /* real constants */
- %token <variable> VARIABLE /* single letter variable */
- %type <number> expr /* real-valued expressions */
- %left '+' '-' /* operators */
- %left '*' '/'
- %right UMINUS
- %token EOF /* . at the beginning of a line */
- %token ILLEGAL /* illegal token */
-
- %%
-
- input : /* empty */
- | input '\n' /* empty line */
- | input expr '\n' { writeln($2) }
- | input VARIABLE '=' expr '\n'
- { var_table[$2] := $4 }
- | input EOF { yyaccept }
- | error '\n' { write('reenter last line: '); yyerrok }
- ;
-
- expr : expr '+' expr { $$ := $1 + $3 }
- | expr '-' expr { $$ := $1 - $3 }
- | expr '*' expr { $$ := $1 * $3 }
- | expr '/' expr { $$ := $1 / $3 }
- | '(' expr ')' { $$ := $2 }
- | '-' expr %prec UMINUS { $$ := -$2 }
- | NUMBER { $$ := $1 }
- | VARIABLE { $$ := var_table[$1] }
- ;
-
- %%
-
- var i : integer;
- begin
- for i := 1 to 26 do var_table[i] := 0.0;
- if yyparse=0 then { done }
- end.