我在哪里可以找到LR(1)解析器生成器的_简单_、易于理解的实现?在哪里可以找到LR(1)解析器生成器的简单(尽可能但不简单!)实现?我不是在寻找性能,只是能够生成LR(1)状态(项集)。C++、C#、Java和Python都适合我。我用C#写了一个非常简单的,想在这里分享一下。它基本上填充了动作查找表,该表告诉您要切换到哪个状态或用于减少的规则。如果数字是非负的,代表新的状态;如果它是负数,那么它的补码(即~x)代表正则指数。现在您只需要制作词法分析器并使用操作表进行实际解析。注意1:生成真实语法状态的速度可能很慢,因此在生产代码中使用它之前您可能要三思而后行!注意2:您可能需要仔细检查它的正确性,因为我只检查过它。使用系统;使用System.Collections.Generic;使用系统诊断;使用System.Linq;使用size_t=System.UInt32;公共类LRParser{私有字符串[]符号;//索引=>符号privateIDictionaryinterned=newSortedDictionary();//symbol=>indexprivateint[/*state*/,/*lookahead*/]actions;//如果>=0,表示移位后的新状态。if[]语法){this.interned.Add(string.Empty,newsize_t());foreach(varruleingrammar){if(!this.interned.ContainsKey(rule.Key)){this.interned.Add(rule.Key,(size_t)this.interned.Count);}foreach(varsymbolinrule.Value){if(!this.interned.ContainsKey(symbol)){this.interned.Add(symbol,(size_t)this.interned.Count);}}}this.symbols=this.interned.ToArray().OrderBy(p=>p.Value).Select(p=>p.Key).ToArray();varsyntax=Array.ConvertAll(grammar,r=>newKeyValuePair(this.interned[r.Key],Array.ConvertAll(r.Value,s=>this.interned[s])));varnonterminals=Array.ConvertAll(this.symbols,s=>newList());for(size_ti=0;inonterminals[s].Count>0?newHashSet():newHashSet(){(size_t)s});老;做{old=firsts.Select(l=>l.Count).Sum();foreach(varruleinsyntax){foreach(variinFirst(rule.Value,firsts)){firsts[rule.Key].Add(i);}}}while(oldl.Count).Sum());varactions=newDictionary>>();varstates=newDictionary,int>(HashSet.CreateSetComparer());vartodo=newStack>();varroot=newItem(0,0,newsize_t());todo.Push(newHashSet());Closure(root,todo.Peek(),firsts,syntax,nonterminals);states.Add(newHashSet(todo.Peek()),states.Count);while(todo.Count>0){varset=todo.Pop();varclosure=newHashSet();foreach(variteminset){Closure(item,closure,firsts,syntax,nonterminals);}vargrouped=Array.ConvertAll(this.symbols,_=>newHashSet());foreach(variteminclosure){if(item.Symbol>=syntax[item.Rule].Value.Length){IDictionary>map;如果一个ctions.TryGetValue(states[set],outmap)){actions[states[set]]=map=newDictionary>();}IList列表;if(!map.TryGetValue(item.Lookahead,outlist)){map[item.Lookahead]=list=newList();}list.Add(~(int)item.Rule);继续;}varnext=item;下一个符号++;分组[语法[item.Rule].Value[item.Symbol]].Add(next);}for(size_tsymbol=0;symbol();foreach(varitemingrouped[symbol]){Closure(item,g,firsts,syntax,nonterminals);}if(g.Count>0){intstate;如果(!states.TryGetValue(g,outstate)){state=states.Count;states.Add(g,state);todo.Push(g);}IDictionary>map;if(!actions.TryGetValue(states[set],outmap)){actions[states[set]]=map=newDictionary>();}IList列表;if(!map.TryGetValue(symbol,outlist)){map[symbol]=list=newList();}list.Add(state);}}}this.actions=newint[states.Count,this.symbols.Length];for(inti=0;ip.Value)){Console.WriteLine("状态{0}:",state.Value);foreach(variteminstate.Key.OrderBy(i=>i.Rule).ThenBy(i=>i.Symbol).ThenBy(i=>i.Lookahead)){Console.WriteLine("t{0}:{1}xB7{2}|{3}→{0}",this.symbols[syntax[item.Rule].Key],string.Join("",syntax[item.Rule].Value.Take((int)item.Symbol).Select(s=>this.symbols[s]).ToArray()),string.Join("",syntax[item.Rule].Value.Skip((int)item.Symbol).选择(s=>this.symbols[s]).ToArray()),this.symbols[item.Lookahead]==string.Empty?"x04":this.symbols[item.Lookahead],string.Join(",",Array.ConvertAll(actions[state.Value][item.Symbola>=0?string.Format("state{0}",a):string.Format("{0}(rule{1})",this.symbols[语法[~a].Key],~a))));}控制台.WriteLine();}}privatestaticvoidClosure(Itemitem,HashSetclosure/*output*/,HashSet[]firs,KeyValuePair[]syntax,IList[]nonterminals){if(closure.Add(item)&&item.Symbol>=语法[item.Rule].Value.Length){foreach(varrinnonterminals[syntax[item.Rule].Value[item.Symbol]]){foreach(variinFirst(syntax[item.Rule].Value.Skip((int)(item.Symbol+1)),firsts)){Closure(newItem(r,0,i==newsize_t()?item.Lookahead:i),closure,firsts,syntax,nonterminals);}}}}privatestructItem:IEquatable{publicsize_tRule;公共size_t符号;公共size_t前瞻;publicItem(size_trule,size_tsymbol,size_tlookahead){this.Rule=rule;this.Symbol=符号;this.Lookahead=向前看;}publicoverrideboolEquals(objectobj){returnobjisItem&&this.Equals((Item)obj);}publicboolEquals(Itemother){returnthis.Rule==other.Rule&&this.Symbol==other.Symbol&&this.Lookahead==other.Lookahead;}publicoverrideintGetHashCode(){returnthis.Rule.GetHashCode()^this.Symbol.GetHashCode()^this.Lookahead.GetHashCode();}}privatestaticIEnumerableFirst(IEnumerablesymbols,IEnumerable[]map){foreach(varsymbolinsymbols){boolepsilon=false;foreach(变量sinmap[symbol]){if(s==newsize_t()){epsilon=true;}else{yieldreturns;}}if(!epsilon){yieldbreak;}}yieldreturnnewsize_t();}privatestaticKeyValuePairMakePair(Kk,Vv){returnnewKeyValuePair(k,v);}privatestaticvoidMain(string[]args){varsw=Stopwatch.StartNew();varparser=newLRParser(MakePair("start",newstring[]{"exps"}),MakePair("exps",newstring[]{"exps","exp"}),MakePair("exps",newstring[]{}),MakePair("exp",newstring[]{"INTEGER"}));Console.WriteLine(sw.ElapsedMilliseconds);LRSTAR9.1是最小的LR(1)和LR(*)解析器生成器,您可以使用选项“/s”来验证解析器生成器是否提供正确的状态。LRSTAR已经针对HYACC进行了测试,发现可以提供正确的LR(1)状态。LRSTAR和6个MicrosoftVisualStudio项目提供了20种语法。C#学习教程就是这样:我在哪里可以找到LR(1)解析器生成器的_简单_、易于理解的实现?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
