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