BSD 4_1_snap development
[unix-history] / usr / doc / yacc / ssa
CommitLineData
f2a0d81d
C
1.SH
2Appendix A: A Simple Example
3.PP
4This example gives the complete Yacc specification for a small desk calculator;
5the desk calculator has 26 registers, labeled ``a'' through ``z'', and accepts
6arithmetic expressions made up of the operators +, \-, *, /,
7% (mod operator), & (bitwise and), | (bitwise or), and assignment.
8If an expression at the top level is an assignment, the value is not
9printed; otherwise it is.
10As in C, an integer that begins with 0 (zero) is assumed to be octal;
11otherwise, it is assumed to be decimal.
12.PP
13As an example of a Yacc specification, the desk calculator
14does a reasonable job of showing how precedences and ambiguities
15are used, and demonstrating simple error recovery.
16The major oversimplifications are that the
17lexical analysis phase is much simpler than for most applications, and the
18output is produced immediately, line by line.
19Note the way that decimal and octal integers are read in by the grammar rules;
20This job is probably better done by the lexical analyzer.
21.sp
22.nf
23.ta .5i 1i 1.5i 2i 2.5i
24
25%{
26# include <stdio.h>
27# include <ctype.h>
28
29int regs[26];
30int base;
31
32%}
33
34%start list
35
36%token DIGIT LETTER
37
38%left \'|\'
39%left \'&\'
40%left \'+\' \'\-\'
41%left \'*\' \'/\' \'%\'
42%left UMINUS /* supplies precedence for unary minus */
43
44%% /* beginning of rules section */
45
46list : /* empty */
47 | list stat \'\en\'
48 | list error \'\en\'
49 { yyerrok; }
50 ;
51
52stat : expr
53 { printf( "%d\en", $1 ); }
54 | LETTER \'=\' expr
55 { regs[$1] = $3; }
56 ;
57
58expr : \'(\' expr \')\'
59 { $$ = $2; }
60 | expr \'+\' expr
61 { $$ = $1 + $3; }
62 | expr \'\-\' expr
63 { $$ = $1 \- $3; }
64 | expr \'*\' expr
65 { $$ = $1 * $3; }
66 | expr \'/\' expr
67 { $$ = $1 / $3; }
68 | expr \'%\' expr
69 { $$ = $1 % $3; }
70 | expr \'&\' expr
71 { $$ = $1 & $3; }
72 | expr \'|\' expr
73 { $$ = $1 | $3; }
74 | \'\-\' expr %prec UMINUS
75 { $$ = \- $2; }
76 | LETTER
77 { $$ = regs[$1]; }
78 | number
79 ;
80
81number : DIGIT
82 { $$ = $1; base = ($1==0) ? 8 : 10; }
83 | number DIGIT
84 { $$ = base * $1 + $2; }
85 ;
86
87%% /* start of programs */
88
89yylex() { /* lexical analysis routine */
90 /* returns LETTER for a lower case letter, yylval = 0 through 25 */
91 /* return DIGIT for a digit, yylval = 0 through 9 */
92 /* all other characters are returned immediately */
93
94 int c;
95
96 while( (c=getchar()) == \' \' ) { /* skip blanks */ }
97
98 /* c is now nonblank */
99
100 if( islower( c ) ) {
101 yylval = c \- \'a\';
102 return ( LETTER );
103 }
104 if( isdigit( c ) ) {
105 yylval = c \- \'0\';
106 return( DIGIT );
107 }
108 return( c );
109 }
110.fi
111.bp