]> git.saurik.com Git - bison.git/blobdiff - tests/calc.at
* tests/calc.at (AT_CHECK_PUSHDEFS, AT_CHECK_POPDEFS): Define
[bison.git] / tests / calc.at
index a5e64efe8358049b8097f1d04a2c962894b32b68..aade61ccbd0d2439a026fd496c42005fa1053990 100644 (file)
@@ -66,13 +66,14 @@ static int global_count = 0;
 
 %{
 static int power (int base, int exponent);
+]AT_LALR1_CC_IF([], [
 /* yyerror receives the location if:
    - %location & %pure & %glr
    - %location & %pure & %yacc & %parse-param. */
-static void yyerror (]AT_YYERROR_ARG_LOC_IF([YYLTYPE *yylloc, ])[
-                     ]AT_PARAM_IF([value *result, int *count, ])[
+static void yyerror (AT_YYERROR_ARG_LOC_IF([YYLTYPE *yylloc, ])
+                     AT_PARAM_IF([value *result, int *count, ])
                      const char *s
-                     );
+                     );])[
 static int yylex (]AT_LEX_FORMALS[);
 static int yygetc (]AT_LEX_FORMALS[);
 static void yyungetc (]AT_LEX_PRE_FORMALS[ int c);
@@ -116,7 +117,8 @@ exp:
 | '-' exp  %prec NEG { $$ = -$2;            }
 | exp '^' exp        { $$ = power ($1, $3); }
 | '(' exp ')'        { $$ = $2;             }
-| '(' error ')'      { $$ = 0;              }
+| '(' error ')'      { $$ = 1111;           }
+| '!'                { YYERROR;             }
 ;
 %%
 /* The input. */
@@ -127,14 +129,15 @@ static FILE *yyin;
 void
 yy::Parser::print_ ()
 {
-  std::cerr << location;
+AT_LOCATION_IF([
+  std::cerr << location;])
 }
 
 /* A C++ error reporting function. */
 void
 yy::Parser::error_ ()
 {
-  std::cerr << location << ": " << message << std::endl;
+  std::cerr << AT_LOCATION_IF([location << ": " << ])message << std::endl;
 }
 
 int
@@ -252,20 +255,18 @@ yylex (]AT_LEX_FORMALS[)
 ])])[
     }
 
-]AT_LALR1_CC_IF(
+]AT_LOCATION_IF([AT_LALR1_CC_IF(
 [ AT_LOC.begin = AT_LOC.end;],
-[AT_LOCATION_IF([
-  AT_LOC.first_column = AT_LOC.last_column;
+[ AT_LOC.first_column = AT_LOC.last_column;
   AT_LOC.first_line   = AT_LOC.last_line;
 ])])[
 
   /* Skip white space.  */
   while ((c = yygetc (]AT_LEX_ARGS[)) == ' ' || c == '\t')
     {
-]AT_LALR1_CC_IF(
+]AT_LOCATION_IF([AT_LALR1_CC_IF(
 [     AT_LOC.begin = AT_LOC.end;],
-[AT_LOCATION_IF([
-      AT_LOC.first_column = AT_LOC.last_column;
+[     AT_LOC.first_column = AT_LOC.last_column;
       AT_LOC.first_line   = AT_LOC.last_line;
 ])])[
     }
@@ -316,9 +317,8 @@ main (int argc, const char **argv)
       exit (1);
     }
 
-#if YYDEBUG
-  yydebug = 1;
-#endif
+]AT_LALR1_CC_IF([], [m4_bmatch([$4], [%debug],
+[  yydebug = 1;])])[
   status = yyparse (]AT_PARAM_IF([&result, &count])[);
   if (global_result != result)
     abort ();
@@ -438,6 +438,9 @@ m4_pushdef([AT_LALR1_CC_IF],
 [m4_bmatch([$3], ["lalr1.cc"], [$1], [$2])])
 m4_pushdef([AT_GLR_IF],
 [m4_bmatch([$3], [%glr-parser], [$1], [$2])])
+# Using yacc.c?
+m4_pushdef([AT_YACC_IF],
+[m4_bmatch([$3], [%glr-parser\|%skeleton], [$2], [$1])])
 m4_pushdef([AT_PARAM_IF],
 [m4_bmatch([$3], [%parse-param], [$1], [$2])])
 m4_pushdef([AT_LOCATION_IF],
@@ -454,14 +457,13 @@ m4_pushdef([AT_GLR_OR_PARAM_IF],
 m4_pushdef([AT_YYERROR_ARG_LOC_IF],
 [AT_GLR_OR_PARAM_IF([AT_PURE_AND_LOC_IF([$1], [$2])],
                     [$2])])
-# yyerror cannot see the locations if !glr & pure & !param.
+# yyerror always sees the locations (when activated), except if
+# yacc & pure & !param.
 m4_pushdef([AT_YYERROR_SEES_LOC_IF],
-[AT_LALR1_CC_IF([$1],
-                [AT_LOCATION_IF([AT_GLR_IF([$1],
-                                           [AT_PURE_IF([AT_PARAM_IF([$1],
-                                                                    [$2])],
-                                                       [$1])])],
-                                [$2])])])
+[AT_LOCATION_IF([AT_YACC_IF([AT_PURE_IF([AT_PARAM_IF([$1], [$2])],
+                                        [$1])],
+                            [$1])],
+                [$2])])
 
 # The interface is pure: either because %pure-parser, or because we
 # are using the C++ parsers.
@@ -511,6 +513,7 @@ m4_popdef([AT_GLR_OR_PARAM_IF])
 m4_popdef([AT_PURE_AND_LOC_IF])
 m4_popdef([AT_LOCATION_IF])
 m4_popdef([AT_PARAM_IF])
+m4_popdef([AT_YACC_IF])
 m4_popdef([AT_GLR_IF])
 m4_popdef([AT_LALR1_CC_IF])
 ])
@@ -559,9 +562,9 @@ _AT_CHECK_CALC([$1],
 _AT_CHECK_CALC_ERROR([$1], [1], [0 0], [11],
                      [1.2: syntax error, unexpected "number"])
 _AT_CHECK_CALC_ERROR([$1], [1], [1//2], [15],
-                     [1.2: syntax error, unexpected '/', expecting "number" or '-' or '('])
+                     [1.2: syntax error, unexpected '/', expecting "number" or '-' or '(' or '!'])
 _AT_CHECK_CALC_ERROR([$1], [1], [error], [4],
-                     [1.0: syntax error, unexpected $undefined, expecting "number" or '-' or '\n' or '('])
+                     [1.0: syntax error, unexpected $undefined])
 _AT_CHECK_CALC_ERROR([$1], [1], [1 = 2 = 3], [22],
                      [1.6: syntax error, unexpected '='])
 _AT_CHECK_CALC_ERROR([$1], [1],
@@ -571,16 +574,38 @@ _AT_CHECK_CALC_ERROR([$1], [1],
                      [2.0: syntax error, unexpected '+'])
 # Exercise error messages with EOF: work on an empty file.
 _AT_CHECK_CALC_ERROR([$1], [1], [/dev/null], [4],
-                     [1.0: syntax error, unexpected "end of input", expecting "number" or '-' or '\n' or '('])
+                     [1.0: syntax error, unexpected "end of input"])
 
 # Exercise the error token: without it, we die at the first error,
-# hence be sure i. to have several errors, ii. to test the action
-# associated to `error'.
-_AT_CHECK_CALC_ERROR([$1], [0], [(1 ++ 2) + (0 0) = 1], [82],
-[1.4: syntax error, unexpected '+', expecting "number" or '-' or '('
-1.14: syntax error, unexpected "number"
-calc: error: 0 != 1])
-
+# hence be sure to
+#
+# - have several errors which exercise different shift/discardings
+#   - (): nothing to pop, nothing to discard
+#   - (1 + 1 + 1 +): a lot to pop, nothing to discard
+#   - (* * *): nothing to pop, a lot to discard
+#   - (1 + 2 * *): some to pop and discard
+#
+# - test the action associated to `error'
+#
+# - check the lookahead that triggers an error is not discarded
+#   when we enter error recovery.  Below, the lookahead causing the
+#   first error is ")", which is needed to recover from the error and
+#   produce the "0" that triggers the "0 != 1" error.
+#
+_AT_CHECK_CALC_ERROR([$1], [0],
+                     [() + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1],
+                     [156],
+[1.1: syntax error, unexpected ')', expecting "number" or '-' or '(' or '!'
+1.17: syntax error, unexpected ')', expecting "number" or '-' or '(' or '!'
+1.22: syntax error, unexpected '*', expecting "number" or '-' or '(' or '!'
+1.40: syntax error, unexpected '*', expecting "number" or '-' or '(' or '!'
+calc: error: 4444 != 1])
+
+# The same, but this time exercising explicitly triggered syntax errors.
+# POSIX says the lookahead causing the error should not be discarded.
+_AT_CHECK_CALC_ERROR([$1], [0], [(!) + (0 0) = 1], [64],
+[1.9: syntax error, unexpected "number"
+calc: error: 2222 != 1])
 AT_CHECK_POPDEFS
 
 AT_CLEANUP
@@ -673,8 +698,9 @@ m4_define([AT_CHECK_CALC_LALR1_CC],
 
 # AT_CHECK_CALC_LALR1_CC()
 
-AT_CHECK_CALC_LALR1_CC([%defines %pure-parser %locations])
-# AT_CHECK_CALC_LALR1_CC([%defines])
+AT_CHECK_CALC_LALR1_CC([%defines %locations])
+
+AT_CHECK_CALC_LALR1_CC([%defines])
 # AT_CHECK_CALC_LALR1_CC([%locations])
 # AT_CHECK_CALC_LALR1_CC([%name-prefix="calc"])
 # AT_CHECK_CALC_LALR1_CC([%verbose])
@@ -683,11 +709,11 @@ AT_CHECK_CALC_LALR1_CC([%defines %pure-parser %locations])
 
 # AT_CHECK_CALC_LALR1_CC([%error-verbose %locations])
 
-AT_CHECK_CALC_LALR1_CC([%error-verbose %locations %defines %name-prefix="calc" %verbose %yacc])
+AT_CHECK_CALC_LALR1_CC([%error-verbose %locations %defines %name-prefix="calc" %verbose %yacc])
 
 # AT_CHECK_CALC_LALR1_CC([%debug])
-AT_CHECK_CALC_LALR1_CC([%error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc])
+AT_CHECK_CALC_LALR1_CC([%error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc])
 
-AT_CHECK_CALC_LALR1_CC([%pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc])
+AT_CHECK_CALC_LALR1_CC([%pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc])
 
 # AT_CHECK_CALC_LALR1_CC([%pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc %parse-param {value *result} %parse-param {int *count}])