Hi bison team,

During my week-end, I wrote a back-end of
bison in C# (version 1.0 and 2.0).
I know it isn't the first priorities of
the bison team, but I read the Mono project
write it on their TODO list.

This back-end is based on lalr1.cc and I've
test this back-end with:
        - the infixe calc grammar (with
          and without generating an AST tree)
        - the tiger grammar (this bison parser
          replace my old jay parser on my tiger
          compiler in C#).

During my tests, I don't found any particular
problem and my first feed back is that
location is much more usable than in Jay.

I think, this back-end need more test and they
are lot of things which may be more cleaner
like how I convert macro (YYLOC_DEFAULT for
example) and how I have typed the stacks.

If someone want, I can write a full example to
use this back-end.


Bye.


PS: Sorry for my English.

-- 
J�r�my DEMEULE - EPITA SIGL Promotion 2005
Mail: demeul_j at epita.fr
Tel: +33 (0)6 07 96 46 39
URL: http://www.sigl.epita.net/
m4_divert(-1)

# C++ skeleton for Bison

# Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.



# This program is free software; you can redistribute it and/or modify

# it under the terms of the GNU General Public License as published by

# the Free Software Foundation; either version 2 of the License, or

# (at your option) any later version.



# This program is distributed in the hope that it will be useful,

# but WITHOUT ANY WARRANTY; without even the implied warranty of

# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

# GNU General Public License for more details.



# You should have received a copy of the GNU General Public License

# along with this program; if not, write to the Free Software

# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA

# 02111-1307  USA



## ---------------- ##

## Default values.  ##

## ---------------- ##



# Default parser class name.

m4_define_default([b4_parser_class_name], [parser])







## ----------------- ##

## Semantic Values.  ##

## ----------------- ##





# b4_lhs_value([TYPE])

# --------------------

# Expansion of $<TYPE>$.

m4_define([b4_lhs_value],

[(yyval[]m4_ifval([$1], [.$1]))])





# b4_rhs_value(RULE-LENGTH, NUM, [TYPE])

# --------------------------------------

# Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH

# symbols on RHS.

m4_define([b4_rhs_value],

[([EMAIL PROTECTED]([$1 - $2])@}m4_ifval([$3], [.$3]))])



m4_define_default([b4_location_type], [location])

m4_define_default([b4_filename_type], [string])



# b4_lhs_location()

# -----------------

# Expansion of @$.

m4_define([b4_lhs_location],

[(yyloc)])





# b4_rhs_location(RULE-LENGTH, NUM)

# ---------------------------------

# Expansion of @NUM, where the current rule has RULE-LENGTH symbols

# on RHS.

m4_define([b4_rhs_location],

[([EMAIL PROTECTED]([$1 - $2])@})])





# b4_parse_param_decl

# -------------------

# Extra formal arguments of the constructor.

# Change the parameter names from "foo" into "foo_yyarg", so that

# there is no collision bw the user chosen attribute name, and the

# argument name in the constructor.

m4_define([b4_parse_param_decl],

[m4_ifset([b4_parse_param],

          [m4_map_sep([b4_parse_param_decl_1], [, ], 
[b4_parse_param])])])



m4_define([b4_parse_param_decl_1],

[$1_yyarg])







# b4_parse_param_cons

# -------------------

# Extra initialisations of the constructor.

m4_define([b4_parse_param_cons],

          [m4_ifset([b4_parse_param],

                    [,

      b4_cc_constructor_calls(b4_parse_param)])])

m4_define([b4_cc_constructor_calls],

          [m4_map_sep([b4_cc_constructor_call], [,

      ], [EMAIL PROTECTED])])

m4_define([b4_cc_constructor_call],

          [$2 ($2_yyarg)])



# b4_parse_param_vars

# -------------------

# Extra instance variables.

m4_define([b4_parse_param_vars],

          [m4_ifset([b4_parse_param],

                    [

    /* User arguments.  */

b4_cc_var_decls(b4_parse_param)])])

m4_define([b4_cc_var_decls],

          [m4_map_sep([b4_cc_var_decl], [

], [EMAIL PROTECTED])])

m4_define([b4_cc_var_decl],

          [    $1;])





# b4_token_defines_cs(LIST-OF-PAIRS-TOKEN-NAME-TOKEN-NUMBER)

# -------------------------------------------------------

# Output the definition of the tokens (if there are) as enums and 
#define.

m4_define([b4_token_defines_cs],

[m4_if([EMAIL PROTECTED], [[]], [],

[/* Tokens.  */

   /* Put the tokens into the symbol table, so that GDB and other 
debuggers

      know about them.  */

   public enum yytokentype {

m4_map_sep([     b4_token_enum], [,

],

           [EMAIL PROTECTED])

   }

])

])



# b4_declare_debug

# ----------------

# Output a YYDEBUG

m4_define([b4_declare_debug],

          [m4_if(b4_debug, 1, [

/* Enabling traces.  */

#define YYDEBUG

], [])])



# b4_declare_verbose

# ----------------

# Output a YYDEBUG

m4_define([b4_declare_verbose],

          [m4_if(b4_error_verbose, 1, [

/* Enabling verbose error message.  */

#define YYERROR_VERBOSE

], [])])



# We do want M4 expansion after # for CPP macros.

m4_changecom()

m4_divert(0)dnl

m4_if(b4_defines_flag, 0, [],

[EMAIL PROTECTED] tokens.cs

b4_copyright([C# Skeleton parser for LALR(1) parsing with Bison],

             [2002, 2003, 2004, 2005])[

/* FIXME: This is wrong, we want computed header guards.

   I don't know why the macros are missing now. :( */



using System;

#if V2

using System.Collections.Generics;

#else

using System.Collections;

#endif



namespace yy {



// TODO: change m4 macro for token defines.

]b4_token_defines_cs(b4_tokens)[





  public interface yyInput {

    int token ();

    object yyval ();

    location yyloc ();

  }



}



]/* Line __line__ of lalr1.cs.  */

b4_syncline([EMAIL PROTECTED]@], [EMAIL PROTECTED]@])[

/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].

   If N is 0, then set CURRENT to the empty location which ends

   the previous symbol: RHS[0] (always defined).  */





namespace yy

{

#if !V2

#region V1 implementation

  public class state_stack : stack

  {

    public state_stack () : base ()

    {

    }



    public state_stack (int n) : base (n)

    {

    }



    public void push (int t)

    {

      seq_.Insert (0, t);

    }



    public int this[int n]

    {

      get { return (int) seq_[n]; }

    }

  }



  public class state_slice : slice

  {

    public state_slice (state_stack stack, int range)

      : base (stack, range)

    {

    }



    public int this [int i]

    {

      get { return (stack_ as state_stack) [range_ - i]; }

    }

  }



  public class location_stack : stack

  {

    public location_stack () : base ()

    {

    }



    public location_stack (int n) : base (n)

    {

    }



    public void push (location t)

    {

      seq_.Insert (0, t);

    }



    public location this[int n]

    {

      get { return (location) seq_[n]; }

    }

  }



  public class location_slice : slice

  {

    public location_slice (location_stack stack, int range)

      : base (stack, range)

    {

    }



    public location this [int i]

    {

      get { return (stack_ as location_stack) [range_ - i]; }

    }

  }



  public class semantique_stack : stack

  {

    public semantique_stack () : base ()

    {

    }



    public semantique_stack (int n) : base (n)

    {

    }



    public void push (object t)

    {

      seq_.Insert (0, t);

    }



    public object this[int n]

    {

      get { return seq_[n]; }

    }

  }



  public class semantique_slice : slice

  {

    public semantique_slice (semantique_stack stack, int range)

      : base (stack, range)

    {

    }



    public object this [int i]

    {

      get { return (stack_ as semantique_stack) [range_ - i]; }

    }

  }

#endregion

#endif

}



// end of parser]

])dnl

@output @output_parser_name@

b4_copyright([C# Skeleton parser for LALR(1) parsing with Bison],

             [2002, 2003, 2004, 2005])

m4_if(b4_prefix[], [yy], [],

[

// Take the name prefix into account.

#define yylex   b4_prefix[]lex])

m4_if(b4_defines_flag, 0, [],

[

/*#include @[EMAIL PROTECTED]/])[

]b4_declare_debug[

]b4_declare_verbose[



using System;

#if V2

using System.Collections.Generic;

#else

using System.Collections;

#endif



/* Copy the first part of user declarations.  */

]b4_pre_prologue[



]/* Line __line__ of lalr1.cs.  */

b4_syncline([EMAIL PROTECTED]@], [EMAIL PROTECTED]@])[



/* Copy the second part of user declarations.  */

]b4_post_prologue[



namespace yy

{

#if V2

  using state_stack = yy.stack<int>;

  using state_slice = yy.slice<int>;

  using location_stack = yy.stack<location>;

  using location_slice = yy.slice<location>;

  using semantique_stack = yy.stack<object>;

  using semantique_stack = yy.slice<object>;

#endif

  /// A Bison parser.

  public class ]b4_parser_class_name[

  {

    /// Symbol semantic values.

    //typedef traits<]b4_parser_class_name[>::semantic_type 
semantic_type;

    /// Symbol locations.

    //typedef traits<]b4_parser_class_name[>::location_type 
location_type;



    /// Build a parser object.

    public ]b4_parser_class_name[ (]b4_parse_param_decl[)

      ]b4_parse_param_cons[

    {

      yydebug_ = 0;

      yycdebug_ = Console.Error;

      yyloc = new location ();

      // place parameter cons here ?

    }



    /// Parse.

    /// \returns  0 if parsing succeeded.

    public virtual int parse ()

    {

      YYCDEBUG("Starting parse\r\n");



      yynerrs_ = 0;

      yyerrstatus_ = 0;



      /* Start.  */

      yystate_ = 0;

      yylooka_ = yyempty_;



    ]m4_ifdef([b4_initial_action], [

    m4_pushdef([b4_at_dollar],     [yylloc])dnl

    m4_pushdef([b4_dollar_dollar], [yylval])dnl

      /* User initialization code. */

      b4_initial_action

    m4_popdef([b4_dollar_dollar])dnl

    m4_popdef([b4_at_dollar])dnl

    /* Line __line__ of yacc.c.  */

    b4_syncline([EMAIL PROTECTED]@], [EMAIL PROTECTED]@])])dnl



    [  /* Initialize the stacks.  The initial state will be pushed in

        yynewstate, since the latter expects the semantical and the

        location values to have been already stored, initialize these

        stacks with a primary value.  */

      yystate_stack_ = new state_stack ();

      yysemantic_stack_ = new semantique_stack ();

      yylocation_stack_ = new location_stack ();

      yysemantic_stack_.push (yylval);

      yylocation_stack_.push (yylloc);



      /* New state.  */

    yynewstate:

      yystate_stack_.push (yystate_);

      YYCDEBUG("Entering state " + yystate_.ToString() + "\r\n");

      goto yybackup;



      /* Backup.  */

    yybackup:



      /* Try to take a decision without look-ahead.  */

      yyn_ = yypact_[yystate_];

      if (yyn_ == yypact_ninf_)

        goto yydefault;



      /* Read a look-ahead token.  */

      if (yylooka_ == yyempty_)

        yylex_ ();



      /* Convert token to internal form.  */

      if (yylooka_ <= yyeof_)

        {

          yylooka_ = yyilooka_ = yyeof_;

          YYCDEBUG("Now at end of input\r\n");

        }

      else

        {

          yyilooka_ = yytranslate_ (yylooka_);

          YY_SYMBOL_PRINT ("Next token is", yyilooka_, yylval, yylloc);

        }



      /* If the proper action on seeing token ILOOKA_ is to reduce or to

        detect an error, take that action.  */

      yyn_ += yyilooka_;

      if (yyn_ < 0 || yylast_ < yyn_ || yycheck_[yyn_] != yyilooka_)

        goto yydefault;



      /* Reduce or error.  */

      yyn_ = yytable_[yyn_];

      if (yyn_ < 0)

        {

          if (yyn_ == yytable_ninf_)

            goto yyerrlab;

          else

            {

              yyn_ = -yyn_;

              goto yyreduce;

            }

        }

      else if (yyn_ == 0)

        goto yyerrlab;



      /* Accept?  */

      if (yyn_ == yyfinal_)

        goto yyacceptlab;



      /* Shift the look-ahead token.  */

      YY_SYMBOL_PRINT ("Shifting", yyilooka_, yylval, yylloc);



      /* Discard the token being shifted unless it is eof.  */

      if (yylooka_ != yyeof_)

        yylooka_ = yyempty_;



      yysemantic_stack_.push (yylval);

      yylocation_stack_.push (yylloc);



      /* Count tokens shifted since error; after three, turn off error

        status.  */

      if (yyerrstatus_ != 0)

        --yyerrstatus_;



      yystate_ = yyn_;

      goto yynewstate;



    /*-----------------------------------------------------------.

    | yydefault -- do the default action for the current state.  |

    `-----------------------------------------------------------*/

    yydefault:

      yyn_ = yydefact_[yystate_];

      if (yyn_ == 0)

        goto yyerrlab;

      goto yyreduce;



    /*-----------------------------.

    | yyreduce -- Do a reduction.  |

    `-----------------------------*/

    yyreduce:

      yylen_ = yyr2_[yyn_];

      /* If LEN_ is nonzero, implement the default value of the action:

        `$$ = $1'.  Otherwise, use the top of the stack.



        Otherwise, the following line sets YYVAL to garbage.

        This behavior is undocumented and Bison

        users should not rely upon it.  */

      if (yylen_ != 0)

        yyval = yysemantic_stack_[yylen_ - 1];

      else

        yyval = yysemantic_stack_[0];



      {

        location_slice pslice = new location_slice (yylocation_stack_, 
yylen_);

        YYLLOC_DEFAULT (pslice, yylen_);

      }

      YY_REDUCE_PRINT (yyn_);

      switch (yyn_)

        {

          ]b4_actions[

          default: break;

        }



    ]/* Line __line__ of lalr1.cs.  */

    b4_syncline([EMAIL PROTECTED]@], [EMAIL PROTECTED]@])[



      yypop_ (yylen_);



      YY_STACK_PRINT ();



      yysemantic_stack_.push (yyval);

      yylocation_stack_.push (yyloc);



      /* Shift the result of the reduction.  */

      yyn_ = yyr1_[yyn_];

      yystate_ = yypgoto_[yyn_ - yyntokens_] + yystate_stack_[0];

      if (0 <= yystate_ && yystate_ <= yylast_

          && yycheck_[yystate_] == yystate_stack_[0])

        yystate_ = yytable_[yystate_];

      else

        yystate_ = yydefgoto_[yyn_ - yyntokens_];

      goto yynewstate;



    /*------------------------------------.

    | yyerrlab -- here on detecting error |

    `------------------------------------*/

    yyerrlab:

      /* If not already recovering from an error, report this error.  */

      yyreport_syntax_error_ ();



      yyerror_range_[0] = yylloc;

      if (yyerrstatus_ == 3)

        {

          /* If just tried and failed to reuse look-ahead token after an

            error, discard it.  */



          /* Return failure if at end of input.  */

          if (yylooka_ <= yyeof_)

            {

              /* If at end of input, pop the error token,

                then the rest of the stack, then return failure.  */

              if (yylooka_ == yyeof_)

                for (;;)

                  {

                    yyerror_range_[0] = yylocation_stack_[0];

                    yypop_ ();

                    if (yystate_stack_.height () == 1)

                      goto yyabortlab;

                    yydestruct_ ("Error: popping",

                                  yystos_[yystate_stack_[0]],

                                  yysemantic_stack_[0],

                                  yylocation_stack_[0]);

                  }

            }

          else

            {

              yydestruct_ ("Error: discarding", yyilooka_, yylval, yylloc);

              yylooka_ = yyempty_;

            }

        }



      /* Else will try to reuse look-ahead token after shifting the error

        token.  */

      goto yyerrlab1;





    /*---------------------------------------------------.

    | yyerrorlab -- error raised explicitly by YYERROR.  |

    `---------------------------------------------------*/

    yyerrorlab:



    #if __GNUC__

      /* Pacify GCC when the user code never invokes YYERROR and the 
label

        yyerrorlab therefore never appears in user code.  */

      if (0)

        goto yyerrorlab;

    #endif



      yyerror_range_[0] = yylocation_stack_[yylen_ - 1];

      yypop_ (yylen_);

      yystate_ = yystate_stack_[0];

      goto yyerrlab1;



    /*-------------------------------------------------------------.

    | yyerrlab1 -- common code for both syntax error and YYERROR.  |

    `-------------------------------------------------------------*/

    yyerrlab1:

      yyerrstatus_ = 3; /* Each real token shifted decrements this.  */



      for (;;)

        {

          yyn_ = yypact_[yystate_];

          if (yyn_ != yypact_ninf_)

            {

              yyn_ += yyterror_;

              if (0 <= yyn_ && yyn_ <= yylast_ && yycheck_[yyn_] == 
yyterror_)

                {

                  yyn_ = yytable_[yyn_];

                  if (0 < yyn_)

                    break;

                }

            }



          /* Pop the current state because it cannot handle the error token.  */

          if (yystate_stack_.height () == 1)

            goto yyabortlab;



          yyerror_range_[0] = yylocation_stack_[0];

          yydestruct_ ("Error: popping",

                      yystos_[yystate_],

                      yysemantic_stack_[0], yylocation_stack_[0]);

          yypop_ ();

          yystate_ = yystate_stack_[0];

          YY_STACK_PRINT ();

        }



      if (yyn_ == yyfinal_)

        goto yyacceptlab;



      yyerror_range_[1] = yylloc;

      // Using YYLLOC is tempting, but would change the location of

      // the look-ahead.  YYLOC is available though.

      YYLLOC_DEFAULT (yyerror_range_, 2);

      yysemantic_stack_.push (yylval);

      yylocation_stack_.push (yyloc);



      /* Shift the error token. */

      YY_SYMBOL_PRINT ("Shifting", yystos_[yyn_],

                   yysemantic_stack_[0], yylocation_stack_[0]);



      yystate_ = yyn_;

      goto yynewstate;



      /* Accept.  */

    yyacceptlab:

      return 0;



      /* Abort.  */

    yyabortlab:

      /* Free the lookahead. */

      yydestruct_ ("Error: discarding lookahead", yyilooka_, yylval, 
yylloc);

      yylooka_ = yyempty_;

      return 1;

    }



    /// The current debugging stream.

    public System.IO.TextWriter debug_stream ()

    {

      return yycdebug_;

    }

    /// Set the current debugging stream.

    public void set_debug_stream (System.IO.TextWriter o)

    {

      yycdebug_ = o;

    }



    /// Type for debugging levels.

    //typedef int debug_level_type;

    /// The current debugging level.

    public int debug_level ()

    {

      return yydebug_;

    }

    /// Set the current debugging level.

    public void set_debug_level (int l)

    {

      yydebug_ = l;

    }





    /// Call the scanner.

    protected virtual void yylex_ ()

    {

      // TODO: call the scanner differently

      //       It must be an object like in Jay

      YYCDEBUG("Reading a token: ");

      yylooka_ = yyLex_.token ();

      yylval = yyLex_.yyval ();

      yylloc = new location (yyLex_.yyloc ());

    }







    /// Report a syntax error.

    /// \param loc    where the syntax error is found.

    /// \param msg    a description of the syntax error.

    protected virtual void error (location loc, string msg)

    {

      if (error_fct_ != null)

        error_fct_ (loc, msg);

    }



    /// Generate an error message, and invoke error.

    protected virtual void yyreport_syntax_error_ ()

    {

      /* If not already recovering from an error, report this error.  */

      if (yyerrstatus_ == 0)

        {

          ++yynerrs_;

          string message;

    #if YYERROR_VERBOSE

          yyn_ = yypact_[yystate_];

          if (yypact_ninf_ < yyn_ && yyn_ < yylast_)

            {

              /* Start YYX at -YYN if negative to avoid negative indexes in

                YYCHECK.  */

              int yyxbegin = yyn_ < 0 ? -yyn_ : 0;



              /* Stay within bounds of both yycheck and yytname.  */

              int yychecklim = yylast_ - yyn_;

              int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_;

              int count = 0;

              for (int x = yyxbegin; x < yyxend; ++x)

                if (yycheck_[x + yyn_] == x && x != yyterror_)

                  ++count;



              message = "syntax error, unexpected ";

              message += yyname_[yyilooka_];

              if (count < 5)

                {

                  count = 0;

                  for (int x = yyxbegin; x < yyxend; ++x)

                    if (yycheck_[x + yyn_] == x && x != yyterror_)

                      {

                        message += (count++ == 0) ? ", expecting " : " or ";

                        message += yyname_[x];

                      }

                }

            }

          else

    #endif

            message = "syntax error";

          error (yylloc, message);

        }

    }



#if YYDEBUG

    /// \brief Report a symbol on the debug stream.

    /// \param yytype       The token type.

    /// \param yyvaluep     Its semantic value.

    /// \param yylocationp  Its location.

    protected virtual void yysymprint_ (int yytype,

                              object yyvaluep,

                              location yylocationp)

    {

      /* Pacify ``unused variable'' warnings.  */

      //(void) yyvaluep;

      //(void) yylocationp;

      /* Backward compatibility, but should be removed eventually. */

      //std::ostream& cdebug_ = *yycdebug_;

      //(void) cdebug_;



      yycdebug_.Write((yytype < yyntokens_ ? "token" : "nterm"));

      yycdebug_.Write(" " + yyname_[yytype] + " (");

      yycdebug_.Write(yylocationp.ToString() + ": ");

      switch (yytype)

        {

    ]m4_map([b4_symbol_actions], m4_defn([b4_symbol_printers]))dnl

    [      default:

            break;

        }

      yycdebug_.Write(")");

    }

#endif





    /// State numbers.

    //typedef traits<]b4_parser_class_name[>::state_type state_type;

    /// State stack type.

    //typedef stack<state_type>    state_stack_type;

    /// Semantic value stack type.

    //typedef stack<semantic_type> semantic_stack_type;

    /// location stack type.

    //typedef stack<location_type> location_stack_type;



    /// The state stack.

    private state_stack yystate_stack_;

    /// The semantic value stack.

    private semantique_stack yysemantic_stack_;

    /// The location stack.

    private location_stack yylocation_stack_;



    /// Internal symbol numbers.

    //typedef traits<]b4_parser_class_name[>::token_number_type 
token_number_type;

    /* Tables.  */

    /// For a state, the index in \a yytable_ of its portion.

    //static const ]b4_int_type_for([b4_pact])[ yypact_[];

    private static int[] yypact_ =

    {

      ]b4_pact[

    };

    //static const ]b4_int_type(b4_pact_ninf, b4_pact_ninf)[ 
yypact_ninf_;

    private static int yypact_ninf_ = ]b4_pact_ninf[;



    /// For a state, default rule to reduce.

    /// Unless\a  yytable_ specifies something else to do.

    /// Zero means the default is an error.

    //static const ]b4_int_type_for([b4_defact])[ yydefact_[];

    private static int[] yydefact_ =

    {

      ]b4_defact[

    };



    //static const ]b4_int_type_for([b4_pgoto])[ yypgoto_[];

    private static int[] yypgoto_ =

    {

      ]b4_pgoto[

    };

    //static const ]b4_int_type_for([b4_defgoto])[ yydefgoto_[];

    private static int[] yydefgoto_ =

    {

      ]b4_defgoto[

    };



    /// What to do in a state.

    /// \a yytable_[yypact_[s]]: what to do in state \a s.

    /// - if positive, shift that token.

    /// - if negative, reduce the rule which number is the opposite.

    /// - if zero, do what YYDEFACT says.

    //static const ]b4_int_type_for([b4_table])[ yytable_[];

    private static int[] yytable_ =

    {

      ]b4_table[

    };

    //static const ]b4_int_type(b4_table_ninf, b4_table_ninf)[ 
yytable_ninf_;

    private static int yytable_ninf_ = ]b4_table_ninf[;



    //static const ]b4_int_type_for([b4_check])[ yycheck_[];

    private static int[] yycheck_ =

    {

      ]b4_check[

    };



    /// For a state, its accessing symbol.

    //static const ]b4_int_type_for([b4_stos])[ yystos_[];

    private static int[] yystos_ =

    {

      ]b4_stos[

    };



    /// For a rule, its LHS.

    //static const ]b4_int_type_for([b4_r1])[ yyr1_[];

    private static int[] yyr1_ =

    {

      ]b4_r1[

    };

    /// For a rule, its RHS length.

    //static const ]b4_int_type_for([b4_r2])[ yyr2_[];

    private static int[] yyr2_ =

    {

      ]b4_r2[

    };



#if YYDEBUG || YYERROR_VERBOSE

]m4_define([b4_0s_to_nulls],[m4_map_sep([b4_0_to_null],[, ],$@)])

m4_define([b4_0_to_null],[m4_if([$1],[0],[null],[$1])])[

    /// For a symbol, its name in clear.

    //static const char* const yyname_[];

    private static string[] yyname_ =

    {

      ]b4_0s_to_nulls(b4_tname)[

    };

#endif



#if YYDEBUG

    /// A type to store symbol numbers and -1.

    //typedef traits<]b4_parser_class_name[>::rhs_number_type 
rhs_number_type;

    /// A `-1'-separated list of the rules' RHS.

    //static const rhs_number_type yyrhs_[];

    private static int[] yyrhs_ =

    {

      ]b4_rhs[

    };

    /// For each rule, the index of the first RHS symbol in \a yyrhs_.

    //static const ]b4_int_type_for([b4_prhs])[ yyprhs_[];

    private static int[] yyprhs_ =

    {

      ]b4_prhs[

    };

    /// For each rule, its source line number.

    //static const ]b4_int_type_for([b4_rline])[ yyrline_[];

    private static int[] yyrline_ =

    {

      ]b4_rline[

    };

    /// For each scanner token number, its symbol number.

    //static const ]b4_int_type_for([b4_toknum])[ yytoken_number_[];

    private static int[] yytoken_number_ =

    {

      ]b4_toknum[

    };

    /// Report on the debug stream that the rule \a r is going to be 
reduced.

    protected virtual void yyreduce_print_ (int yyrule)

    {

      int yylno = yyrline_[yyrule];

      /* Print the symbols being reduced, and their result.  */

      yycdebug_.Write("Reducing stack by rule ");

      yycdebug_.Write(yyn_ - 1);

      yycdebug_.Write(" (line " + yylno + "), ");

      for (int i = yyprhs_[yyn_];

          0 <= yyrhs_[i]; ++i)

        yycdebug_.Write(yyname_[yyrhs_[i]] + " ");

      yycdebug_.WriteLine("-> " + yyname_[yyr1_[yyn_]]);

    }

    /// Print the state stack on the debug stream.

    protected virtual void yystack_print_ ()

    {

      yycdebug_.Write("Stack now");

    //  for (state_stack_type::const_iterator i = yystate_stack_.begin 
();

    //       i != yystate_stack_.end (); ++i)

#if V2

      for (state_stack.Enumerator<int> i = 
yystate_stack_.GetEnumerator(); i.MoveNext(); )

        yycdebug_.Write(" " + i.Value);

#else

      for (IEnumerator i = yystate_stack_.GetEnumerator (); i.MoveNext 
(); )

        yycdebug_.Write(" " + i.Current.ToString ());

#endif

      yycdebug_.WriteLine();

    }

    

#endif



    /// Convert a scanner token number to a symbol number.

    //inline token_number_type yytranslate_ (int token);

    private int yytranslate_ (int token)

    {

      int[]

      translate_table =

      {

        ]b4_translate[

      };

      if ((int) token <= yyuser_token_number_max_)

        return translate_table[token];

      else

        return yyundef_token_;

    }



    /// \brief Reclaim the memory associated to a symbol.

    /// \param yymsg        Why this token is reclaimed.

    /// \param yytype       The symbol type.

    /// \param yyvaluep     Its semantic value.

    /// \param yylocationp  Its location.

//    inline void yydestruct_ (const char* yymsg,

//                             int yytype,

//                             semantic_type* yyvaluep,

//                             location_type* yylocationp);

    private void yydestruct_ (string yymsg,

                              int yytype,

                              object yyvaluep,

                              location yylocationp)

    {

      /* Pacify ``unused variable'' warnings.  */

      //(void) yymsg;

      //(void) yyvaluep;

      //(void) yylocationp;



      YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);



      switch (yytype)

        {

    ]m4_map([b4_symbol_actions], m4_defn([b4_symbol_destructors]))[

          default:

            break;

        }

    }



    /// Pop \a n symbols the three stacks.

    private void yypop_ ()

    {

      yypop_ (1);

    }



    private void yypop_ (int n)

    {

      yystate_stack_.pop (n);

      yysemantic_stack_.pop (n);

      yylocation_stack_.pop (n);

    }



    /* Constants.  */

    //static const int yyeof_;

    private static int yyeof_  = 0;

    /* LAST_ -- Last index in TABLE_.  */

    private static int yylast_ = ]b4_last[;

    private static int yynnts_ = ]b4_nterms_number[;

    private static int yyempty_ = -2;

    private static int yyfinal_ = ]b4_final_state_number[;

    private static int yyterror_ = 1;

    private static int yyerrcode_ = 256;

    private static int yyntokens_ = ]b4_tokens_number[;

    private static int yyuser_token_number_max_ = 
]b4_user_token_number_max[;

    private static int yyundef_token_ = ]b4_undef_token_number[;



    /* State.  */

    private int yyn_;

    private int yylen_;

    private int yystate_;



    /* Error handling. */

    private int yynerrs_;

    private int yyerrstatus_;



    /* Debugging.  */

    private int yydebug_;

    //std::ostream* yycdebug_;

    System.IO.TextWriter yycdebug_;



    /* Look-ahead and look-ahead in internal form.  */

    private int yylooka_;

    private int yyilooka_;



    /// Semantic value of the look-ahead.

    //private YYSTYPE yylval;

    private object yylval;

    /// Location of the look-ahead.

    private location yylloc;

    /// The locations where the error started and ended.

    private location[] yyerror_range_ = new location[2];



    /// $$.

    //private YYSTYPE yyval;

    private object yyval;

    /// @@$.

    private location yyloc;



    /// Handle error function.

    private PrintErrorDelegate error_fct_;



    /// C++ to C# macro expansion

    private void YY_SYMBOL_PRINT(string Title, int Type, object Value, 
location Location)

    {

      if (yydebug_ != 0)

        {

          yycdebug_.Write(Title + " ");

          yysymprint_(Type, Value, Location);

          yycdebug_.WriteLine();

        }

    }



    private void YY_REDUCE_PRINT(int Rule)

    {

      if (yydebug_ != 0)

        yyreduce_print_ (Rule);

    }



    private void YY_STACK_PRINT()

    {

      if (yydebug_ != 0)

        yystack_print_ ();

    }



    private void YYCDEBUG(string msg)

    {

      if (yydebug_ != 0)

        yycdebug_.Write(msg);

    }



    private void YYLLOC_DEFAULT(location[] Rhs, int N)

    {

      yyloc = new location(yyloc);

      if (N != 0)

        {

          yyloc.begin = Rhs[0].begin;

          yyloc.end = Rhs[N - 1].end;

        }

      else

        {

          yyloc.begin = yyloc.end = Rhs[0].end;

        }

    }



    private void YYLLOC_DEFAULT(location_slice Rhs, int N)

    {

      yyloc = new location(yyloc);

      if (N != 0)

        {

          yyloc.begin = Rhs[1].begin;

          yyloc.end     = Rhs[N].begin;

        }

      else

        {

          yyloc.begin = yyloc.end = Rhs[0].end;

        }

    }



    public yyInput YYLexer

    {

      get

      {

        return yyLex_;

      }

      set

      {

        yyLex_ = value;

      }

    }



    private yyInput yyLex_;



    public object YYVal

    {

      get

      {

        return yyval;

      }

    }



    public PrintErrorDelegate error_fct

    {

      set

      {

        error_fct_ = value;

      }

    }



]b4_parse_param_vars[

  }



  public delegate void PrintErrorDelegate(location loc, string msg);



}



]b4_epilogue

dnl

@output stack.cs

b4_copyright([stack handling for Bison C# parsers], [2002, 2003, 2004, 
2005])[



using System;

#if V2

using System.Collections.Generics;

#else

using System.Collections;

#endif



namespace yy

{

#if V2

  public class stack<T>

  {



    public stack ()

      : this (0)

    {

    }



    public stack (uint n)

    {

      seq_ = new List<T> (n);

    }



    public T this [uint i]

    {

      get {

        return seq_[(int)i];

      }

    }



    public void push (T t)

    {

      seq_.Insert (0, t);

    }



    public void pop (uint n)

    {

      for (; n != 0; --n)

        seq_.RemoveAt (0);

    }



    public void pop ()

    {

      pop (1);

    }



    public uint height ()

    {

      return (uint)seq_.Count;

    }



    public IEnumerator<T> GetEnumerator ()

    {

      for (int i = seq_.Count; i != 0; --i)

        {

          yield return seq_[i - 1];

        }

    }



    private List<T> seq_;

  }



  /// Present a slice of the top of a stack.

  public class slice<T>

  {



    public slice (stack<T> stack,

           uint range)

    {

      stack_ = stack;

      range_ = range;

    }



    public T this [uint i]

    {

      get {

        return stack_[range_ - i];

      }

    }



    private stack<T> stack_;

    private uint range_;

  }

#else

  public class stack

  {

    protected stack ()

      : this (0)

    {

    }



    protected stack (int n)

    {

      seq_ = new ArrayList (n);

    }



    public void pop (int n)

    {

      for (; n != 0; --n)

        seq_.RemoveAt (0);

    }



    public void pop ()

    {

      pop (1);

    }



    public int height ()

    {

      return (int)seq_.Count;

    }



    public IEnumerator GetEnumerator ()

    {

      return seq_.GetEnumerator ();

    }



    protected ArrayList seq_; 

  }



  public class slice

  {

    public slice (stack stack,

           int range)

    {

      stack_ = stack;

      range_ = range;

    }



    protected stack stack_;

    protected int range_;

  }

#endif



}



// end of file stack.cs]

dnl

@output position.cs

b4_copyright([Position class for Bison C# parsers], [2002, 2003, 2004, 
2005])[



/**

 ** \file position.cs

 ** Define the position class.

 */



using System;





namespace yy

{

  /// Abstract a position.

  public class position

  {

    /// Initial column number.

    public const int initial_column = 0;

    /// Initial line number.

    public const int initial_line = 1;



    /** \name Ctor & dtor.

     ** \{ */

    /// Construct a position.

    public position ()

    {

      filename = null;

      line = initial_line;

      column = initial_column;

    }



    /// Clone a position.

    public position (position copy)

    {

      filename = copy.filename;

      line = copy.line;

      column = copy.column;

    }

    /** \} */





    /** \name Line and Column related manipulators

     ** \{ */

    /// (line related) Advance to the COUNT next lines.

    public void lines (int count)

    {

      column = initial_column;

      line += count;

    }



    public void lines ()

    {

      lines (1);

    }



    /// (column related) Advance to the COUNT next columns.

    public void columns (int count)

    {

      int leftmost = initial_column;

      int current  = column;

      if (leftmost <= current + count)

        column += count;

      else

        column = initial_column;

    }



    public void columns ()

    {

      columns (1);

    }

    /** \} */





    /// Add two position objects.

    public static position operator + (position begin, int width)

    {

      position res = begin;

      res.columns(width);

      return res;

    }



    /// Increment a position.

    public static position operator ++ (position pos)

    {

      ++pos.column;

      return pos;

    }



    /// Sub two position objects.

    public static position operator - (position begin, int width)

    {

      return begin + -width; 

    }



    /// \brief Convert this position on a string.

    public override string ToString()

    {

      string res = "";

      if (this.filename != null)

        res = this.filename + ":";

      res += this.line + "." + this.column;

      return res;

    }



    /// File name to which this position refers.

    public ]b4_filename_type[ filename;

    /// Current line number.

    public int line;

    /// Current column number.

    public int column;

  };



}

// end file position.cs]

@output location.cs

b4_copyright([Location class for Bison C# parsers], [2002, 2003, 2004, 
2005])[



/**

 ** \file location.cs

 ** Define the location class.

 */



using System;





namespace yy

{



  /// Abstract a location.

  public class location

  {

    /** \name Ctor & dtor.

     ** \{ */

    /// Construct a location.

    public location ()

    {

      begin = new position ();

      end = new position ();

    }



    /// Clone a location.

    public location (location copy)

    {

      begin = new position (copy.begin);

      end = new position (copy.end);

    }

    /** \} */





    /** \name Line and Column related manipulators

     ** \{ */

    /// Reset initial location to final location.

    public void step ()

    {

      begin = end;

    }



    /// Extend the current location to the COUNT next columns.

    public void columns (int count)

    {

      end += count;

    }



    public void columns ()

    {

      ++end;

    }



    /// Extend the current location to the COUNT next lines.

    public void lines (int count)

    {

      end.lines (count);

    }



    public void lines ()

    {

      end.lines (1);

    }

    /** \} */



    /// Join two location objects to create a location.

    public static location operator + (location begin, location end)

    {

      location res = begin;

      res.end = end.end;

      return res;

    }



    /// Add two location objects.

    public static location operator + (location begin, int width)

    {

      location res = begin;

      res.columns (width);

      return res;

    }



    /** \brief Convert this location on a string.

     **

     ** Avoid duplicate information.

     */

    public override string ToString()

    {

      string res = "";

      position last = this.end - 1;

      res = this.begin.ToString();

      if ((last.filename != null) &&

          ((this.begin.filename == null) || (this.begin.filename != 
last.filename)))

        res += "-" + last.ToString();

      else if (this.begin.line != last.line)

        res += "-" + last.line.ToString() + "." + last.column.ToString();

      else if (this.begin.column != last.column)

        res += "-" + last.column;

      return res;

    }





    /// Beginning of the located region.

    public position begin;

    /// End of the located region.

    public position end;

  };



}



// end file location.cs]

Reply via email to