99 |
| exp '=' exp |
| exp '=' exp |
100 |
{ |
{ |
101 |
if ($1 != $3) |
if ($1 != $3) |
102 |
printf ("calc: error: %d != %d\n", $1, $3); |
fprintf (stderr, "calc: error: %d != %d\n", $1, $3); |
103 |
$$ = $1 == $3; |
$$ = $1 == $3; |
104 |
} |
} |
105 |
| exp '+' exp { $$ = $1 + $3; } |
| exp '+' exp { $$ = $1 + $3; } |
109 |
| '-' exp %prec NEG { $$ = -$2; } |
| '-' exp %prec NEG { $$ = -$2; } |
110 |
| exp '^' exp { $$ = power ($1, $3); } |
| exp '^' exp { $$ = power ($1, $3); } |
111 |
| '(' exp ')' { $$ = $2; } |
| '(' exp ')' { $$ = $2; } |
112 |
|
| '(' error ')' { $$ = 0; } |
113 |
; |
; |
114 |
%% |
%% |
115 |
/* The input. */ |
/* The input. */ |
119 |
yyerror (const char *s) |
yyerror (const char *s) |
120 |
{ |
{ |
121 |
#if YYLSP_NEEDED |
#if YYLSP_NEEDED |
122 |
fprintf (stderr, "%d.%d:%d.%d: ", |
fprintf (stderr, "%d.%d-%d.%d: ", |
123 |
yylloc.first_line, yylloc.first_column, |
yylloc.first_line, yylloc.first_column, |
124 |
yylloc.last_line, yylloc.last_column); |
yylloc.last_line, yylloc.last_column); |
125 |
#endif |
#endif |
139 |
if (res == '\n') |
if (res == '\n') |
140 |
{ |
{ |
141 |
yylloc.last_line++; |
yylloc.last_line++; |
142 |
yylloc.last_column = 0; |
yylloc.last_column = 1; |
143 |
} |
} |
144 |
else |
else |
145 |
yylloc.last_column++; |
yylloc.last_column++; |
256 |
yydebug = 1; |
yydebug = 1; |
257 |
#endif |
#endif |
258 |
#if YYLSP_NEEDED |
#if YYLSP_NEEDED |
259 |
yylloc.last_column = 0; |
yylloc.last_column = 1; |
260 |
yylloc.last_line = 1; |
yylloc.last_line = 1; |
261 |
#endif |
#endif |
262 |
yyparse (); |
yyparse (); |
319 |
]]) |
]]) |
320 |
AT_CHECK([./calc input], 0, [], [stderr])]) |
AT_CHECK([./calc input], 0, [], [stderr])]) |
321 |
|
|
322 |
|
m4_bmatch([$1], [--debug], |
323 |
AT_CHECK([wc -l <stderr | sed 's/[[^0-9]]//g'], 0, |
[AT_CHECK([wc -l <stderr | sed 's/[[^0-9]]//g'], 0, [$3 |
324 |
[m4_bmatch([$1], [--debug], |
])]) |
325 |
[$3], [1]) |
|
326 |
]) |
# Normalize the observed and expected error messages, depending upon the |
327 |
|
# options. |
328 |
egrep -v '^((Start|Enter|Read|Reduc|Shift)ing|state|Error:) ' stderr >at-stderr |
# 1. Remove the traces from observed. |
329 |
|
egrep -v '^((Start|Enter|Read|Reduc|Shift)ing|state|Error:|Next|Discarding) ' stderr >at-stderr |
330 |
mv at-stderr stderr |
mv at-stderr stderr |
331 |
|
# 2. Create the reference error message. |
332 |
AT_CHECK([cat stderr], 0, |
AT_DATA([[expout]], |
333 |
[m4_bmatch([$1], [--location], [$4: ])[]dnl |
[$4 |
|
parse error[]dnl |
|
|
m4_bmatch([$1], [--yyerror-verbose], [, $5])[]dnl |
|
|
|
|
334 |
]) |
]) |
335 |
|
# 3. If locations are not used, remove them. |
336 |
|
m4_bmatch([$1], [--location], [], |
337 |
|
[[sed 's/^[-0-9.]*: //' expout >at-expout |
338 |
|
mv at-expout expout]]) |
339 |
|
# 4. If error-verbose is not used, strip the`, unexpected....' part. |
340 |
|
m4_bmatch([$1], [--yyerror-verbose], [], |
341 |
|
[[sed 's/parse error, .*$/parse error/' expout >at-expout |
342 |
|
mv at-expout expout]]) |
343 |
|
# 5. Check |
344 |
|
AT_CHECK([cat stderr], 0, [expout]) |
345 |
]) |
]) |
346 |
|
|
347 |
|
|
379 |
|
|
380 |
# Some parse errors. |
# Some parse errors. |
381 |
_AT_CHECK_CALC_ERROR([$1], [0 0], [10], |
_AT_CHECK_CALC_ERROR([$1], [0 0], [10], |
382 |
[1.2:1.3], |
[1.3-1.4: parse error, unexpected "number"]) |
|
[unexpected "number"]) |
|
383 |
_AT_CHECK_CALC_ERROR([$1], [1//2], [13], |
_AT_CHECK_CALC_ERROR([$1], [1//2], [13], |
384 |
[1.2:1.3], |
[1.3-1.4: parse error, unexpected '/', expecting "number" or '-' or '(']) |
|
[unexpected '/', expecting "number" or '-' or '(']) |
|
385 |
_AT_CHECK_CALC_ERROR([$1], [error], [4], |
_AT_CHECK_CALC_ERROR([$1], [error], [4], |
386 |
[1.0:1.1], |
[1.1-1.2: parse error, unexpected $undefined., expecting "number" or '-' or '\n' or '(']) |
|
[unexpected $undefined., expecting "number" or '-' or '\n' or '(']) |
|
387 |
_AT_CHECK_CALC_ERROR([$1], [1 = 2 = 3], [19], |
_AT_CHECK_CALC_ERROR([$1], [1 = 2 = 3], [19], |
388 |
[1.6:1.7], |
[1.7-1.8: parse error, unexpected '=']) |
|
[unexpected '=']) |
|
389 |
_AT_CHECK_CALC_ERROR([$1], |
_AT_CHECK_CALC_ERROR([$1], |
390 |
[ |
[ |
391 |
+1], |
+1], |
392 |
[13], |
[13], |
393 |
[2.0:2.1], |
[2.1-2.2: parse error, unexpected '+']) |
|
[unexpected '+']) |
|
394 |
# Exercise error messages with EOF: work on an empty file. |
# Exercise error messages with EOF: work on an empty file. |
395 |
_AT_CHECK_CALC_ERROR([$1], |
_AT_CHECK_CALC_ERROR([$1], |
396 |
[/dev/null], |
[/dev/null], |
397 |
[4], |
[4], |
398 |
[1.0:1.1], |
[1.1-1.2: parse error, unexpected "end of file", expecting "number" or '-' or '\n' or '(']) |
399 |
[unexpected "end of file", expecting "number" or '-' or '\n' or '(']) |
|
400 |
|
# Exercise the error token: without it, we die at the first error, |
401 |
|
# hence be sure i. to have several errors, ii. to test the action |
402 |
|
# associated to `error'. |
403 |
|
_AT_CHECK_CALC_ERROR([$1], |
404 |
|
[(1 ++ 2) + (0 0) = 1], |
405 |
|
[76], |
406 |
|
[1.5-1.6: parse error, unexpected '+', expecting "number" or '-' or '(' |
407 |
|
1.15-1.16: parse error, unexpected "number" |
408 |
|
calc: error: 0 != 1]) |
409 |
|
|
410 |
|
# Add a studid example demonstrating that Bison can further improve the |
411 |
|
# error message. FIXME: Fix this ridiculous message. |
412 |
|
_AT_CHECK_CALC_ERROR([$1], |
413 |
|
[()], |
414 |
|
[21], |
415 |
|
[1.2-1.3: parse error, unexpected ')', expecting error or "number" or '-' or '(']) |
416 |
|
|
417 |
AT_CLEANUP |
AT_CLEANUP |
418 |
])# AT_CHECK_CALC |
])# AT_CHECK_CALC |