calc3.y revision 1.1.1.5 1 1.1.1.3 christos /* $NetBSD: calc3.y,v 1.1.1.5 2015/01/03 22:58:23 christos Exp $ */
2 1.1.1.3 christos
3 1.1 christos %pure-parser
4 1.1 christos
5 1.1 christos %parse-param { int regs[26] }
6 1.1 christos %parse-param { int *base }
7 1.1 christos
8 1.1 christos %lex-param { int *base }
9 1.1 christos
10 1.1 christos %{
11 1.1 christos # include <stdio.h>
12 1.1 christos # include <ctype.h>
13 1.1 christos
14 1.1.1.4 christos #ifdef YYBISON
15 1.1.1.4 christos #define YYSTYPE int
16 1.1.1.4 christos #define YYLEX_PARAM base
17 1.1.1.4 christos #define YYLEX_DECL() yylex(YYSTYPE *yylval, int *YYLEX_PARAM)
18 1.1.1.4 christos #define YYERROR_DECL() yyerror(int regs[26], int *base, const char *s)
19 1.1.1.4 christos int YYLEX_DECL();
20 1.1.1.4 christos static void YYERROR_DECL();
21 1.1.1.4 christos #endif
22 1.1.1.4 christos
23 1.1 christos %}
24 1.1 christos
25 1.1 christos %start list
26 1.1 christos
27 1.1 christos %token DIGIT LETTER
28 1.1 christos
29 1.1 christos %left '|'
30 1.1 christos %left '&'
31 1.1 christos %left '+' '-'
32 1.1 christos %left '*' '/' '%'
33 1.1 christos %left UMINUS /* supplies precedence for unary minus */
34 1.1 christos
35 1.1 christos %% /* beginning of rules section */
36 1.1 christos
37 1.1 christos list : /* empty */
38 1.1 christos | list stat '\n'
39 1.1 christos | list error '\n'
40 1.1 christos { yyerrok ; }
41 1.1 christos ;
42 1.1 christos
43 1.1 christos stat : expr
44 1.1 christos { printf("%d\n",$1);}
45 1.1 christos | LETTER '=' expr
46 1.1 christos { regs[$1] = $3; }
47 1.1 christos ;
48 1.1 christos
49 1.1 christos expr : '(' expr ')'
50 1.1 christos { $$ = $2; }
51 1.1 christos | expr '+' expr
52 1.1 christos { $$ = $1 + $3; }
53 1.1 christos | expr '-' expr
54 1.1 christos { $$ = $1 - $3; }
55 1.1 christos | expr '*' expr
56 1.1 christos { $$ = $1 * $3; }
57 1.1 christos | expr '/' expr
58 1.1 christos { $$ = $1 / $3; }
59 1.1 christos | expr '%' expr
60 1.1 christos { $$ = $1 % $3; }
61 1.1 christos | expr '&' expr
62 1.1 christos { $$ = $1 & $3; }
63 1.1 christos | expr '|' expr
64 1.1 christos { $$ = $1 | $3; }
65 1.1 christos | '-' expr %prec UMINUS
66 1.1 christos { $$ = - $2; }
67 1.1 christos | LETTER
68 1.1 christos { $$ = regs[$1]; }
69 1.1 christos | number
70 1.1 christos ;
71 1.1 christos
72 1.1 christos number: DIGIT
73 1.1 christos { $$ = $1; (*base) = ($1==0) ? 8 : 10; }
74 1.1 christos | number DIGIT
75 1.1 christos { $$ = (*base) * $1 + $2; }
76 1.1 christos ;
77 1.1 christos
78 1.1 christos %% /* start of programs */
79 1.1 christos
80 1.1.1.2 christos #ifdef YYBYACC
81 1.1.1.2 christos extern int YYLEX_DECL();
82 1.1.1.2 christos #endif
83 1.1.1.2 christos
84 1.1 christos int
85 1.1 christos main (void)
86 1.1 christos {
87 1.1 christos int regs[26];
88 1.1 christos int base = 10;
89 1.1 christos
90 1.1 christos while(!feof(stdin)) {
91 1.1 christos yyparse(regs, &base);
92 1.1 christos }
93 1.1 christos return 0;
94 1.1 christos }
95 1.1 christos
96 1.1.1.5 christos #define UNUSED(x) ((void)(x))
97 1.1.1.5 christos
98 1.1 christos static void
99 1.1 christos YYERROR_DECL()
100 1.1 christos {
101 1.1.1.5 christos UNUSED(regs); /* %parse-param regs is not actually used here */
102 1.1.1.5 christos UNUSED(base); /* %parse-param base is not actually used here */
103 1.1 christos fprintf(stderr, "%s\n", s);
104 1.1 christos }
105 1.1 christos
106 1.1 christos int
107 1.1 christos YYLEX_DECL()
108 1.1 christos {
109 1.1 christos /* lexical analysis routine */
110 1.1 christos /* returns LETTER for a lower case letter, yylval = 0 through 25 */
111 1.1 christos /* return DIGIT for a digit, yylval = 0 through 9 */
112 1.1 christos /* all other characters are returned immediately */
113 1.1 christos
114 1.1 christos int c;
115 1.1 christos
116 1.1 christos while( (c=getchar()) == ' ' ) { /* skip blanks */ }
117 1.1 christos
118 1.1 christos /* c is now nonblank */
119 1.1 christos
120 1.1 christos if( islower( c )) {
121 1.1 christos *yylval = (c - 'a');
122 1.1 christos return ( LETTER );
123 1.1 christos }
124 1.1 christos if( isdigit( c )) {
125 1.1 christos *yylval = (c - '0') % (*base);
126 1.1 christos return ( DIGIT );
127 1.1 christos }
128 1.1 christos return( c );
129 1.1 christos }
130