Mercurial > jwe > qt-gui-with-push-parser
annotate parser.yy @ 6:1b575145197e
interpreter is now a class instead of a namespace with functions
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Thu, 23 May 2019 07:41:18 -0400 |
parents | 0e154787183d |
children | 822a2fe5bb51 |
rev | line source |
---|---|
0 | 1 // Infix notation calculator. |
2 | |
3 %{ | |
4 | |
5 #define YYSTYPE double | |
6 | |
7 #include <iostream> | |
4
0e154787183d
new interpreter and qt_interpreter objects
John W. Eaton <jwe@octave.org>
parents:
1
diff
changeset
|
8 #include <string> |
0 | 9 |
10 #include <cctype> | |
11 #include <cmath> | |
12 #include <cstdio> | |
13 | |
4
0e154787183d
new interpreter and qt_interpreter objects
John W. Eaton <jwe@octave.org>
parents:
1
diff
changeset
|
14 #include "interpreter.h" |
0 | 15 #include "main.h" |
16 #include "gui-main.h" | |
17 #include "tty-main.h" | |
4
0e154787183d
new interpreter and qt_interpreter objects
John W. Eaton <jwe@octave.org>
parents:
1
diff
changeset
|
18 #include "parser.h" |
0 | 19 |
4
0e154787183d
new interpreter and qt_interpreter objects
John W. Eaton <jwe@octave.org>
parents:
1
diff
changeset
|
20 namespace parser |
0 | 21 { |
22 FILE *outfile = 0; | |
23 size_t bufptr = 0; | |
24 size_t chunk_size = 0; | |
25 | |
1
08df60a01bc1
debug flag, handle input with signal
John W. Eaton <jwe@octave.org>
parents:
0
diff
changeset
|
26 const char *buf; |
08df60a01bc1
debug flag, handle input with signal
John W. Eaton <jwe@octave.org>
parents:
0
diff
changeset
|
27 bool beg_of_stmt = true; |
0 | 28 |
29 static int yylex (void); | |
1
08df60a01bc1
debug flag, handle input with signal
John W. Eaton <jwe@octave.org>
parents:
0
diff
changeset
|
30 |
08df60a01bc1
debug flag, handle input with signal
John W. Eaton <jwe@octave.org>
parents:
0
diff
changeset
|
31 static void debug_trace (const char *); |
0 | 32 } |
33 | |
34 static void yyerror (char const *); | |
35 | |
6
1b575145197e
interpreter is now a class instead of a namespace with functions
John W. Eaton <jwe@octave.org>
parents:
4
diff
changeset
|
36 static void emit_error (const char *msg); |
1b575145197e
interpreter is now a class instead of a namespace with functions
John W. Eaton <jwe@octave.org>
parents:
4
diff
changeset
|
37 static void emit_result (double value); |
1b575145197e
interpreter is now a class instead of a namespace with functions
John W. Eaton <jwe@octave.org>
parents:
4
diff
changeset
|
38 |
0 | 39 %} |
40 | |
41 %define api.push-pull push | |
42 | |
43 // Bison declarations. | |
44 %token NUM | |
45 %left '-' '+' | |
46 %left '*' '/' | |
47 %left NEG // negation--unary minus | |
48 %right '^' // exponentiation | |
49 | |
50 %% | |
51 | |
52 input : // empty | |
53 { } | |
54 | input line | |
1
08df60a01bc1
debug flag, handle input with signal
John W. Eaton <jwe@octave.org>
parents:
0
diff
changeset
|
55 | error |
08df60a01bc1
debug flag, handle input with signal
John W. Eaton <jwe@octave.org>
parents:
0
diff
changeset
|
56 { |
4
0e154787183d
new interpreter and qt_interpreter objects
John W. Eaton <jwe@octave.org>
parents:
1
diff
changeset
|
57 parser::debug_trace ("ABORT"); |
1
08df60a01bc1
debug flag, handle input with signal
John W. Eaton <jwe@octave.org>
parents:
0
diff
changeset
|
58 YYABORT; |
08df60a01bc1
debug flag, handle input with signal
John W. Eaton <jwe@octave.org>
parents:
0
diff
changeset
|
59 } |
0 | 60 ; |
61 | |
62 line : ';' | |
63 { } | |
64 | exp ';' | |
65 { | |
6
1b575145197e
interpreter is now a class instead of a namespace with functions
John W. Eaton <jwe@octave.org>
parents:
4
diff
changeset
|
66 emit_result ($1); |
4
0e154787183d
new interpreter and qt_interpreter objects
John W. Eaton <jwe@octave.org>
parents:
1
diff
changeset
|
67 parser::beg_of_stmt = true; |
0 | 68 } |
69 ; | |
70 | |
71 exp : NUM | |
72 { | |
4
0e154787183d
new interpreter and qt_interpreter objects
John W. Eaton <jwe@octave.org>
parents:
1
diff
changeset
|
73 parser::debug_trace ("NUM"); |
0 | 74 $$ = $1; |
4
0e154787183d
new interpreter and qt_interpreter objects
John W. Eaton <jwe@octave.org>
parents:
1
diff
changeset
|
75 parser::beg_of_stmt = false; |
0 | 76 } |
77 | exp '+' exp | |
78 { | |
4
0e154787183d
new interpreter and qt_interpreter objects
John W. Eaton <jwe@octave.org>
parents:
1
diff
changeset
|
79 parser::debug_trace ("ADD"); |
0 | 80 $$ = $1 + $3; |
4
0e154787183d
new interpreter and qt_interpreter objects
John W. Eaton <jwe@octave.org>
parents:
1
diff
changeset
|
81 parser::beg_of_stmt = false; |
0 | 82 } |
83 | exp '-' exp | |
84 { | |
4
0e154787183d
new interpreter and qt_interpreter objects
John W. Eaton <jwe@octave.org>
parents:
1
diff
changeset
|
85 parser::debug_trace ("SUB"); |
0 | 86 $$ = $1 - $3; |
4
0e154787183d
new interpreter and qt_interpreter objects
John W. Eaton <jwe@octave.org>
parents:
1
diff
changeset
|
87 parser::beg_of_stmt = false; |
0 | 88 } |
89 | exp '*' exp | |
90 { | |
4
0e154787183d
new interpreter and qt_interpreter objects
John W. Eaton <jwe@octave.org>
parents:
1
diff
changeset
|
91 parser::debug_trace ("MUL"); |
0 | 92 $$ = $1 * $3; |
4
0e154787183d
new interpreter and qt_interpreter objects
John W. Eaton <jwe@octave.org>
parents:
1
diff
changeset
|
93 parser::beg_of_stmt = false; |
0 | 94 } |
95 | exp '/' exp | |
96 { | |
4
0e154787183d
new interpreter and qt_interpreter objects
John W. Eaton <jwe@octave.org>
parents:
1
diff
changeset
|
97 parser::debug_trace ("DIV"); |
0 | 98 $$ = $1 / $3; |
4
0e154787183d
new interpreter and qt_interpreter objects
John W. Eaton <jwe@octave.org>
parents:
1
diff
changeset
|
99 parser::beg_of_stmt = false; |
0 | 100 } |
101 | '-' exp %prec NEG | |
102 { | |
4
0e154787183d
new interpreter and qt_interpreter objects
John W. Eaton <jwe@octave.org>
parents:
1
diff
changeset
|
103 parser::debug_trace ("NEG"); |
0 | 104 $$ = -$2; |
4
0e154787183d
new interpreter and qt_interpreter objects
John W. Eaton <jwe@octave.org>
parents:
1
diff
changeset
|
105 parser::beg_of_stmt = false; |
0 | 106 } |
107 | exp '^' exp | |
108 { | |
4
0e154787183d
new interpreter and qt_interpreter objects
John W. Eaton <jwe@octave.org>
parents:
1
diff
changeset
|
109 parser::debug_trace ("EXP"); |
0 | 110 $$ = std::pow ($1, $3); |
4
0e154787183d
new interpreter and qt_interpreter objects
John W. Eaton <jwe@octave.org>
parents:
1
diff
changeset
|
111 parser::beg_of_stmt = false; |
0 | 112 } |
113 | '(' exp ')' | |
114 { | |
4
0e154787183d
new interpreter and qt_interpreter objects
John W. Eaton <jwe@octave.org>
parents:
1
diff
changeset
|
115 parser::debug_trace ("PAREN"); |
0 | 116 $$ = $2; |
4
0e154787183d
new interpreter and qt_interpreter objects
John W. Eaton <jwe@octave.org>
parents:
1
diff
changeset
|
117 parser::beg_of_stmt = false; |
0 | 118 } |
119 ; | |
120 | |
121 %% | |
122 | |
4
0e154787183d
new interpreter and qt_interpreter objects
John W. Eaton <jwe@octave.org>
parents:
1
diff
changeset
|
123 namespace parser |
0 | 124 { |
125 // The lexical analyzer returns a double floating point number on the | |
126 // stack and the token NUM, or the numeric code of the character read | |
127 // if not a number. It skips all blanks and tabs, and returns -1 for | |
128 // end-of-input. | |
129 | |
130 static int yylex (void) | |
131 { | |
132 int c; | |
133 | |
134 if (bufptr >= chunk_size) | |
135 return -1; | |
136 | |
137 // Skip white space. | |
138 while ((c = buf[bufptr++]) == ' ' || c == '\t' || c == '\n') | |
139 ; | |
140 | |
141 // Process numbers. | |
142 if (c == '.' || isdigit (c)) | |
143 { | |
144 int chars_read = 0; | |
145 bufptr--; | |
146 sscanf (&buf[bufptr], "%lf%n", &yylval, &chars_read); | |
147 bufptr += chars_read; | |
148 return NUM; | |
149 } | |
150 | |
151 // Return a single char. | |
152 return c; | |
153 } | |
154 | |
155 static yypstate *ps = 0; | |
156 | |
4
0e154787183d
new interpreter and qt_interpreter objects
John W. Eaton <jwe@octave.org>
parents:
1
diff
changeset
|
157 void init (void) |
0e154787183d
new interpreter and qt_interpreter objects
John W. Eaton <jwe@octave.org>
parents:
1
diff
changeset
|
158 { |
0e154787183d
new interpreter and qt_interpreter objects
John W. Eaton <jwe@octave.org>
parents:
1
diff
changeset
|
159 fini (); |
0e154787183d
new interpreter and qt_interpreter objects
John W. Eaton <jwe@octave.org>
parents:
1
diff
changeset
|
160 |
0e154787183d
new interpreter and qt_interpreter objects
John W. Eaton <jwe@octave.org>
parents:
1
diff
changeset
|
161 ps = yypstate_new (); |
0e154787183d
new interpreter and qt_interpreter objects
John W. Eaton <jwe@octave.org>
parents:
1
diff
changeset
|
162 } |
0e154787183d
new interpreter and qt_interpreter objects
John W. Eaton <jwe@octave.org>
parents:
1
diff
changeset
|
163 |
0e154787183d
new interpreter and qt_interpreter objects
John W. Eaton <jwe@octave.org>
parents:
1
diff
changeset
|
164 void fini (void) |
0 | 165 { |
166 if (ps) | |
167 yypstate_delete (ps); | |
168 | |
169 ps = 0; | |
170 } | |
171 | |
172 int parse_and_execute (const std::string& line) | |
173 { | |
174 bufptr = 0; | |
175 chunk_size = line.length (); | |
176 buf = line.c_str (); | |
177 | |
178 int status; | |
179 | |
180 do | |
181 { | |
182 ::yychar = yylex (); | |
183 | |
184 if (::yychar < 0) | |
185 return -1; | |
186 | |
187 status = yypush_parse (ps); | |
188 } | |
189 while (status == YYPUSH_MORE); | |
190 | |
1
08df60a01bc1
debug flag, handle input with signal
John W. Eaton <jwe@octave.org>
parents:
0
diff
changeset
|
191 return -2; |
0 | 192 } |
193 | |
1
08df60a01bc1
debug flag, handle input with signal
John W. Eaton <jwe@octave.org>
parents:
0
diff
changeset
|
194 void debug_trace (const char *msg) |
08df60a01bc1
debug flag, handle input with signal
John W. Eaton <jwe@octave.org>
parents:
0
diff
changeset
|
195 { |
08df60a01bc1
debug flag, handle input with signal
John W. Eaton <jwe@octave.org>
parents:
0
diff
changeset
|
196 if (calc::debug_mode) |
08df60a01bc1
debug flag, handle input with signal
John W. Eaton <jwe@octave.org>
parents:
0
diff
changeset
|
197 std::cerr << msg << std::endl; |
08df60a01bc1
debug flag, handle input with signal
John W. Eaton <jwe@octave.org>
parents:
0
diff
changeset
|
198 } |
0 | 199 } |
200 | |
201 static void yyerror (char const *msg) | |
202 { | |
6
1b575145197e
interpreter is now a class instead of a namespace with functions
John W. Eaton <jwe@octave.org>
parents:
4
diff
changeset
|
203 emit_error (msg); |
0 | 204 } |
6
1b575145197e
interpreter is now a class instead of a namespace with functions
John W. Eaton <jwe@octave.org>
parents:
4
diff
changeset
|
205 |
1b575145197e
interpreter is now a class instead of a namespace with functions
John W. Eaton <jwe@octave.org>
parents:
4
diff
changeset
|
206 static void emit_error (const char *msg) |
1b575145197e
interpreter is now a class instead of a namespace with functions
John W. Eaton <jwe@octave.org>
parents:
4
diff
changeset
|
207 { |
1b575145197e
interpreter is now a class instead of a namespace with functions
John W. Eaton <jwe@octave.org>
parents:
4
diff
changeset
|
208 calc::interpreter::the_interpreter->emit_error (msg); |
1b575145197e
interpreter is now a class instead of a namespace with functions
John W. Eaton <jwe@octave.org>
parents:
4
diff
changeset
|
209 } |
1b575145197e
interpreter is now a class instead of a namespace with functions
John W. Eaton <jwe@octave.org>
parents:
4
diff
changeset
|
210 |
1b575145197e
interpreter is now a class instead of a namespace with functions
John W. Eaton <jwe@octave.org>
parents:
4
diff
changeset
|
211 static void emit_result (double value) |
1b575145197e
interpreter is now a class instead of a namespace with functions
John W. Eaton <jwe@octave.org>
parents:
4
diff
changeset
|
212 { |
1b575145197e
interpreter is now a class instead of a namespace with functions
John W. Eaton <jwe@octave.org>
parents:
4
diff
changeset
|
213 calc::interpreter::the_interpreter->emit_result (value); |
1b575145197e
interpreter is now a class instead of a namespace with functions
John W. Eaton <jwe@octave.org>
parents:
4
diff
changeset
|
214 } |