mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-23 03:03:02 +00:00
d: improve the example
* examples/d/calc.y: Exit with failure on errors. Remove useless operators (=, !) meant for the test suite. Add unary + for symmetry. * examples/d/calc.test: Adjust expectations.
This commit is contained in:
@@ -23,4 +23,4 @@ run 0 7
|
|||||||
cat >input <<EOF
|
cat >input <<EOF
|
||||||
1 + 2 * * 3
|
1 + 2 * * 3
|
||||||
EOF
|
EOF
|
||||||
run 0 "err: syntax error, unexpected *, expecting - or ! or ( or number"
|
run 1 "err: syntax error, unexpected *, expecting + or - or ( or number"
|
||||||
|
|||||||
@@ -18,17 +18,15 @@
|
|||||||
MINUS "-"
|
MINUS "-"
|
||||||
STAR "*"
|
STAR "*"
|
||||||
SLASH "/"
|
SLASH "/"
|
||||||
BANG "!"
|
|
||||||
LPAR "("
|
LPAR "("
|
||||||
RPAR ")"
|
RPAR ")"
|
||||||
EOL "end of line"
|
EOL "end of line"
|
||||||
%token <ival> NUM "number"
|
%token <ival> NUM "number"
|
||||||
%type <ival> exp
|
%type <ival> exp
|
||||||
|
|
||||||
%nonassoc "=" /* comparison */
|
|
||||||
%left "-" "+"
|
%left "-" "+"
|
||||||
%left "*" "/"
|
%left "*" "/"
|
||||||
%precedence NEG /* negation--unary minus */
|
%precedence UNARY /* unary operators */
|
||||||
|
|
||||||
/* Grammar follows */
|
/* Grammar follows */
|
||||||
%%
|
%%
|
||||||
@@ -44,29 +42,21 @@ line:
|
|||||||
;
|
;
|
||||||
|
|
||||||
exp:
|
exp:
|
||||||
NUM { $$ = $1; }
|
NUM { $$ = $1; }
|
||||||
| exp "=" exp
|
| exp "+" exp { $$ = $1 + $3; }
|
||||||
{
|
| exp "-" exp { $$ = $1 - $3; }
|
||||||
if ($1 != $3)
|
| exp "*" exp { $$ = $1 * $3; }
|
||||||
yyerror (format ("calc: error: %d != %d", $1, $3));
|
| exp "/" exp { $$ = $1 / $3; }
|
||||||
}
|
| "+" exp %prec UNARY { $$ = -$2; }
|
||||||
| exp "+" exp { $$ = $1 + $3; }
|
| "-" exp %prec UNARY { $$ = -$2; }
|
||||||
| exp "-" exp { $$ = $1 - $3; }
|
| "(" exp ")" { $$ = $2; }
|
||||||
| exp "*" exp { $$ = $1 * $3; }
|
|
||||||
| exp "/" exp { $$ = $1 / $3; }
|
|
||||||
| "-" exp %prec NEG { $$ = -$2; }
|
|
||||||
| "(" exp ")" { $$ = $2; }
|
|
||||||
| "(" error ")" { $$ = 1111; }
|
|
||||||
| "!" { $$ = 0; return YYERROR; }
|
|
||||||
| "-" error { $$ = 0; return YYERROR; }
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
%%
|
%%
|
||||||
class CalcLexer : Lexer {
|
class CalcLexer : Lexer {
|
||||||
|
|
||||||
this ()
|
// Should be a local in main, shared with %parse-param.
|
||||||
{}
|
int exit_status = 0;
|
||||||
|
|
||||||
int
|
int
|
||||||
get_char ()
|
get_char ()
|
||||||
@@ -84,6 +74,7 @@ class CalcLexer : Lexer {
|
|||||||
|
|
||||||
public void yyerror (string s)
|
public void yyerror (string s)
|
||||||
{
|
{
|
||||||
|
exit_status = 1;
|
||||||
stderr.writeln (s);
|
stderr.writeln (s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,7 +132,6 @@ class CalcLexer : Lexer {
|
|||||||
case '-': return YYTokenType.MINUS;
|
case '-': return YYTokenType.MINUS;
|
||||||
case '*': return YYTokenType.STAR;
|
case '*': return YYTokenType.STAR;
|
||||||
case '/': return YYTokenType.SLASH;
|
case '/': return YYTokenType.SLASH;
|
||||||
case '!': return YYTokenType.BANG;
|
|
||||||
case '(': return YYTokenType.LPAR;
|
case '(': return YYTokenType.LPAR;
|
||||||
case ')': return YYTokenType.RPAR;
|
case ')': return YYTokenType.RPAR;
|
||||||
case '\n': return YYTokenType.EOL;
|
case '\n': return YYTokenType.EOL;
|
||||||
@@ -150,9 +140,10 @@ class CalcLexer : Lexer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void main ()
|
int main ()
|
||||||
{
|
{
|
||||||
CalcLexer l = new CalcLexer ();
|
CalcLexer l = new CalcLexer ();
|
||||||
Calc p = new Calc (l);
|
Calc p = new Calc (l);
|
||||||
p.parse ();
|
p.parse ();
|
||||||
|
return l.exit_status;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user