]> git.saurik.com Git - bison.git/commitdiff
2007-03-07 Paolo Bonzini <bonzini@gnu.org>
authorPaolo Bonzini <bonzini@gnu.org>
Fri, 9 Mar 2007 09:13:43 +0000 (09:13 +0000)
committerPaolo Bonzini <bonzini@gnu.org>
Fri, 9 Mar 2007 09:13:43 +0000 (09:13 +0000)
        * data/java.m4 (b4_single_class_if): Remove.
        (b4_abstract_if): Look at "%define abstract".
        (b4_lexer_if): New.
        (b4_union_name): Rename...
        (b4_yystype): ... to this.  Map to "%define stype".
        (b4_rhs_value, b4_parse_param_decl, b4_lex_param_decl,
        b4_maybe_throws): Fix quoting.
        (b4_lex_param_call): Move below to keep b4_*_param_decl close.
        * data/lalr1.java (Lexer interface): Always define.
        (Lexer interface within parser class): Remove.
        (YYLexer class): New, used when "%code lexer" is present.
        (constructor): When "%code lexer" is used, pass %lex-param
        to the lexer constructor.
        (yylex, yyparse): Remove %lex-param from method invocations
        (YYStack, yyaction, yyparse): Rename b4_union_name to b4_yystype.

        * doc/bison.texinfo (Java Bison Interface): Mention "%define
        abstract".  Rename "%define union_name" to "%define stype".
        Rename method names according to previous patch.
        (Java Scanner Interface): Describe "%code lexer" instead of
        "%pure-parser" and "%define single_class".
        (Java Differences): Mention "%code lexer".

        * tests/java.at (_AT_DATA_JAVA_CALC_Y): Remove final argument.
        Include scanner here, using macros from tests/local.at.
        (AT_DATA_CALC_Y): Remove final argument.
        (_AT_CHECK_JAVA_CALC): Likewise.
        (AT_CHECK_JAVA_CALC): Likewise.  Test all four combinations
        of %locations and %error-verbose.
        (main): Test with and without %lex-param.
        * tests/local.at (_AT_BISON_OPTION_PUSHDEFS): Push AT_LEXPARAM_IF.
        (AT_BISON_OPTION_POPDEFS): Pop it.

ChangeLog
data/java.m4
data/lalr1.java
doc/bison.texinfo
tests/java.at
tests/local.at

index f00768ad69b0e2e0c0214478d786f7cb218fe3b0..ef4793567015527ce39bcb6e55ab070daeae9918 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,38 @@
+2007-03-07  Paolo Bonzini  <bonzini@gnu.org>
+
+        * data/java.m4 (b4_single_class_if): Remove.
+        (b4_abstract_if): Look at "%define abstract".
+        (b4_lexer_if): New.
+        (b4_union_name): Rename...
+        (b4_yystype): ... to this.  Map to "%define stype".
+        (b4_rhs_value, b4_parse_param_decl, b4_lex_param_decl,
+        b4_maybe_throws): Fix quoting.
+        (b4_lex_param_call): Move below to keep b4_*_param_decl close.
+        * data/lalr1.java (Lexer interface): Always define.
+        (Lexer interface within parser class): Remove.
+        (YYLexer class): New, used when "%code lexer" is present.
+        (constructor): When "%code lexer" is used, pass %lex-param
+        to the lexer constructor.
+        (yylex, yyparse): Remove %lex-param from method invocations
+        (YYStack, yyaction, yyparse): Rename b4_union_name to b4_yystype.
+
+        * doc/bison.texinfo (Java Bison Interface): Mention "%define
+        abstract".  Rename "%define union_name" to "%define stype".
+        Rename method names according to previous patch.
+        (Java Scanner Interface): Describe "%code lexer" instead of
+        "%pure-parser" and "%define single_class".
+        (Java Differences): Mention "%code lexer".
+
+        * tests/java.at (_AT_DATA_JAVA_CALC_Y): Remove final argument.
+        Include scanner here, using macros from tests/local.at.
+        (AT_DATA_CALC_Y): Remove final argument.
+        (_AT_CHECK_JAVA_CALC): Likewise.
+        (AT_CHECK_JAVA_CALC): Likewise.  Test all four combinations
+        of %locations and %error-verbose.
+        (main): Test with and without %lex-param.
+        * tests/local.at (_AT_BISON_OPTION_PUSHDEFS): Push AT_LEXPARAM_IF.
+        (AT_BISON_OPTION_POPDEFS): Pop it.
+
 2007-03-07  Juan Manuel Guerrero  <juan.guerrero@gmx.de>
 
        DJGPP spefic issue.  Inhibit the use of disallowed characters for
 2007-03-07  Juan Manuel Guerrero  <juan.guerrero@gmx.de>
 
        DJGPP spefic issue.  Inhibit the use of disallowed characters for
index 38820f0d20fb36eca4ed25fd6499406f0d0f652e..4fd7625888f67f8d81df7b1b2704b716a930e0f0 100644 (file)
@@ -38,17 +38,18 @@ b4_percent_define_default([[public]], [[false]])
 m4_define([b4_public_if],
 [b4_percent_define_flag_if([public], [$1], [$2])])
 
 m4_define([b4_public_if],
 [b4_percent_define_flag_if([public], [$1], [$2])])
 
-# b4_single_class_if(TRUE, FALSE)
-# -------------------------------
-b4_percent_define_default([[single_class]], [[false]])
-m4_define([b4_single_class_if],
-[b4_percent_define_flag_if([single_class], [$1], [$2])])
-
 
 # b4_abstract_if(TRUE, FALSE)
 # ---------------------------
 
 # b4_abstract_if(TRUE, FALSE)
 # ---------------------------
+b4_percent_define_default([[abstract]], [[false]])
 m4_define([b4_abstract_if],
 m4_define([b4_abstract_if],
-[b4_pure_if([$2], [b4_single_class_if([$2], [$1])])])
+[b4_percent_define_flag_if([abstract], [$1], [$2])])
+
+
+# b4_lexer_if(TRUE, FALSE)
+# ------------------------
+m4_define([b4_lexer_if],
+[b4_percent_code_ifdef([[lexer]], [$1], [$2])])
 
 
 # b4_identification
 
 
 # b4_identification
@@ -126,8 +127,8 @@ m4_define([b4_case], [  case $1:
 ## Default values.  ##
 ## ---------------- ##
 
 ## Default values.  ##
 ## ---------------- ##
 
-m4_define([b4_union_name], [b4_percent_define_get([[union_name]])])
-b4_percent_define_default([[union_name]], [[Object]])])
+m4_define([b4_yystype], [b4_percent_define_get([[stype]])])
+b4_percent_define_default([[stype]], [[Object]])])
 
 m4_define_default([[b4_prefix]], [[YY]])])
 b4_percent_define_default([[parser_class_name]], [b4_prefix[]Parser])])
 
 m4_define_default([[b4_prefix]], [[YY]])])
 b4_percent_define_default([[parser_class_name]], [b4_prefix[]Parser])])
@@ -165,7 +166,7 @@ m4_define([b4_lhs_value], [yyval])
 # In this simple implementation, %token and %type have class names
 # between the angle brackets.
 m4_define([b4_rhs_value],
 # In this simple implementation, %token and %type have class names
 # between the angle brackets.
 m4_define([b4_rhs_value],
-[(m4_ifval([$3], [($3)])[](yystack.valueAt ($1-($2))))])
+[(m4_ifval($3, [($3)])[](yystack.valueAt ($1-($2))))])
 
 # b4_lhs_location()
 # -----------------
 
 # b4_lhs_location()
 # -----------------
@@ -199,25 +200,14 @@ m4_define([b4_parse_param], b4_parse_param))
 m4_define([b4_lex_param_decl],
 [m4_ifset([b4_lex_param],
           [b4_remove_comma([$1],
 m4_define([b4_lex_param_decl],
 [m4_ifset([b4_lex_param],
           [b4_remove_comma([$1],
-                          [m4_map([b4_lex_param_decl_1], [b4_lex_param])])],
+                          b4_param_decls(b4_lex_param))],
          [$1])])
 
          [$1])])
 
-m4_define([b4_lex_param_decl_1], [, $1])
-m4_define([b4_remove_comma], [m4_ifval([$1], [$1, ], [])m4_cdr([m4_cdr($@)])])
+m4_define([b4_param_decls],
+         [m4_map([b4_param_decl], [$@])])
+m4_define([b4_param_decl], [, $1])
 
 
-
-
-# b4_lex_param_call
-# -------------------
-# Extra initialisations of the constructor.
-m4_define([b4_lex_param_call],
-          [m4_ifset([b4_lex_param],
-                   [b4_remove_comma([$1],
-                                    [b4_lex_param_calls(b4_lex_param)])],
-                   [$1])])
-m4_define([b4_lex_param_calls],
-         [m4_map([b4_lex_param_call_1], [$@])])
-m4_define([b4_lex_param_call_1], [, $2])
+m4_define([b4_remove_comma], [m4_ifval($1, [$1, ], [])m4_shiftn(2, $@)])
 
 
 
 
 
 
@@ -227,11 +217,22 @@ m4_define([b4_lex_param_call_1], [, $2])
 m4_define([b4_parse_param_decl],
 [m4_ifset([b4_parse_param],
           [b4_remove_comma([$1],
 m4_define([b4_parse_param_decl],
 [m4_ifset([b4_parse_param],
           [b4_remove_comma([$1],
-                          [m4_map([b4_parse_param_decl_1],
-                                  [b4_parse_param])])],
+                          b4_param_decls(b4_parse_param))],
          [$1])])
 
          [$1])])
 
-m4_define([b4_parse_param_decl_1], [, $1])
+
+
+# b4_lex_param_call
+# -------------------
+# Delegating the lexer parameters to the lexer constructor.
+m4_define([b4_lex_param_call],
+          [m4_ifset([b4_lex_param],
+                   [b4_remove_comma([$1],
+                                    b4_param_calls(b4_lex_param))],
+                   [$1])])
+m4_define([b4_param_calls],
+         [m4_map([b4_param_call], [$@])])
+m4_define([b4_param_call], [, $2])
 
 
 
 
 
 
@@ -241,12 +242,15 @@ m4_define([b4_parse_param_decl_1], [, $1])
 m4_define([b4_parse_param_cons],
           [m4_ifset([b4_parse_param],
                    [b4_constructor_calls(b4_parse_param)])])
 m4_define([b4_parse_param_cons],
           [m4_ifset([b4_parse_param],
                    [b4_constructor_calls(b4_parse_param)])])
+
 m4_define([b4_constructor_calls],
          [m4_map([b4_constructor_call], [$@])])
 m4_define([b4_constructor_call],
          [this.$2 = $2;
          ])
 
 m4_define([b4_constructor_calls],
          [m4_map([b4_constructor_call], [$@])])
 m4_define([b4_constructor_call],
          [this.$2 = $2;
          ])
 
+
+
 # b4_parse_param_vars
 # -------------------
 # Extra instance variables.
 # b4_parse_param_vars
 # -------------------
 # Extra instance variables.
@@ -255,14 +259,17 @@ m4_define([b4_parse_param_vars],
                    [
     /* User arguments.  */
 b4_var_decls(b4_parse_param)])])
                    [
     /* User arguments.  */
 b4_var_decls(b4_parse_param)])])
+
 m4_define([b4_var_decls],
          [m4_map_sep([b4_var_decl], [
 ], [$@])])
 m4_define([b4_var_decl],
          [    protected final $1;])
 
 m4_define([b4_var_decls],
          [m4_map_sep([b4_var_decl], [
 ], [$@])])
 m4_define([b4_var_decl],
          [    protected final $1;])
 
+
+
 # b4_maybe_throws(THROWS)
 # -----------------------
 # Expand to either an empty string or "throws THROWS".
 m4_define([b4_maybe_throws],
 # b4_maybe_throws(THROWS)
 # -----------------------
 # Expand to either an empty string or "throws THROWS".
 m4_define([b4_maybe_throws],
-         [m4_ifval([$1], [throws $1])])
+         [m4_ifval($1, [throws $1])])
index 6d2637528575c6a91f354327c8e26eb496d65c33..fc2d8484b5c2d8946e9b7ceacaed1afcaca75c58 100644 (file)
@@ -103,7 +103,7 @@ b4_token_enums(b4_tokens)
       return new ]b4_location_type[ (rhs.locationAt (0).end);
   }]])
 
       return new ]b4_location_type[ (rhs.locationAt (0).end);
   }]])
 
-  b4_pure_if([[/**
+  /**
    * Communication interface between the scanner and the Bison-generated
    * parser <tt>]b4_parser_class_name[</tt>.
    */
    * Communication interface between the scanner and the Bison-generated
    * parser <tt>]b4_parser_class_name[</tt>.
    */
@@ -121,30 +121,15 @@ b4_token_enums(b4_tokens)
     /**
      * Method to retrieve the semantic value of the last scanned token.
      * @@return the semantic value of the last scanned token.  */
     /**
      * Method to retrieve the semantic value of the last scanned token.
      * @@return the semantic value of the last scanned token.  */
-    ]b4_union_name[ getLVal ();]], [[
-
-    /**
-     * A place where the scanner can store the beginning position of the
-     * last scanned token.  */
-    ]b4_locations_if([b4_position_type[ yystartpos;]])[
-
-    /**
-     * A place where the scanner can store the ending position of the last
-     * scanned token, i.e. the first position beyond the last scanned token.  */
-    ]b4_locations_if([b4_position_type[ yyendpos;]])[
+    ]b4_yystype[ getLVal ();]
 
     /**
 
     /**
-     * A place where the scanner can store the semantic value of the
-     * last scanned token.  */
-    protected ]b4_union_name[ yylval;]])
-
-    b4_single_class_if([], [[/**
      * Entry point for the scanner.  Returns the token identifier corresponding
      * to the next token and ]b4_pure_if([prepares to return], [stores])[
      * the semantic value]b4_locations_if([ and beginning/ending positions])[
      * of the token. 
      * @@return the token identifier corresponding to the next token. */
      * Entry point for the scanner.  Returns the token identifier corresponding
      * to the next token and ]b4_pure_if([prepares to return], [stores])[
      * the semantic value]b4_locations_if([ and beginning/ending positions])[
      * of the token. 
      * @@return the token identifier corresponding to the next token. */
-    abstract int yylex (]b4_lex_param_decl) b4_maybe_throws([b4_lex_throws])[;
+    int yylex () ]b4_maybe_throws([b4_lex_throws])[;
 
     /**
      * Entry point for error reporting.  Emits an error
 
     /**
      * Entry point for error reporting.  Emits an error
@@ -154,20 +139,35 @@ b4_token_enums(b4_tokens)
      * ]b4_locations_if([loc], [[The location of the element to which the
      *                error message is related]])[
      * @@param s The string for the error message.  */
      * ]b4_locations_if([loc], [[The location of the element to which the
      *                error message is related]])[
      * @@param s The string for the error message.  */
-     abstract void yyerror (]b4_locations_if([b4_location_type[ loc, ]])[String s);]])
-  b4_pure_if([}
+     void yyerror (]b4_locations_if([b4_location_type[ loc, ]])[String s);]
+  }
+
+  b4_lexer_if([[private class YYLexer implements Lexer {
+]b4_percent_code_get([[lexer]])[
+  }
 
 
-  /** The object doing lexical analysis for us.  */
-  private Lexer yylex;])
-  b4_parse_param_vars[
+  ]])[/** The object doing lexical analysis for us.  */
+  private Lexer yylexer;
+  ]
+  b4_parse_param_vars
 
 
+b4_lexer_if([[
   /**
   /**
-   * Instantiates the Bison-generated parser.  ]b4_pure_if([
-   * @@param yylex The scanner that will supply tokens to the parser.])[
+   * Instantiates the Bison-generated parser.
    */
    */
-  public ]b4_parser_class_name[ (]b4_parse_param_decl([b4_pure_if([Lexer yylex])])[) {
-    ]b4_pure_if(this.yylex = yylex;)
-    b4_parse_param_cons[
+  public ]b4_parser_class_name (b4_parse_param_decl([b4_lex_param_decl])[) {
+    this.yylexer = new YYLexer(]b4_lex_param_call[);
+    ]b4_parse_param_cons[
+  }
+]])
+
+  /**
+   * Instantiates the Bison-generated parser.
+   * @@param yylex The scanner that will supply tokens to the parser.
+   */
+  b4_lexer_if([[protected]], [[public]]) b4_parser_class_name[ (]b4_parse_param_decl([[Lexer yylexer]])[) {
+    this.yylexer = yylexer;
+    ]b4_parse_param_cons[
   }
 
   private java.io.PrintStream yyDebugStream = System.err;
   }
 
   private java.io.PrintStream yyDebugStream = System.err;
@@ -199,19 +199,19 @@ b4_token_enums(b4_tokens)
    */
   public final void setDebugLevel(int level) { yydebug = level; }
 
    */
   public final void setDebugLevel(int level) { yydebug = level; }
 
-  ]b4_pure_if([[
-  private final int yylex (]b4_lex_param_decl) b4_maybe_throws([b4_lex_throws]) [{
-    return yylex.yylex (]b4_lex_param_call[);
+  private final int yylex () ]b4_maybe_throws([b4_lex_throws]) [{
+    return yylexer.yylex ();
   }
   protected final void yyerror (]b4_locations_if([b4_location_type[ loc, ]])[String s) {
   }
   protected final void yyerror (]b4_locations_if([b4_location_type[ loc, ]])[String s) {
-    yylex.yyerror (]b4_locations_if([loc, ])[s);
-  }]])
-  b4_locations_if([
+    yylexer.yyerror (]b4_locations_if([loc, ])[s);
+  }
+
+  ]b4_locations_if([
   protected final void yyerror (String s) {
   protected final void yyerror (String s) {
-    yyerror ((Location)null, s);
+    yylexer.yyerror ((Location)null, s);
   }
   protected final void yyerror (]b4_position_type[ loc, String s) {
   }
   protected final void yyerror (]b4_position_type[ loc, String s) {
-    yyerror (new ]b4_location_type[ (loc), s);
+    yylexer.yyerror (new ]b4_location_type[ (loc), s);
   }])
 
   [protected final void yycdebug (String s) {
   }])
 
   [protected final void yycdebug (String s) {
@@ -222,12 +222,12 @@ b4_token_enums(b4_tokens)
   private final class YYStack {
     private int[] stateStack = new int[16];
     ]b4_locations_if([[private ]b4_location_type[[] locStack = new ]b4_location_type[[16];]])[
   private final class YYStack {
     private int[] stateStack = new int[16];
     ]b4_locations_if([[private ]b4_location_type[[] locStack = new ]b4_location_type[[16];]])[
-    private ]b4_union_name[[] valueStack = new ]b4_union_name[[16];
+    private ]b4_yystype[[] valueStack = new ]b4_yystype[[16];
 
     public int size = 16;
     public int height = -1;
     
 
     public int size = 16;
     public int height = -1;
     
-    public final void push (int state, ]b4_union_name[ value]dnl
+    public final void push (int state, ]b4_yystype[ value]dnl
                            b4_locations_if([, ]b4_location_type[ loc])[) {
       height++;
       if (size == height) 
                            b4_locations_if([, ]b4_location_type[ loc])[) {
       height++;
       if (size == height) 
@@ -240,7 +240,7 @@ b4_token_enums(b4_tokens)
          System.arraycopy (locStack, 0, newLocStack, 0, height);
          locStack = newLocStack;]])
          
          System.arraycopy (locStack, 0, newLocStack, 0, height);
          locStack = newLocStack;]])
          
-         b4_union_name[[] newValueStack = new ]b4_union_name[[size * 2];
+         b4_yystype[[] newValueStack = new ]b4_yystype[[size * 2];
          System.arraycopy (valueStack, 0, newValueStack, 0, height);
          valueStack = newValueStack;
 
          System.arraycopy (valueStack, 0, newValueStack, 0, height);
          valueStack = newValueStack;
 
@@ -273,7 +273,7 @@ b4_token_enums(b4_tokens)
       return locStack[height - i];
     }
 
       return locStack[height - i];
     }
 
-    ]])[public final ]b4_union_name[ valueAt (int i) {
+    ]])[public final ]b4_yystype[ valueAt (int i) {
       return valueStack[height - i];
     }
 
       return valueStack[height - i];
     }
 
@@ -330,7 +330,7 @@ b4_token_enums(b4_tokens)
 
   private int yyaction (int yyn, YYStack yystack, int yylen)
   {
 
   private int yyaction (int yyn, YYStack yystack, int yylen)
   {
-    ]b4_union_name[ yyval;
+    ]b4_yystype[ yyval;
     ]b4_locations_if([b4_location_type[ yyloc = yylloc (yystack, yylen);]])[
 
     /* If YYLEN is nonzero, implement the default value of the action:
     ]b4_locations_if([b4_location_type[ yyloc = yylloc (yystack, yylen);]])[
 
     /* If YYLEN is nonzero, implement the default value of the action:
@@ -410,7 +410,7 @@ b4_token_enums(b4_tokens)
   `--------------------------------*/
 
   private void yy_symbol_print (String s, int yytype,
   `--------------------------------*/
 
   private void yy_symbol_print (String s, int yytype,
-                                ]b4_union_name[ yyvaluep]dnl
+                                ]b4_yystype[ yyvaluep]dnl
                                 b4_locations_if([, Object yylocationp])[)
   {
     if (yydebug > 0)
                                 b4_locations_if([, Object yylocationp])[)
   {
     if (yydebug > 0)
@@ -452,7 +452,7 @@ b4_token_enums(b4_tokens)
     ]b4_location_type[ yyloc;])
 
     /// Semantic value of the lookahead.
     ]b4_location_type[ yyloc;])
 
     /// Semantic value of the lookahead.
-    b4_union_name[ yylval = null;
+    b4_yystype[ yylval = null;
 
     int yyresult;
 
 
     int yyresult;
 
@@ -497,13 +497,11 @@ m4_popdef([b4_at_dollar])])dnl
         if (yychar == yyempty_)
           {
            yycdebug ("Reading a token: ");
         if (yychar == yyempty_)
           {
            yycdebug ("Reading a token: ");
-           yychar = yylex (]b4_lex_param_call[);]
-            b4_locations_if([
-           b4_pure_if([yylloc = new ]b4_location_type[(yylex.getStartPos (),
-                                                       yylex.getEndPos ());],
-                      [yylloc = new ]b4_location_type[(this.yystartpos,
-                                                       this.yyendpos);]);])
-            b4_pure_if([yylval = yylex.getLVal ()], [yylval = this.yylval]);[
+           yychar = yylex ();]
+            b4_locations_if([[
+           yylloc = new ]b4_location_type[(yylexer.getStartPos (),
+                                           yylexer.getEndPos ());]])
+            yylval = yylexer.getLVal ();[
           }
     
         /* Convert token to internal form.  */
           }
     
         /* Convert token to internal form.  */
index fe9e4b5283c90c7d1df75cd7fa2c76b3b0d9e68e..c226a077a6e3335624b255141ec11c9cddbcddee 100644 (file)
@@ -8380,7 +8380,10 @@ Remember that, according to the Java language specification, the name
 of the @file{.java} file should match the name of the class in this
 case.
 
 of the @file{.java} file should match the name of the class in this
 case.
 
-All these files are documented using Javadoc.
+Similarly, a declaration @samp{%define "abstract"} will make your
+class abstract.
+
+You can create documentation for generated parsers using Javadoc.
 
 @node Java Semantic Values
 @subsection Java Semantic Values
 
 @node Java Semantic Values
 @subsection Java Semantic Values
@@ -8404,7 +8407,7 @@ superclass of all the semantic values using the @samp{%define} directive.
 For example, after the following declaration:
 
 @example
 For example, after the following declaration:
 
 @example
-%define "union_name" "ASTNode"
+%define "stype" "ASTNode"
 @end example
 
 @noindent
 @end example
 
 @noindent
@@ -8483,7 +8486,7 @@ Run the syntactic analysis, and return @code{true} on success,
 @code{false} otherwise.
 @end deftypemethod
 
 @code{false} otherwise.
 @end deftypemethod
 
-@deftypemethod {YYParser} {boolean} yyrecovering ()
+@deftypemethod {YYParser} {boolean} recovering ()
 During the syntactic analysis, return @code{true} if recovering
 from a syntax error.  @xref{Error Recovery}.
 @end deftypemethod
 During the syntactic analysis, return @code{true} if recovering
 from a syntax error.  @xref{Error Recovery}.
 @end deftypemethod
@@ -8510,33 +8513,39 @@ Interface}); the parser uses it to report a parser error occurring at
 
 @node Java Scanner Interface
 @subsection Java Scanner Interface
 
 @node Java Scanner Interface
 @subsection Java Scanner Interface
-@c - prefix for yylex.
-@c - Pure interface to yylex
+@c - %code lexer
 @c - %lex-param
 @c - %lex-param
+@c - Lexer interface
 
 
-There are two possible ways to interface a Bison-generated Java parser
-with a scanner.
-
-@cindex pure parser, in Java
 Contrary to C parsers, Java parsers do not use global variables; the
 state of the parser is always local to an instance of the parser class.
 Contrary to C parsers, Java parsers do not use global variables; the
 state of the parser is always local to an instance of the parser class.
-Therefore, all Java parsers are ``pure'' in the C sense.  The
-@code{%pure-parser} directive can still be used in Java, and it
-will control whether the lexer resides in a separate class than the
-Bison-generated parser (therefore, Bison generates a class that is
-``purely'' a parser), or in the same class.  The interface to the scanner
-is similar, though the two cases present a slightly different naming.
-
-For the @code{%pure-parser} case, the scanner implements an interface
-called @code{Lexer} and defined within the parser class (e.g.,
-@code{YYParser.Lexer}.  The constructor of the parser object accepts
-an object implementing the interface.  The interface specifies
-the following methods.
-
-@deftypemethod {Lexer} {void} error (Location @var{l}, String @var{m})
+Therefore, all Java parsers are ``pure'', and the @code{%pure-parser}
+directive does not do anything when used in Java.
+
+The scanner always resides in a separate class than the parser.
+Still, Java also two possible ways to interface a Bison-generated Java
+parser with a scanner, that is, the scanner may reside in a separate file
+than the Bison grammar, or in the same file.  The interface
+to the scanner is similar in the two cases.
+
+In the first case, where the scanner in the same file as the grammar, the
+scanner code has to be placed in @code{%code lexer} blocks.  If you want
+to pass parameters from the parser constructor to the scanner constructor,
+specify them with @code{%lex-param}; they are passed before
+@code{%parse-param}s to the constructor.
+
+In the second case, the scanner has to implement interface @code{Lexer},
+which is defined within the parser class (e.g., @code{YYParser.Lexer}).
+The constructor of the parser object will then accept an object
+implementing the interface; @code{%lex-param} is not used in this
+case.
+
+In both cases, the scanner has to implement the following methods.
+
+@deftypemethod {Lexer} {void} yyerror (Location @var{l}, String @var{m})
 As explained in @pxref{Java Parser Interface}, this method is defined
 As explained in @pxref{Java Parser Interface}, this method is defined
-by the user to emit an error message.  The first parameter is not used
-unless location tracking is active.  Its type can be changed using
+by the user to emit an error message.  The first parameter is omitted
+if location tracking is not active.  Its type can be changed using
 @samp{%define "location_type" "@var{class-name}".}
 @end deftypemethod
 
 @samp{%define "location_type" "@var{class-name}".}
 @end deftypemethod
 
@@ -8549,9 +8558,9 @@ interface.  Invocations of @samp{%lex-param @{@var{type1}
 
 @deftypemethod {Lexer} {Position} getStartPos ()
 @deftypemethodx {Lexer} {Position} getEndPos ()
 
 @deftypemethod {Lexer} {Position} getStartPos ()
 @deftypemethodx {Lexer} {Position} getEndPos ()
-Return respectively the first position of the last token that yylex
-returned, and the first position beyond it.  These methods are not
-needed unless location tracking is active.
+Return respectively the first position of the last token that
+@code{yylex} returned, and the first position beyond it.  These
+methods are not needed unless location tracking is active.
 
 The return type can be changed using @samp{%define "position_type"
 "@var{class-name}".}
 
 The return type can be changed using @samp{%define "position_type"
 "@var{class-name}".}
@@ -8561,7 +8570,7 @@ The return type can be changed using @samp{%define "position_type"
 Return respectively the first position of the last token that yylex
 returned, and the first position beyond it.
 
 Return respectively the first position of the last token that yylex
 returned, and the first position beyond it.
 
-The return type can be changed using @samp{%define "union_name"
+The return type can be changed using @samp{%define "stype"
 "@var{class-name}".}
 @end deftypemethod
 
 "@var{class-name}".}
 @end deftypemethod
 
@@ -8599,19 +8608,10 @@ The field's type can be changed using @samp{%define "position_type"
 Return respectively the first position of the last token that yylex
 returned, and the first position beyond it.
 
 Return respectively the first position of the last token that yylex
 returned, and the first position beyond it.
 
-The field's type can be changed using @samp{%define "union_name"
+The field's type can be changed using @samp{%define "stype"
 "@var{class-name}".}
 @end deftypecv
 
 "@var{class-name}".}
 @end deftypecv
 
-By default the class generated for a non-pure Java parser is abstract,
-and the methods @code{yylex} and @code{yyerror} shall be placed in a
-subclass (possibly defined in the additional code section).  It is
-also possible, using the @code{%define "single_class"} declaration, to
-define the scanner in the same class as the parser; when this
-declaration is present, the class is not declared as abstract.
-In order to place the declarations for the scanner inside the
-parser class, you should use @code{%code} sections.
-
 @node Java Differences
 @subsection Differences between C/C++ and Java Grammars
 
 @node Java Differences
 @subsection Differences between C/C++ and Java Grammars
 
@@ -8621,10 +8621,10 @@ section summarizes this differences.
 
 @itemize
 @item
 
 @itemize
 @item
-Since Java lacks a preprocessor, the @code{YYERROR}, @code{YYACCEPT},
+Java lacks a preprocessor, so the @code{YYERROR}, @code{YYACCEPT},
 @code{YYABORT} symbols (@pxref{Table of Symbols}) cannot obviously be
 @code{YYABORT} symbols (@pxref{Table of Symbols}) cannot obviously be
-macros.  Instead, they should be preceded in an action with
-@code{return}.  The actual definition of these symbols should be
+macros.  Instead, they should be preceded by @code{return} when they
+appear in an action.  The actual definition of these symbols is
 opaque to the Bison grammar, and it might change in the future.  The
 only meaningful operation that you can do, is to return them.
 
 opaque to the Bison grammar, and it might change in the future.  The
 only meaningful operation that you can do, is to return them.
 
@@ -8636,19 +8636,25 @@ corresponds to these C macros.}.
 
 @item
 The prolog declarations have a different meaning than in C/C++ code.
 
 @item
 The prolog declarations have a different meaning than in C/C++ code.
-@table @code
-@item %code
-@code{%code imports} blocks are placed at the beginning of the Java
-source code.  They may include copyright notices.  For a @code{package}
-declarations, it is suggested to use @code{%define package} instead.
+@table @asis
+@item @code{%code imports}
+blocks are placed at the beginning of the Java source code.  They may
+include copyright notices.  For a @code{package} declarations, it is
+suggested to use @code{%define package} instead.
 
 
-@code{%code} blocks are placed inside the parser class.  If @code{%define
-single_class} is being used, the definitions of @code{yylex} and
-@code{yyerror} should be placed here.  Subroutines for the parser actions
-may be included in this kind of block.
+@item unqualified @code{%code}
+blocks are placed inside the parser class.
+
+@item @code{%code lexer}
+blocks, if specified, should include the implementation of the
+scanner.  If there is no such block, the scanner can be any class
+that implements the appropriate interface (see @pxref{Java Scanner
+Interface}).
+@end item
 
 Other @code{%code} blocks are not supported in Java parsers.
 
 Other @code{%code} blocks are not supported in Java parsers.
-@end table
+The epilogue has the same meaning as in C/C++ code and it can
+be used to define other classes used by the parser.
 @end itemize
 
 @c ================================================= FAQ
 @end itemize
 
 @c ================================================= FAQ
index b331649208881b4bd4df3a6ffa662af676cdcc08..ca5d180f194e4f44945785e99c9844c9832b23bf 100644 (file)
@@ -25,7 +25,7 @@ AT_BANNER([[Java Calculator.]])
 # ------------------------- #
 
 
 # ------------------------- #
 
 
-# _AT_DATA_JAVA_CALC_Y($1, $2, $3, [BISON-DIRECTIVES], [BISON-EPILOGUE])
+# _AT_DATA_JAVA_CALC_Y($1, $2, $3, [BISON-DIRECTIVES])
 # ----------------------------------------------------------------------
 # Produce `calc.y'.  Don't call this macro directly, because it contains
 # some occurrences of `$1' etc. which will be interpreted by m4.  So
 # ----------------------------------------------------------------------
 # Produce `calc.y'.  Don't call this macro directly, because it contains
 # some occurrences of `$1' etc. which will be interpreted by m4.  So
@@ -37,11 +37,12 @@ m4_define([_AT_DATA_JAVA_CALC_Y],
 AT_DATA([Calc.y],
 [[/* Infix notation calculator--calc */
 %language "Java"
 AT_DATA([Calc.y],
 [[/* Infix notation calculator--calc */
 %language "Java"
-%name-prefix "Calc"]
+%name-prefix "Calc"
 %define parser_class_name "Calc"
 %define public
 
 %define parser_class_name "Calc"
 %define public
 
-$4[
+]$4[
+
 %code imports {
   import java.io.StreamTokenizer;
   import java.io.InputStream;
 %code imports {
   import java.io.StreamTokenizer;
   import java.io.InputStream;
@@ -93,52 +94,130 @@ exp:
 | '!'                { $$ = new Integer (0); return YYERROR;                }
 | '-' error          { $$ = new Integer (0); return YYERROR;                }
 ;
 | '!'                { $$ = new Integer (0); return YYERROR;                }
 | '-' error          { $$ = new Integer (0); return YYERROR;                }
 ;
+
+]AT_LEXPARAM_IF([[
+%code lexer {
+]],
+[[
 %%
 %%
+class CalcLexer implements Calc.Lexer {
+]])[
+  StreamTokenizer st;
+
+  public ]AT_LEXPARAM_IF([[YYLexer]], [[CalcLexer]]) (InputStream is)
+  {
+    st = new StreamTokenizer (new InputStreamReader (is));
+    st.resetSyntax ();
+    st.eolIsSignificant (true);
+    st.whitespaceChars (9, 9);
+    st.whitespaceChars (32, 32);
+    st.wordChars (48, 57);
+  }
+
+AT_LOCATION_IF([[
+  Position yystartpos;
+  Position yyendpos = new Position (1);
 
 
-  class Position {
-    public int line;
-
-    public Position ()
-    {
-      line = 0;
-    }
-
-    public Position (int l)
-    {
-      line = l;
-    }
-
-    public long getHashCode ()
-    {
-      return line;
-    }
-
-    public boolean equals (Position l)
-    {
-      return l.line == line;
-    }
-
-    public String toString ()
-    {
-      return Integer.toString (line);
-    }
-
-    public int lineno ()
-    {
-      return line;
-    }
+  public Position getStartPos() {
+    return yystartpos;
   }
 
   }
 
-]$5
-])
+  public Position getEndPos() {
+    return yyendpos;
+  }
+
+  public void yyerror (Calc.Location l, String s)
+  {
+    if (l == null)
+      System.err.println (s);
+    else
+      System.err.println (l.begin + ": " + s);
+  }
+]], [[
+  public void yyerror (String s)
+  {
+    System.err.println (s); 
+  }
+]])[
+
+  Integer yylval;
+
+  public Object getLVal() {
+    return yylval;
+  }
+
+  public int yylex () throws IOException {
+    int ttype = st.nextToken ();
+    ]AT_LOCATION_IF([[yystartpos = yyendpos;]])[
+    if (ttype == st.TT_EOF)
+      return Calc.EOF;
+
+    else if (ttype == st.TT_EOL)
+      {
+        ]AT_LOCATION_IF([[yyendpos = new Position (yyendpos.lineno () + 1);]])[
+        return (int) '\n';
+      }
+
+    else if (ttype == st.TT_WORD)
+      {
+        yylval = new Integer (st.sval);
+        return Calc.NUM;
+      }
+
+    else
+      return st.ttype;
+  }
+
+
+]AT_LEXPARAM_IF([[
+};
+%%]], [[
+}]])
+
+[
+class Position {
+  public int line;
+
+  public Position ()
+  {
+    line = 0;
+  }
+
+  public Position (int l)
+  {
+    line = l;
+  }
+
+  public long getHashCode ()
+  {
+    return line;
+  }
+
+  public boolean equals (Position l)
+  {
+    return l.line == line;
+  }
+
+  public String toString ()
+  {
+    return Integer.toString (line);
+  }
+
+  public int lineno ()
+  {
+    return line;
+  }
+}
+
+]])
 ])# _AT_DATA_JAVA_CALC_Y
 
 
 ])# _AT_DATA_JAVA_CALC_Y
 
 
-# AT_DATA_CALC_Y([BISON-OPTIONS], [BISON-EPILOGUE])
+# AT_DATA_CALC_Y([BISON-OPTIONS])
 # -------------------------------------------------
 # Produce `calc.y'.
 m4_define([AT_DATA_JAVA_CALC_Y],
 # -------------------------------------------------
 # Produce `calc.y'.
 m4_define([AT_DATA_JAVA_CALC_Y],
-[_AT_DATA_JAVA_CALC_Y($[1], $[2], $[3], [$1], [$2])
+[_AT_DATA_JAVA_CALC_Y($[1], $[2], $[3], [$1])
 ])
 
 
 ])
 
 
@@ -196,7 +275,7 @@ mv at-expout expout]])
 AT_CHECK([cat stderr], 0, [expout])
 ])
 
 AT_CHECK([cat stderr], 0, [expout])
 ])
 
-# _AT_CHECK_JAVA_CALC([BISON-DIRECTIVES], [BISON-CODE], [BISON-EPILOGUE])
+# _AT_CHECK_JAVA_CALC([BISON-DIRECTIVES], [BISON-CODE])
 # -----------------------------------------------------------------------
 # Start a testing chunk which compiles `calc' grammar with
 # BISON-DIRECTIVES, and performs several tests over the parser.
 # -----------------------------------------------------------------------
 # Start a testing chunk which compiles `calc' grammar with
 # BISON-DIRECTIVES, and performs several tests over the parser.
@@ -209,7 +288,7 @@ AT_BISON_OPTION_PUSHDEFS([$1])
 AT_DATA_JAVA_CALC_Y([$1
 %code {
 $2
 AT_DATA_JAVA_CALC_Y([$1
 %code {
 $2
-}], [$3])
+}])
 
 AT_CHECK([bison -o Calc.java Calc.y])
 AT_JAVA_COMPILE([Calc.java])
 
 AT_CHECK([bison -o Calc.java Calc.y])
 AT_JAVA_COMPILE([Calc.java])
@@ -288,14 +367,16 @@ AT_CLEANUP
 ])# _AT_CHECK_JAVA_CALC
 
 
 ])# _AT_CHECK_JAVA_CALC
 
 
-# AT_CHECK_JAVA_CALC([BISON-DIRECTIVES], [BISON-EPILOGUE])
+# AT_CHECK_JAVA_CALC([BISON-DIRECTIVES])
 # --------------------------------------------------------
 # Start a testing chunk which compiles `calc' grammar with
 # BISON-DIRECTIVES, and performs several tests over the parser.
 # Run the test with and without %error-verbose.
 m4_define([AT_CHECK_JAVA_CALC],
 # --------------------------------------------------------
 # Start a testing chunk which compiles `calc' grammar with
 # BISON-DIRECTIVES, and performs several tests over the parser.
 # Run the test with and without %error-verbose.
 m4_define([AT_CHECK_JAVA_CALC],
-[_AT_CHECK_JAVA_CALC([$1], [$2], [$3])
-_AT_CHECK_JAVA_CALC([%error-verbose $1], [$2], [$3])
+[_AT_CHECK_JAVA_CALC([$1], [$2])
+_AT_CHECK_JAVA_CALC([%error-verbose $1], [$2])
+_AT_CHECK_JAVA_CALC([%locations $1], [$2])
+_AT_CHECK_JAVA_CALC([%error-verbose %locations $1], [$2])
 ])# AT_CHECK_JAVA_CALC
 
 
 ])# AT_CHECK_JAVA_CALC
 
 
@@ -303,113 +384,18 @@ _AT_CHECK_JAVA_CALC([%error-verbose $1], [$2], [$3])
 # Simple LALR Calculator.  #
 # ------------------------ #
 
 # Simple LALR Calculator.  #
 # ------------------------ #
 
-dnl AT_CHECK_JAVA_CALC([], [])
-
-AT_CHECK_JAVA_CALC([%define single_class %locations], [[
-  StreamTokenizer st;
-
-  public Calc (InputStream is)
-  {
-    Reader r = new InputStreamReader (is);
-    st = new StreamTokenizer(r);
-    st.resetSyntax ();
-    st.eolIsSignificant (true);
-    st.whitespaceChars (9, 9);
-    st.whitespaceChars (32, 32);
-    st.wordChars (48, 57);
-
-    yyendpos = new Position (1);
-  }
-
-  public int yylex () throws IOException {
-    int ttype = st.nextToken ();
-    yystartpos = yyendpos;
-    if (ttype == st.TT_EOF)
-      return EOF;
-
-    else if (ttype == st.TT_EOL)
-      {
-        yyendpos = new Position (yyendpos.lineno () + 1);
-        return (int) '\n';
-      }
-
-    else if (ttype == st.TT_WORD)
-      {
-        yylval = new Integer (st.sval);
-        return NUM;
-      }
-
-    else
-      return st.ttype;
-  }
-
-  public void yyerror (Location l, String s)
-  {
-    if (l == null)
-      System.err.println (s);
-    else
-      System.err.println (l.begin + ": " + s);
-  }
-
-  public static void main (String args[]) throws IOException
-  {
-    new Calc (System.in).parse ();
-  }
-]])
-
-AT_CHECK_JAVA_CALC([%pure-parser], [[
+AT_CHECK_JAVA_CALC([], [[
   public static void main (String args[]) throws IOException
   {
     CalcLexer l = new CalcLexer (System.in);
     Calc p = new Calc (l);
     p.parse ();
   }
   public static void main (String args[]) throws IOException
   {
     CalcLexer l = new CalcLexer (System.in);
     Calc p = new Calc (l);
     p.parse ();
   }
-]], [[
-class CalcLexer implements Calc.Lexer {
-  Integer yylval;
-
-  StreamTokenizer st;
-  
-  public Object getLVal ()
-  {
-    return yylval;
-  }
-  
-  public CalcLexer (InputStream is)
-  {
-    Reader r = new InputStreamReader (is);
-    st = new StreamTokenizer(r);
-    st.resetSyntax ();
-    st.eolIsSignificant (true);
-    st.whitespaceChars (9, 9);
-    st.whitespaceChars (32, 32);
-    st.wordChars (48, 57);
-  }
-  
-  public int yylex () throws IOException {
-    int ttype = st.nextToken ();
-    if (ttype == st.TT_EOF)
-      return Calc.EOF;
-        
-    else if (ttype == st.TT_EOL)
-      return (int) '\n';
-        
-    else if (ttype == st.TT_WORD)
-      {
-        yylval = new Integer (st.sval);
-        return Calc.NUM;
-      }
-        
-    else
-      return st.ttype;
-  }
+]])
 
 
-  
-  public void yyerror (String s)
+AT_CHECK_JAVA_CALC([%lex-param { InputStream is } ], [[
+  public static void main (String args[]) throws IOException
   {
   {
-    System.err.println (s); 
+    new Calc (System.in).parse ();
   }
   }
-}
 ]])
 ]])
-
-dnl AT_CHECK_JAVA_CALC([%pure-parser %locations], [])
index 7c4858ad0ad8b3b3079ee6e56c4e0ac91e085db3..ab68cca95cab93087441542f0ee7a1c2b3e4a130 100644 (file)
@@ -52,6 +52,8 @@ m4_pushdef([AT_GLR_CC_IF],
 # Using yacc.c?
 m4_pushdef([AT_YACC_IF],
 [m4_bmatch([$3], [%language\|%glr-parser\|%skeleton], [$2], [$1])])
 # Using yacc.c?
 m4_pushdef([AT_YACC_IF],
 [m4_bmatch([$3], [%language\|%glr-parser\|%skeleton], [$2], [$1])])
+m4_pushdef([AT_LEXPARAM_IF],
+[m4_bmatch([$3], [%lex-param], [$1], [$2])])
 m4_pushdef([AT_PARAM_IF],
 [m4_bmatch([$3], [%parse-param], [$1], [$2])])
 m4_pushdef([AT_LOCATION_IF],
 m4_pushdef([AT_PARAM_IF],
 [m4_bmatch([$3], [%parse-param], [$1], [$2])])
 m4_pushdef([AT_LOCATION_IF],
@@ -128,6 +130,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_PURE_AND_LOC_IF])
 m4_popdef([AT_LOCATION_IF])
 m4_popdef([AT_PARAM_IF])
+m4_popdef([AT_LEXPARAM_IF])
 m4_popdef([AT_YACC_IF])
 m4_popdef([AT_GLR_IF])
 m4_popdef([AT_SKEL_CC_IF])
 m4_popdef([AT_YACC_IF])
 m4_popdef([AT_GLR_IF])
 m4_popdef([AT_SKEL_CC_IF])