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:
Akim Demaille
2019-02-23 11:35:26 +01:00
parent 661bbacfc7
commit 575b814119
2 changed files with 15 additions and 24 deletions

View File

@@ -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"

View File

@@ -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;
} }