/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /// <summary>Fill in the parse table entries for this state. There are two /// parse tables that encode the viable prefix recognition machine, an /// action table and a reduce-goto table. The rows in each table /// correspond to states of the machine. The columns of the action table /// are indexed by terminal symbols and correspond to either transitions /// out of the state (shift entries) or reductions from the state to some /// previous state saved on the stack (reduce entries). All entries in the /// action table that are not shifts or reduces, represent errors. The /// reduce-goto table is indexed by non terminals and represents transitions /// out of a state on that non-terminal.<p> /// Conflicts occur if more than one action needs to go in one entry of the /// action table (this cannot happen with the reduce-goto table). Conflicts /// are resolved by always shifting for shift/reduce conflicts and choosing /// the lowest numbered production (hence the one that appeared first in /// the specification) in reduce/reduce conflicts. All conflicts are /// reported and if more conflicts are detected than were declared by the /// user, code generation is aborted. /// * /// </summary> /// <param name="act_table"> the action table to put entries in. /// </param> /// <param name="reduce_table">the reduce-goto table to put entries in. /// /// </param> public virtual void build_table_entries(parse_action_table act_table, parse_reduce_table reduce_table) { parse_action_row our_act_row; parse_reduce_row our_red_row; lalr_item itm; parse_action act, other_act; symbol sym; terminal_set conflict_set = new terminal_set(); /* pull out our rows from the tables */ our_act_row = act_table.under_state[index()]; our_red_row = reduce_table.under_state[index()]; /* consider each item in our state */ //UPGRADE_TODO: method 'java.util.Enumeration.hasMoreElements' was converted to ' ' which has a different behavior. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1073_javautilEnumerationhasMoreElements"' for (System.Collections.IEnumerator i = items().all(); i.MoveNext(); ) { //UPGRADE_TODO: method 'java.util.Enumeration.nextElement' was converted to ' ' which has a different behavior. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1073_javautilEnumerationnextElement"' itm = (lalr_item) i.Current; /* if its completed (dot at end) then reduce under the lookahead */ if (itm.dot_at_end()) { act = new reduce_action(itm.the_production()); /* consider each lookahead symbol */ for (int t = 0; t < terminal.number(); t++) { /* skip over the ones not in the lookahead */ if (!itm.lookahead().contains(t)) continue; /* if we don't already have an action put this one in */ if (our_act_row.under_term[t].kind() == parse_action.ERROR) { our_act_row.under_term[t] = act; } else { /* we now have at least one conflict */ terminal term = terminal.find(t); other_act = our_act_row.under_term[t]; /* if the other act was not a shift */ if ((other_act.kind() != parse_action.SHIFT) && (other_act.kind() != parse_action.NONASSOC)) { /* if we have lower index hence priority, replace it*/ if (itm.the_production().index() < ((reduce_action) other_act).reduce_with().index()) { /* replace the action */ our_act_row.under_term[t] = act; } } else { /* Check precedences,see if problem is correctable */ if (fix_with_precedence(itm.the_production(), t, our_act_row, act)) { term = null; } } if (term != null) { conflict_set.add(term); } } } } } /* consider each outgoing transition */ for (lalr_transition trans = transitions(); trans != null; trans = trans.next()) { /* if its on an terminal add a shift entry */ sym = trans.on_symbol(); if (!sym.is_non_term()) { act = new shift_action(trans.to_state()); /* if we don't already have an action put this one in */ if (our_act_row.under_term[sym.index()].kind() == parse_action.ERROR) { our_act_row.under_term[sym.index()] = act; } else { /* we now have at least one conflict */ production p = ((reduce_action) our_act_row.under_term[sym.index()]).reduce_with(); /* shift always wins */ if (!fix_with_precedence(p, sym.index(), our_act_row, act)) { our_act_row.under_term[sym.index()] = act; conflict_set.add(terminal.find(sym.index())); } } } else { /* for non terminals add an entry to the reduce-goto table */ our_red_row.under_non_term[sym.index()] = trans.to_state(); } } /* if we end up with conflict(s), report them */ if (!conflict_set.empty()) report_conflicts(conflict_set); }
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /// <summary>Emit the parser subclass with embedded tables. /// </summary> /// <param name="out"> stream to produce output on. /// </param> /// <param name="action_table"> internal representation of the action table. /// </param> /// <param name="reduce_table"> internal representation of the reduce-goto table. /// </param> /// <param name="start_st"> start state of the parse machine. /// </param> /// <param name="start_prod"> start production of the grammar. /// </param> /// <param name="compact_reduces">do we use most frequent reduce as default? /// </param> /// <param name="suppress_scanner">should scanner be suppressed for compatibility? /// /// </param> public static void parser(System.IO.StreamWriter out_Renamed, parse_action_table action_table, parse_reduce_table reduce_table, int start_st, production start_prod, bool compact_reduces, bool suppress_scanner) { long start_time = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; /* top of file */ out_Renamed.WriteLine(); out_Renamed.WriteLine("//----------------------------------------------------"); out_Renamed.WriteLine("// The following code was generated by " + version.title_str); out_Renamed.WriteLine("// " + System.DateTime.Now); out_Renamed.WriteLine("//----------------------------------------------------"); out_Renamed.WriteLine(); out_Renamed.WriteLine("using System;"); emit_package(out_Renamed); /* user supplied imports */ for (int i = 0; i < import_list.Count; i++) { out_Renamed.WriteLine("using " + import_list.Peek(import_list.Count - (i + 1)) + ";"); } /* class header */ out_Renamed.WriteLine(); out_Renamed.WriteLine("///<summary>" + version.title_str + " generated parser." + "</summary>"); out_Renamed.WriteLine("///<version>" + System.DateTime.Now + "</version>"); out_Renamed.WriteLine("///"); out_Renamed.WriteLine("public class " + parser_class_name + " : CUP.runtime.lr_parser {"); /* constructors [CSA/davidm, 24-jul-99] */ out_Renamed.WriteLine(); out_Renamed.WriteLine(" /** Default constructor. */"); out_Renamed.WriteLine(" public " + parser_class_name + "() : base() {}"); if (!suppress_scanner) { out_Renamed.WriteLine(); out_Renamed.WriteLine(" /** Constructor which sets the default scanner. */"); out_Renamed.WriteLine(" public " + parser_class_name + "(CUP.runtime.Scanner s) : base(s) {}"); } /* emit the various tables */ emit_production_table(out_Renamed); do_action_table(out_Renamed, action_table, compact_reduces); do_reduce_table(out_Renamed, reduce_table); /* instance of the action encapsulation class */ out_Renamed.WriteLine(" /** Instance of action encapsulation class. */"); out_Renamed.WriteLine(" protected " + pre("actions") + " action_obj;"); out_Renamed.WriteLine(); /* action object initializer */ out_Renamed.WriteLine(" /** Action encapsulation object initializer. */"); out_Renamed.WriteLine(" protected override void init_actions()"); out_Renamed.WriteLine(" {"); out_Renamed.WriteLine(" action_obj = new " + pre("actions") + "(this);"); out_Renamed.WriteLine(" }"); out_Renamed.WriteLine(); /* access to action code */ out_Renamed.WriteLine(" /** Invoke a user supplied parse action. */"); out_Renamed.WriteLine(" public override CUP.runtime.Symbol do_action("); out_Renamed.WriteLine(" int act_num,"); out_Renamed.WriteLine(" CUP.runtime.lr_parser parser,"); out_Renamed.WriteLine(" CUP.runtime.SymbolStack stack,"); out_Renamed.WriteLine(" int top)"); out_Renamed.WriteLine(" {"); out_Renamed.WriteLine(" /* call code in generated class */"); out_Renamed.WriteLine(" return action_obj." + pre("do_action(") + "act_num, parser, stack, top);"); out_Renamed.WriteLine(" }"); out_Renamed.WriteLine(""); /* method to tell the parser about the start state */ out_Renamed.WriteLine(" /** Indicates start state. */"); out_Renamed.WriteLine(" public override int start_state() {return " + start_st + ";}"); /* method to indicate start production */ out_Renamed.WriteLine(" /** Indicates start production. */"); out_Renamed.WriteLine(" public override int start_production() {return " + start_production.index() + ";}"); out_Renamed.WriteLine(); /* methods to indicate EOF and error symbol indexes */ out_Renamed.WriteLine(" /** <code>EOF</code> Symbol index. */"); out_Renamed.WriteLine(" public override int EOF_sym() {return " + terminal.EOF.index() + ";}"); out_Renamed.WriteLine(); out_Renamed.WriteLine(" /** <code>error</code> Symbol index. */"); out_Renamed.WriteLine(" public override int error_sym() {return " + terminal.error.index() + ";}"); out_Renamed.WriteLine(); /* user supplied code for user_init() */ if (init_code != null) { out_Renamed.WriteLine(); out_Renamed.WriteLine(" /** User initialization code. */"); out_Renamed.WriteLine(" public override void user_init()"); out_Renamed.WriteLine(" {"); out_Renamed.WriteLine(init_code); out_Renamed.WriteLine(" }"); } /* user supplied code for scan */ if (scan_code != null) { out_Renamed.WriteLine(); out_Renamed.WriteLine(" /** Scan to get the next Symbol. */"); out_Renamed.WriteLine(" public override CUP.runtime.Symbol scan()"); out_Renamed.WriteLine(" {"); out_Renamed.WriteLine(scan_code); out_Renamed.WriteLine(" }"); } /* user supplied code */ if (parser_code != null) { out_Renamed.WriteLine(); out_Renamed.WriteLine(parser_code); } /* end of class */ out_Renamed.WriteLine("}"); /* put out the action code class */ emit_action_code(out_Renamed, start_prod); // End of namespace out_Renamed.WriteLine("}"); parser_time = (System.DateTime.Now.Ticks - 621355968000000000) / 10000 - start_time; }
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /// <summary>Build the (internal) parser from the previously parsed specification. /// This includes:<ul> /// <li> Computing nullability of non-terminals. /// <li> Computing first sets of non-terminals and productions. /// <li> Building the viable prefix recognizer machine. /// <li> Filling in the (internal) parse tables. /// <li> Checking for unreduced productions. /// </ul> /// </summary> protected internal static void build_parser() { /* compute nullability of all non terminals */ if (opt_do_debug || print_progress) System.Console.Error.WriteLine(" Computing non-terminal nullability..."); non_terminal.compute_nullability(); nullability_end = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; /* compute first sets of all non terminals */ if (opt_do_debug || print_progress) System.Console.Error.WriteLine(" Computing first sets..."); non_terminal.compute_first_sets(); first_end = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; /* build the LR viable prefix recognition machine */ if (opt_do_debug || print_progress) System.Console.Error.WriteLine(" Building state machine..."); start_state = lalr_state.build_machine(emit.start_production); machine_end = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; /* build the LR parser action and reduce-goto tables */ if (opt_do_debug || print_progress) System.Console.Error.WriteLine(" Filling in tables..."); action_table = new parse_action_table(); reduce_table = new parse_reduce_table(); for (System.Collections.IEnumerator st = lalr_state.all(); st.MoveNext(); ) { lalr_state lst = (lalr_state) st.Current; lst.build_table_entries(action_table, reduce_table); } table_end = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; /* check and warn for non-reduced productions */ if (opt_do_debug || print_progress) System.Console.Error.WriteLine(" Checking for non-reduced productions..."); action_table.check_reductions(); reduce_check_end = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; /* if we have more conflicts than we expected issue a message and die */ if (emit.num_conflicts > expect_conflicts) { System.Console.Error.WriteLine("*** More conflicts encountered than expected " + "-- parser generation aborted"); lexer.error_count++; // indicate the problem. // we'll die on return, after clean up. } }
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /// <summary>Emit the reduce-goto table. /// </summary> /// <param name="out"> stream to produce output on. /// </param> /// <param name="red_tab">the internal representation of the reduce-goto table. /// /// </param> protected internal static void do_reduce_table(System.IO.StreamWriter out_Renamed, parse_reduce_table red_tab) { lalr_state goto_st; // parse_action act; long start_time = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; /* collect values for reduce-goto table */ short[][] reduce_goto_table = new short[red_tab.num_states()][]; /* do each row of the reduce-goto table */ for (int i = 0; i < red_tab.num_states(); i++) { /* make temporary table for the row. */ short[] temp_table = new short[2 * CUP.parse_reduce_row.size()]; int nentries = 0; /* do each entry in the row */ for (int j = 0; j < CUP.parse_reduce_row.size(); j++) { /* get the entry */ goto_st = red_tab.under_state[i].under_non_term[j]; /* if we have none, skip it */ if (goto_st != null) { /* make entries for the index and the value */ temp_table[nentries++] = (short)j; temp_table[nentries++] = (short)goto_st.index(); } } /* now we know how big to make the row. */ reduce_goto_table[i] = new short[nentries + 2]; Array.Copy(temp_table, 0, reduce_goto_table[i], 0, nentries); /* end row with default value */ reduce_goto_table[i][nentries++] = -1; reduce_goto_table[i][nentries++] = -1; } /* emit the table. */ out_Renamed.WriteLine(); out_Renamed.WriteLine(" /** <code>reduce_goto</code> table. */"); out_Renamed.Write(" private static string[] _strGotoTable = "); do_table_as_string(out_Renamed, reduce_goto_table); out_Renamed.WriteLine(";"); out_Renamed.WriteLine(" protected static readonly short[][] _reduce_table = CUP.runtime.lr_parser.unpackFromStrings(_strGotoTable);"); //out_Renamed.Write(" unpackFromStrings("); //do_table_as_string(out_Renamed, reduce_goto_table); //out_Renamed.WriteLine(");"); /* do the public accessor method */ out_Renamed.WriteLine(); out_Renamed.WriteLine(" /** Access to <code>reduce_goto</code> table. */"); out_Renamed.WriteLine(" public override short[][] reduce_table() {return _reduce_table;}"); out_Renamed.WriteLine(); goto_table_time = (System.DateTime.Now.Ticks - 621355968000000000) / 10000 - start_time; }
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /// <summary>Fill in the parse table entries for this state. There are two /// parse tables that encode the viable prefix recognition machine, an /// action table and a reduce-goto table. The rows in each table /// correspond to states of the machine. The columns of the action table /// are indexed by terminal symbols and correspond to either transitions /// out of the state (shift entries) or reductions from the state to some /// previous state saved on the stack (reduce entries). All entries in the /// action table that are not shifts or reduces, represent errors. The /// reduce-goto table is indexed by non terminals and represents transitions /// out of a state on that non-terminal.<p> /// Conflicts occur if more than one action needs to go in one entry of the /// action table (this cannot happen with the reduce-goto table). Conflicts /// are resolved by always shifting for shift/reduce conflicts and choosing /// the lowest numbered production (hence the one that appeared first in /// the specification) in reduce/reduce conflicts. All conflicts are /// reported and if more conflicts are detected than were declared by the /// user, code generation is aborted. /// * /// </summary> /// <param name="act_table"> the action table to put entries in. /// </param> /// <param name="reduce_table">the reduce-goto table to put entries in. /// /// </param> public virtual void build_table_entries(parse_action_table act_table, parse_reduce_table reduce_table) { parse_action_row our_act_row; parse_reduce_row our_red_row; lalr_item itm; parse_action act, other_act; symbol sym; terminal_set conflict_set = new terminal_set(); /* pull out our rows from the tables */ our_act_row = act_table.under_state[index()]; our_red_row = reduce_table.under_state[index()]; /* consider each item in our state */ //UPGRADE_TODO: method 'java.util.Enumeration.hasMoreElements' was converted to ' ' which has a different behavior. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1073_javautilEnumerationhasMoreElements"' for (System.Collections.IEnumerator i = items().all(); i.MoveNext();) { //UPGRADE_TODO: method 'java.util.Enumeration.nextElement' was converted to ' ' which has a different behavior. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1073_javautilEnumerationnextElement"' itm = (lalr_item)i.Current; /* if its completed (dot at end) then reduce under the lookahead */ if (itm.dot_at_end()) { act = new reduce_action(itm.the_production()); /* consider each lookahead symbol */ for (int t = 0; t < terminal.number(); t++) { /* skip over the ones not in the lookahead */ if (!itm.lookahead().contains(t)) { continue; } /* if we don't already have an action put this one in */ if (our_act_row.under_term[t].kind() == parse_action.ERROR) { our_act_row.under_term[t] = act; } else { /* we now have at least one conflict */ terminal term = terminal.find(t); other_act = our_act_row.under_term[t]; /* if the other act was not a shift */ if ((other_act.kind() != parse_action.SHIFT) && (other_act.kind() != parse_action.NONASSOC)) { /* if we have lower index hence priority, replace it*/ if (itm.the_production().index() < ((reduce_action)other_act).reduce_with().index()) { /* replace the action */ our_act_row.under_term[t] = act; } } else { /* Check precedences,see if problem is correctable */ if (fix_with_precedence(itm.the_production(), t, our_act_row, act)) { term = null; } } if (term != null) { conflict_set.add(term); } } } } } /* consider each outgoing transition */ for (lalr_transition trans = transitions(); trans != null; trans = trans.next()) { /* if its on an terminal add a shift entry */ sym = trans.on_symbol(); if (!sym.is_non_term()) { act = new shift_action(trans.to_state()); /* if we don't already have an action put this one in */ if (our_act_row.under_term[sym.index()].kind() == parse_action.ERROR) { our_act_row.under_term[sym.index()] = act; } else { /* we now have at least one conflict */ production p = ((reduce_action)our_act_row.under_term[sym.index()]).reduce_with(); /* shift always wins */ if (!fix_with_precedence(p, sym.index(), our_act_row, act)) { our_act_row.under_term[sym.index()] = act; conflict_set.add(terminal.find(sym.index())); } } } else { /* for non terminals add an entry to the reduce-goto table */ our_red_row.under_non_term[sym.index()] = trans.to_state(); } } /* if we end up with conflict(s), report them */ if (!conflict_set.empty()) { report_conflicts(conflict_set); } }
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /// <summary>Build the (internal) parser from the previously parsed specification. /// This includes:<ul> /// <li> Computing nullability of non-terminals. /// <li> Computing first sets of non-terminals and productions. /// <li> Building the viable prefix recognizer machine. /// <li> Filling in the (internal) parse tables. /// <li> Checking for unreduced productions. /// </ul> /// </summary> protected internal static void build_parser() { /* compute nullability of all non terminals */ if (opt_do_debug || print_progress) { System.Console.Error.WriteLine(" Computing non-terminal nullability..."); } non_terminal.compute_nullability(); nullability_end = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; /* compute first sets of all non terminals */ if (opt_do_debug || print_progress) { System.Console.Error.WriteLine(" Computing first sets..."); } non_terminal.compute_first_sets(); first_end = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; /* build the LR viable prefix recognition machine */ if (opt_do_debug || print_progress) { System.Console.Error.WriteLine(" Building state machine..."); } start_state = lalr_state.build_machine(emit.start_production); machine_end = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; /* build the LR parser action and reduce-goto tables */ if (opt_do_debug || print_progress) { System.Console.Error.WriteLine(" Filling in tables..."); } action_table = new parse_action_table(); reduce_table = new parse_reduce_table(); for (System.Collections.IEnumerator st = lalr_state.all(); st.MoveNext();) { lalr_state lst = (lalr_state)st.Current; lst.build_table_entries(action_table, reduce_table); } table_end = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; /* check and warn for non-reduced productions */ if (opt_do_debug || print_progress) { System.Console.Error.WriteLine(" Checking for non-reduced productions..."); } action_table.check_reductions(); reduce_check_end = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; /* if we have more conflicts than we expected issue a message and die */ if (emit.num_conflicts > expect_conflicts) { System.Console.Error.WriteLine("*** More conflicts encountered than expected " + "-- parser generation aborted"); lexer.error_count++; // indicate the problem. // we'll die on return, after clean up. } }
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /// <summary>Emit the reduce-goto table. /// </summary> /// <param name="out"> stream to produce output on. /// </param> /// <param name="red_tab">the internal representation of the reduce-goto table. /// /// </param> protected internal static void do_reduce_table(System.IO.StreamWriter out_Renamed, parse_reduce_table red_tab) { lalr_state goto_st; // parse_action act; long start_time = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; /* collect values for reduce-goto table */ short[][] reduce_goto_table = new short[red_tab.num_states()][]; /* do each row of the reduce-goto table */ for (int i = 0; i < red_tab.num_states(); i++) { /* make temporary table for the row. */ short[] temp_table = new short[2 * CUP.parse_reduce_row.size()]; int nentries = 0; /* do each entry in the row */ for (int j = 0; j < CUP.parse_reduce_row.size(); j++) { /* get the entry */ goto_st = red_tab.under_state[i].under_non_term[j]; /* if we have none, skip it */ if (goto_st != null) { /* make entries for the index and the value */ temp_table[nentries++] = (short) j; temp_table[nentries++] = (short) goto_st.index(); } } /* now we know how big to make the row. */ reduce_goto_table[i] = new short[nentries + 2]; Array.Copy(temp_table, 0, reduce_goto_table[i], 0, nentries); /* end row with default value */ reduce_goto_table[i][nentries++] = - 1; reduce_goto_table[i][nentries++] = - 1; } /* emit the table. */ out_Renamed.WriteLine(); out_Renamed.WriteLine(" /** <code>reduce_goto</code> table. */"); out_Renamed.Write(" private static string[] _strGotoTable = "); do_table_as_string(out_Renamed, reduce_goto_table); out_Renamed.WriteLine(";"); out_Renamed.WriteLine(" protected static readonly short[][] _reduce_table = CUP.runtime.lr_parser.unpackFromStrings(_strGotoTable);"); //out_Renamed.Write(" unpackFromStrings("); //do_table_as_string(out_Renamed, reduce_goto_table); //out_Renamed.WriteLine(");"); /* do the public accessor method */ out_Renamed.WriteLine(); out_Renamed.WriteLine(" /** Access to <code>reduce_goto</code> table. */"); out_Renamed.WriteLine(" public override short[][] reduce_table() {return _reduce_table;}"); out_Renamed.WriteLine(); goto_table_time = (System.DateTime.Now.Ticks - 621355968000000000) / 10000 - start_time; }