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]