/[bison]/bison/tests/calc.at
ViewVC logotype

Diff of /bison/tests/calc.at

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.38 by akim, Sun Nov 3 12:16:25 2002 UTC revision 1.39 by akim, Sun Nov 3 16:41:57 2002 UTC
# Line 26  Line 26 
26  # ------------------------- #  # ------------------------- #
27    
28    
29  # _AT_DATA_CALC_Y($1, $2, $3, [CPP-DIRECTIVES])  # _AT_DATA_CALC_Y($1, $2, $3, [BISON-DIRECTIVES])
30  # ---------------------------------------------  # -----------------------------------------------
31  # Produce `calc.y'.  Don't call this macro directly, because it contains  # Produce `calc.y'.  Don't call this macro directly, because it contains
32  # some occurrences of `$1' etc. which will be interpreted by m4.  So  # some occurrences of `$1' etc. which will be interpreted by m4.  So
33  # you should call it with $1, $2, and $3 as arguments, which is what  # you should call it with $1, $2, and $3 as arguments, which is what
# Line 37  m4_define([_AT_DATA_CALC_Y], Line 37  m4_define([_AT_DATA_CALC_Y],
37         [m4_fatal([$0: Invalid arguments: $@])])dnl         [m4_fatal([$0: Invalid arguments: $@])])dnl
38  AT_DATA([calc.y],  AT_DATA([calc.y],
39  [[/* Infix notation calculator--calc */  [[/* Infix notation calculator--calc */
40    ]$4[
41  %{  %{
42  #include <config.h>  #include <config.h>
43  /* We don't need perfect functions for these tests. */  /* We don't need perfect functions for these tests. */
# Line 63  int global_count = 0; Line 63  int global_count = 0;
63    
64  %}  %}
65    
 %parse-param "value_t *result", "result"  
 %parse-param "int *count",      "count"  
   
66  /* Exercise %union. */  /* Exercise %union. */
67  %union  %union
68  {  {
# Line 81  int global_count = 0; Line 78  int global_count = 0;
78  #  define VAL     (yylval)  #  define VAL     (yylval)
79  #endif  #endif
80    
81    #define YYLLOC_FORMAL   ]AT_LOCATION_IF([, YYLTYPE *yylloc])[
82    #define YYLLOC_ARG      ]AT_LOCATION_IF([, yylloc])[
83    #define USE_YYLLOC      ]AT_LOCATION_IF([(void) yylloc;])[
84    
85  #if YYPURE  #if YYPURE
86  #  if YYLSP_NEEDED  #  define LEX_FORMALS     YYSTYPE *yylval YYLLOC_FORMAL
87  #    define LEX_FORMALS     YYSTYPE *yylval, YYLTYPE *yylloc  #  define LEX_ARGS        yylval          YYLLOC_ARG
88  #    define LEX_ARGS        yylval, yylloc  #  define USE_LEX_ARGS    (void) yylval;  USE_YYLLOC
 #    define USE_LEX_ARGS    (void) yylval; (void) yylloc;  
 #  else  
 #    define LEX_FORMALS     YYSTYPE *yylval  
 #    define LEX_ARGS        yylval  
 #    define USE_LEX_ARGS    (void) yylval  
 #  endif  
89  #  define LEX_PRE_FORMALS   LEX_FORMALS,  #  define LEX_PRE_FORMALS   LEX_FORMALS,
90  #  define LEX_PRE_ARGS      LEX_ARGS,  #  define LEX_PRE_ARGS      LEX_ARGS,
91  #else  #else
# Line 102  int global_count = 0; Line 97  int global_count = 0;
97  #endif  #endif
98    
99  static int power (int base, int exponent);  static int power (int base, int exponent);
100  static void yyerror (const char *s);  /* yyerror receives the location if:
101       - %location & %pure & %glr
102       - %location & %pure & %yacc & %parse-param. */
103    static void yyerror (const char *s
104                         ]AT_YYERROR_ARG_LOC_IF([, YYLTYPE *yylloc])[
105                         ]AT_PARAM_IF([, value_t *result, int *count])[
106                         );
107  static int yylex (LEX_FORMALS);  static int yylex (LEX_FORMALS);
108  static int yygetc (LEX_FORMALS);  static int yygetc (LEX_FORMALS);
109  static void yyungetc (LEX_PRE_FORMALS int c);  static void yyungetc (LEX_PRE_FORMALS int c);
# Line 119  static void yyungetc (LEX_PRE_FORMALS in Line 120  static void yyungetc (LEX_PRE_FORMALS in
120  %left NEG     /* negation--unary minus */  %left NEG     /* negation--unary minus */
121  %right '^'    /* exponentiation        */  %right '^'    /* exponentiation        */
122    
 ]$4[  
   
123  /* Grammar follows */  /* Grammar follows */
124  %%  %%
125  input:  input:
126    line    line
127  | input line         { ++*count; ++global_count; }  | input line         { ]AT_PARAM_IF([++*count; ++global_count;])[ }
128  ;  ;
129    
130  line:  line:
131    '\n'    '\n'
132  | exp '\n'           { *result = global_result = $1; }  | exp '\n'           { ]AT_PARAM_IF([*result = global_result = $1;])[ }
133  ;  ;
134    
135  exp:  exp:
136    NUM                { $$ = $1;             }    NUM                { $$ = $1;             }
137  | exp '=' exp  | exp '=' exp
138    {    {
139       if ($1 != $3)      if ($1 != $3)
140         fprintf (stderr, "calc: error: %d != %d\n", $1, $3);        fprintf (stderr, "calc: error: %d != %d\n", $1, $3);
141       $$ = $1;      $$ = $1;
142    }    }
143  | exp '+' exp        { $$ = $1 + $3;        }  | exp '+' exp        { $$ = $1 + $3;        }
144  | exp '-' exp        { $$ = $1 - $3;        }  | exp '-' exp        { $$ = $1 - $3;        }
# Line 155  exp: Line 154  exp:
154  FILE *yyin;  FILE *yyin;
155    
156  static void  static void
157  yyerror (const char *s)  yyerror (const char *s
158             ]AT_YYERROR_ARG_LOC_IF([, YYLTYPE *yylloc])[
159             ]AT_PARAM_IF([, value_t *result, int *count])[)
160  {  {
161  #if YYLSP_NEEDED  ]AT_YYERROR_SEES_LOC_IF([
162    fprintf (stderr, "%d.%d-%d.%d: ",    fprintf (stderr, "%d.%d-%d.%d: ",
163             LOC.first_line, LOC.first_column,             LOC.first_line, LOC.first_column,
164             LOC.last_line, LOC.last_column);             LOC.last_line, LOC.last_column);
165  #endif  ])[
166    fprintf (stderr, "%s\n", s);    fprintf (stderr, "%s\n", s);
167  }  }
168    
169    
170  #if YYLSP_NEEDED  ]AT_LOCATION_IF([
171  static YYLTYPE last_yylloc;  static YYLTYPE last_yylloc;
172  #endif  ])[
173  static int  static int
174  yygetc (LEX_FORMALS)  yygetc (LEX_FORMALS)
175  {  {
176    int res = getc (yyin);    int res = getc (yyin);
177    USE_LEX_ARGS;    USE_LEX_ARGS;
178  #if YYLSP_NEEDED  ]AT_LOCATION_IF([
179    last_yylloc = LOC;    last_yylloc = LOC;
180    if (res == '\n')    if (res == '\n')
181      {      {
# Line 183  yygetc (LEX_FORMALS) Line 184  yygetc (LEX_FORMALS)
184      }      }
185    else    else
186      LOC.last_column++;      LOC.last_column++;
187  #endif  ])[
188    return res;    return res;
189  }  }
190    
# Line 192  static void Line 193  static void
193  yyungetc (LEX_PRE_FORMALS int c)  yyungetc (LEX_PRE_FORMALS int c)
194  {  {
195    USE_LEX_ARGS;    USE_LEX_ARGS;
196  #if YYLSP_NEEDED  ]AT_LOCATION_IF([
197    /* Wrong when C == `\n'. */    /* Wrong when C == `\n'. */
198    LOC = last_yylloc;    LOC = last_yylloc;
199  #endif  ])[
200    ungetc (c, yyin);    ungetc (c, yyin);
201  }  }
202    
# Line 241  yylex (LEX_FORMALS) Line 242  yylex (LEX_FORMALS)
242    if (init)    if (init)
243      {      {
244        init = 0;        init = 0;
245  #if YYLSP_NEEDED  ]AT_LOCATION_IF([
246        LOC.last_column = 1;        LOC.last_column = 1;
247        LOC.last_line = 1;        LOC.last_line = 1;
248  #endif  ])[
249      }      }
250    
251  #if YYLSP_NEEDED  ]AT_LOCATION_IF([
252    LOC.first_column = LOC.last_column;    LOC.first_column = LOC.last_column;
253    LOC.first_line = LOC.last_line;    LOC.first_line = LOC.last_line;
254  #endif  ])[
255    
256    /* Skip white space.  */    /* Skip white space.  */
257    while ((c = yygetc (LEX_ARGS)) == ' ' || c == '\t')    while ((c = yygetc (LEX_ARGS)) == ' ' || c == '\t')
258      {      {
259  #if YYLSP_NEEDED  ]AT_LOCATION_IF([
260        LOC.first_column = LOC.last_column;        LOC.first_column = LOC.last_column;
261        LOC.first_line = LOC.last_line;        LOC.first_line = LOC.last_line;
262  #endif  ])[
263      }      }
264    
265    /* process numbers   */    /* process numbers   */
# Line 309  main (int argc, const char **argv) Line 310  main (int argc, const char **argv)
310  #if YYDEBUG  #if YYDEBUG
311    yydebug = 1;    yydebug = 1;
312  #endif  #endif
313    yyparse (&result, &count);    yyparse (]AT_PARAM_IF([&result, &count])[);
314    assert (global_result == result);    assert (global_result == result);
315    assert (global_count  == count);    assert (global_count  == count);
316    
# Line 352  m4_bmatch([$1], Line 353  m4_bmatch([$1],
353    
354    
355  # _AT_CHECK_CALC_ERROR(BISON-OPTIONS, INPUT, [NUM-DEBUG-LINES],  # _AT_CHECK_CALC_ERROR(BISON-OPTIONS, INPUT, [NUM-DEBUG-LINES],
356  #                      [ERROR-LOCATION], [IF-YYERROR-VERBOSE])  #                      [VERBOSE-AND-LOCATED-ERROR-MESSAGE])
357  # ------------------------------------------------------------  # -------------------------------------------------------------
358  # Run `calc' on INPUT, and expect a `parse error' message.  # Run `calc' on INPUT, and expect a `parse error' message.
359  #  #
360  # If INPUT starts with a slash, it is used as absolute input file name,  # If INPUT starts with a slash, it is used as absolute input file name,
# Line 402  AT_DATA([[expout]], Line 403  AT_DATA([[expout]],
403  [$4  [$4
404  ])  ])
405  # 3. If locations are not used, remove them.  # 3. If locations are not used, remove them.
406  m4_bmatch([$1], [%locations], [],  AT_YYERROR_SEES_LOC_IF([],
407  [[sed 's/^[-0-9.]*: //' expout >at-expout  [[sed 's/^[-0-9.]*: //' expout >at-expout
408  mv at-expout expout]])  mv at-expout expout]])
409  # 4. If error-verbose is not used, strip the`, unexpected....' part.  # 4. If error-verbose is not used, strip the`, unexpected....' part.
# Line 414  AT_CHECK([cat stderr], 0, [expout]) Line 415  AT_CHECK([cat stderr], 0, [expout])
415  ])  ])
416    
417    
418    # AT_CALC_PUSHDEFS($1, $2, [BISON-OPTIONS])
419    # -----------------------------------------
420    # This macro works around the impossibility to define macros
421    # inside macros, because issuing `[$1]' is not possible in M4 :(.
422    # This sucks hard, GNU M4 should really provide M5 like $$1.
423    m4_define([AT_CHECK_PUSHDEFS],
424    [m4_if([$1$2], $[1]$[2], [],
425           [m4_fatal([$0: Invalid arguments: $@])])dnl
426    m4_pushdef([AT_PARAM_IF],
427    [m4_bmatch([$3], [%parse-param], [$1], [$2])])
428    m4_pushdef([AT_LOCATION_IF],
429    [m4_bmatch([$3], [%locations], [$1], [$2])])
430    m4_pushdef([AT_PURE_IF],
431    [m4_bmatch([$3], [%pure-parser], [$1], [$2])])
432    m4_pushdef([AT_GLR_IF],
433    [m4_bmatch([$3], [%glr-parser], [$1], [$2])])
434    m4_pushdef([AT_PURE_AND_LOC_IF],
435    [m4_bmatch([$3], [%locations.*%pure-parser\|%pure-parser.*%locations],
436               [$1], [$2])])
437    m4_pushdef([AT_GLR_OR_PARAM_IF],
438    [m4_bmatch([$3], [%glr-parser\|%parse-param], [$1], [$2])])
439    
440    # yyerror receives the location if %location & %pure & (%glr or %parse-param).
441    m4_pushdef([AT_YYERROR_ARG_LOC_IF],
442    [AT_GLR_OR_PARAM_IF([AT_PURE_AND_LOC_IF([$1], [$2])],
443                        [$2])])
444    # yyerror cannot see the locations if !glr & pure.
445    m4_pushdef([AT_YYERROR_SEES_LOC_IF],
446    [AT_LOCATION_IF([AT_GLR_IF([$1],
447                               [AT_PURE_IF([$2], [$1])])],
448                    [$2])])
449    ])
450    
451    
452    # AT_CALC_POPDEFS
453    # ---------------
454    m4_define([AT_CHECK_POPDEFS],
455    [m4_popdef([AT_YYERROR_SEES_LOC_IF])
456    m4_popdef([AT_YYERROR_ARG_LOC_IF])
457    m4_popdef([AT_GLR_OR_PARAM_IF])
458    m4_popdef([AT_PURE_AND_LOC_IF])
459    m4_popdef([AT_GLR_IF])
460    m4_popdef([AT_LOCATION_IF])
461    m4_popdef([AT_PARAM_IF])
462    ])
463    
464    
465    
466  # AT_CHECK_CALC([BISON-OPTIONS])  # AT_CHECK_CALC([BISON-OPTIONS])
467  # ------------------------------  # ------------------------------
468  # Start a testing chunk which compiles `calc' grammar with  # Start a testing chunk which compiles `calc' grammar with
# Line 422  m4_define([AT_CHECK_CALC], Line 471  m4_define([AT_CHECK_CALC],
471  [# We use integers to avoid dependencies upon the precision of doubles.  [# We use integers to avoid dependencies upon the precision of doubles.
472  AT_SETUP([Calculator $1])  AT_SETUP([Calculator $1])
473    
474    AT_CHECK_PUSHDEFS($[1], $[2], [$1])
475    
476  AT_DATA_CALC_Y([$1])  AT_DATA_CALC_Y([$1])
477    
478  # Specify the output files to avoid problems on different file systems.  # Specify the output files to avoid problems on different file systems.
# Line 473  _AT_CHECK_CALC_ERROR([$1], [(1 ++ 2) + ( Line 524  _AT_CHECK_CALC_ERROR([$1], [(1 ++ 2) + (
524  1.15-1.16: parse error, unexpected "number"  1.15-1.16: parse error, unexpected "number"
525  calc: error: 0 != 1])  calc: error: 0 != 1])
526    
527    AT_CHECK_POPDEFS
528    
529  AT_CLEANUP  AT_CLEANUP
530  ])# AT_CHECK_CALC  ])# AT_CHECK_CALC
531    
# Line 508  AT_CHECK_CALC_LALR([%error-verbose %loca Line 561  AT_CHECK_CALC_LALR([%error-verbose %loca
561  AT_CHECK_CALC_LALR([%debug])  AT_CHECK_CALC_LALR([%debug])
562  AT_CHECK_CALC_LALR([%error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc])  AT_CHECK_CALC_LALR([%error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc])
563    
564  # AT_CHECK_CALC_LALR([%pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc])  AT_CHECK_CALC_LALR([%pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc])
565    
566    AT_CHECK_CALC_LALR([%pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc %parse-param "value_t *result", "result" %parse-param "int *count", "count"])
567    
568    
569  # ----------------------- #  # ----------------------- #
# Line 541  AT_CHECK_CALC_GLR([%error-verbose %locat Line 596  AT_CHECK_CALC_GLR([%error-verbose %locat
596  AT_CHECK_CALC_GLR([%debug])  AT_CHECK_CALC_GLR([%debug])
597  AT_CHECK_CALC_GLR([%error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc])  AT_CHECK_CALC_GLR([%error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc])
598    
599  # AT_CHECK_CALC_GLR([%pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc])  AT_CHECK_CALC_GLR([%pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc])
600    
601    AT_CHECK_CALC_GLR([%pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc %parse-param "value_t *result", "result" %parse-param "int *count", "count"])

Legend:
Removed from v.1.38  
changed lines
  Added in v.1.39

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26