public void GetParser(Lexer m_lexer) { Serialiser b = new Serialiser(arr); b.VersionCheck(); m_startSymbol = (CSymbol)b.Deserialise(); m_startSymbol.kids = new ObjectList(); // 4.2a m_accept = (ParseState)b.Deserialise(); m_states = (Hashtable)b.Deserialise(); literals = (Hashtable)b.Deserialise(); symbolInfo = (Hashtable)b.Deserialise(); m_concrete = (bool)b.Deserialise(); GetEOF(m_lexer); }
public void AddEntries() { ProdItemList pil; for (pil=m_items; pil.m_pi!=null; pil=pil.m_next) { ProdItem item = pil.m_pi; if (item.m_done) continue; CSymbol s = item.Next(); if (s==null || item.IsReducingAction()) continue; // shift/goto action // Build a new parse state as target: we will check later to see if we need it ParseState p = new ParseState(m_sgen,s); // the new state should have at least the successor of this item p.MaybeAdd(new ProdItem(item.m_prod, item.m_pos+1)); // check the rest of the items in this ParseState (leads to m_done for them) // looking for other items that allow this CSymbol to pass for (ProdItemList pil1=pil.m_next; pil1!=null && pil1.m_pi!=null; pil1=pil1.m_next) { ProdItem another = pil1.m_pi; if (s==another.Next()) { p.MaybeAdd(new ProdItem(another.m_prod, another.m_pos+1)); another.m_done = true; } } if (!m_items.AtEnd) { if (s.IsAction()) { p = p.CheckExists(); foreach (CSymbol f in s.m_follow.Keys) if (f!=m_sgen.m_symbols.EOFSymbol) { Transition t = GetTransition(f); // if (t.m_next!=null) // m_sgen.Error(15,s.pos,String.Format("Action/Action or Action/Shift conflict on {0}",f.yytext)); t.m_next = new ParserShift((ParserAction)s,p); } } else { // we guarantee to make a nonzero entry in the parsetable GetTransition(s).m_next = new ParserShift(null, p.CheckExists()); } } } }
public bool SameAs(ParseState p) { if (m_accessingSymbol!=p.m_accessingSymbol) return false; ProdItemList pos1 = m_items; ProdItemList pos2 = p.m_items; while (!pos1.AtEnd && !pos2.AtEnd && pos1.m_pi.m_prod==pos2.m_pi.m_prod && pos1.m_pi.m_pos==pos2.m_pi.m_pos) { pos1 = pos1.m_next; pos2 = pos2.m_next; } return pos1.AtEnd && pos2.AtEnd; }
public Transition(ParseState p,CSymbol a) { m_ps = p; m_A = a; m_tno = p.m_sgen.m_trans++; p.m_transitions[a.yytext] = this; }
public bool Lookback(Production pr,ParseState p) { return new Path(this,pr.Prefix(pr.m_rhs.Count)).Top==this; }
public override void Print(ParseState ps,CSymbol s) { base.Print(ps,s); while (s.m_symtype==CSymbol.SymType.nodesymbol) s = s.m_refSymbol; Transition t = (Transition)ps.m_transitions[s.yytext]; Transition.Follow(t).Print(); }
public ParserShift(ParserAction action,ParseState next) : base(action) { m_next=next; }
internal Hashtable Reduce(ParseState p) // Objectlist of ParserReduce to distinct productions { if (!p.m_transitions.Contains(yytext)) return null; return ((Transition)p.m_transitions[yytext]).m_reduce; }
public Precedence.PrecType ShiftPrecedence(Production prod,ParseState ps) // 4.5h { if (prod==null) // no reduce available return Precedence.PrecType.left; // shift // 4.5h if (!((SymbolSet)prod.m_lhs.m_follow).Contains(this)) // if this is not a follow symbol of the prod's lhs, there is no conflict return Precedence.PrecType.left; // shift // 4.5h if (m_prec==null) { // no precedence information Console.WriteLine("Shift/Reduce conflict {0} on reduction {1} in state {2}", yytext, prod.m_pno,ps.m_state); return Precedence.PrecType.left; // shift anyway // 4.5h } if (m_prec.m_type==Precedence.PrecType.nonassoc) // 4.5h return Precedence.PrecType.nonassoc; // 4.5h int p = Precedence.Check(this,prod,0); if (p==0) { if (Precedence.Check(m_prec,Precedence.PrecType.right,0)!=0) { // equal precedence but right associative: shift return Precedence.PrecType.left; // 4.5h } return Precedence.PrecType.right; // don't shift // 4.5h } return (p>0)?Precedence.PrecType.left:Precedence.PrecType.right; // shift if symbol has higher precedence than production, else reduce // 4.5h }
void _Create() { ptokens tks = new ptokens(erh); m_outname = "syntax"; tks.m_sgen = this; m_lexer = tks; m_symbols.erh = erh; m_symbols.ClassInit(this); m_outname = "syntax"; m_outFile.WriteLine("using System;using Tools;"); Production special = new Production(this,m_symbols.Special); m_lexer.yytext = "error"; CSymbol e = (new CSymbol(this)).Resolve(); e.m_symtype = CSymbol.SymType.nonterminal; e.m_defined=true; // 1: INPUT // top-down parsing of script m_lexer.Start(m_inFile); m_tok = (TOKEN)m_lexer.Next(); //Console.WriteLine("Token <{0}> {1}",m_tok.yytext,m_tok.GetType().Name); while (m_tok!=null) ParseProduction(); // that's the end of the script if (!m_parserseen) Error(30,0,"no parser directive detected - possibly incorrect text encoding?"); m_outFile.WriteLine(m_actions); // output the action function m_outFile.WriteLine("} return null; }"); special.AddToRhs(m_symbols.m_startSymbol); special.AddToRhs(m_symbols.EOFSymbol); // 2: PROCESSING Console.WriteLine("First"); DoFirst(); Console.WriteLine("Follow"); DoFollow(); Console.WriteLine("Parse Table"); ParseState start = new ParseState(this,null); m_symbols.m_states[0] = start; start.MaybeAdd(new ProdItem(special,0)); start.Closure(); start.AddEntries(); Transition tfinal = (Transition)start.m_transitions[m_symbols.m_startSymbol.yytext]; ParserShift pe = tfinal.m_next; m_symbols.m_accept = pe.m_next; if (m_symbols.m_accept==null) m_symbols.erh.Error(new CSToolsFatalException(43,0,0,"","No accept state. ParserGenerator cannot continue.")); // 2A: Reduce States for the LR(0) parser foreach (ParseState ps in m_symbols.m_states.Values) ps.ReduceStates(); /* if (m_showParser) { foreach (ParseState ps in m_symbols.m_states.Values) { ps.Print0(); if (ps==m_symbols.m_accept) Console.WriteLine(" EOF accept"); } } */ // 3: Compute Look-ahead sets if (m_lalrParser) { m_symbols.Transitions(new Builder(Transition.BuildDR)); /* if (m_showParser) m_symbols.PrintTransitions(new Func(Transition.DR),"DR"); */ m_symbols.Transitions(new Builder(Transition.BuildReads)); new Digraph(this, new Relation(Transition.reads), new Func(Transition.DR), new Func(Transition.Read), new AddToFunc(Transition.AddToRead)).Compute(); // detect cycles in Read TBD /* if (m_showParser) m_symbols.PrintTransitions(new Func(Transition.Read),"Read"); */ m_symbols.Transitions(new Builder(Transition.BuildIncludes)); m_symbols.Transitions(new Builder(Transition.BuildLookback)); new Digraph(this, new Relation(Transition.includes), new Func(Transition.Read), new Func(Transition.Follow), new AddToFunc(Transition.AddToFollow)).Compute(); // detect cycles for which Read is non empty TBD /* if (m_showParser) m_symbols.PrintTransitions(new Func(Transition.Follow),"Follow"); */ m_symbols.Transitions(new Builder(Transition.BuildLA)); } // 5: OUTPUT // output the run-time ParsingInfo table Console.WriteLine("Building parse table"); m_symbols.Transitions(new Builder(Transition.BuildParseTable)); foreach (CSymbol v in m_symbols.symbols.Values) { if (v.m_symtype!=CSymbol.SymType.nodesymbol) continue; ParsingInfo pi = new ParsingInfo(v.yytext); CSymbol r = v; while (r.m_symtype==CSymbol.SymType.nodesymbol) r = r.m_refSymbol; if (m_symbols.symbolInfo[v.yytext]!=null) m_symbols.erh.Error(new CSToolsException(45,"Bad %node/%symbol hierarchy")); pi.m_parsetable = m_symbols.GetSymbolInfo(r.yytext).m_parsetable; m_symbols.symbolInfo[v.yytext] = pi; } Console.WriteLine("Writing the output file"); m_outFile.WriteLine(@"/// <summary/>"); m_outFile.WriteLine("public yy"+m_outname+"():base() { arr = new int[] { "); m_symbols.Emit(m_outFile); // output the class factories CSymbol s; Console.WriteLine("Class factories"); IDictionaryEnumerator de = m_symbols.symbols.GetEnumerator(); for (int pos = 0; pos<m_symbols.symbols.Count; pos++) { de.MoveNext(); string str = (string)de.Key; s = (CSymbol)de.Value; if ((s==null) // might happen because of error recovery || (s.m_symtype!=CSymbol.SymType.nonterminal && s.m_symtype!=CSymbol.SymType.nodesymbol)) continue; //Console.WriteLine("{0} {1}",s.yytext,s.m_symtype); m_outFile.WriteLine("new Sfactory(this,\"{0}\",new SCreator({0}_factory));",str); } m_outFile.WriteLine("}"); de.Reset(); for (int pos = 0; pos<m_symbols.symbols.Count; pos++) { de.MoveNext(); string str = (string)de.Key; s = (CSymbol)de.Value; if ((s==null) // might happen because of error recovery || (s.m_symtype!=CSymbol.SymType.nonterminal && s.m_symtype!=CSymbol.SymType.nodesymbol)) continue; //Console.WriteLine("{0} {1}",s.yytext,s.m_symtype); m_outFile.WriteLine(@"/// <summary/>"); m_outFile.WriteLine("public static object "+str+"_factory(Parser yyp) { return new "+str+"(yyp); }"); } m_outFile.WriteLine("}"); m_outFile.WriteLine(@"/// <summary/>"); m_outFile.WriteLine("public class "+m_outname+": Parser {"); m_outFile.WriteLine(@"/// <summary/>"); m_outFile.WriteLine("public "+m_outname+"():base(new yy"+m_outname+"(),new "+m_lexerClass+"()) {}"); m_outFile.WriteLine(@"/// <summary/>"); m_outFile.WriteLine("public "+m_outname+"(Symbols syms):base(syms,new "+m_lexerClass+"()) {}"); m_outFile.WriteLine(@"/// <summary/>"); m_outFile.WriteLine("public "+m_outname+"(Symbols syms,ErrorHandler erh):base(syms,new "+m_lexerClass+"(erh)) {}"); m_outFile.WriteLine(m_actvars); m_outFile.WriteLine(" }"); if (m_namespace) m_outFile.WriteLine("}"); Console.WriteLine("Done"); if (m_showParser) { foreach (ParseState ps in m_symbols.m_states.Values) { ps.Print(); if (ps==m_symbols.m_accept) Console.WriteLine(" EOF accept"); } } }
internal ParseState Next(ParseState p) { if (!p.m_transitions.Contains(yytext)) return null; ParserShift ps = ((Transition)p.m_transitions[yytext]).m_next; if (ps==null) return null; return ps.m_next; }
// Objectlist of ParserReduce to distinct productions internal Hashtable Reduce(ParseState p) { if (!p.m_transitions.Contains(yytext)) return null; return ((Transition)p.m_transitions[yytext]).m_reduce; }
public bool Lookback(Production pr, ParseState p) { return(new Path(this, pr.Prefix(pr.m_rhs.Count)).Top == this); }
public override void Print(ParseState ps,CSymbol s) { base.Print(ps,s); Console.Write(" "); m_lookAhead.Print(); }
public Path(ParseState[] s) { m_states = s; }
public ObjectList m_prods = new ObjectList(); // Production: productions with this symbol as left side public void AddStartItems(ParseState pstate,SymbolSet follows) { for (int pos=0;pos<m_prods.Count;pos++) { Production p = (Production)m_prods[pos]; pstate.MaybeAdd(new ProdItem(p, 0)); } }
public Path(ParseState q,CSymbol[] x) { m_states = new ParseState[x.Length+1]; ParseState c; c = m_states[0] = q; for (int j=0;j<x.Length;j++) { int k; for (k=j;k<x.Length;k++) if (!x[k].IsAction()) break; if (k>=x.Length) { m_states[j+1] = c; continue; } Transition t = (Transition)c.m_transitions[x[k].yytext]; if (t==null || t.m_next==null) { valid = false; break; } c = m_states[j+1] = t.m_next.m_next; } }
public virtual void Print(ParseState ps,CSymbol s) { Console.Write(" {0} {1} ",s.yytext,str); if (m_action!=null) m_action.Print(); }