public static void Build(GrammarTables result, Grammar grammar) { using (var builder = new BuildDFA()) { builder.InternalBuild(result, grammar); } }
private void LoadEGT(BinaryReader reader) { using (EGTReader egtReader = new EGTReader(reader)) { while (egtReader.GetNextRecord()) { switch (egtReader.ReadRecordType()) { case EGTRecord.Property: GrammarProperties.SetProperty(egtReader.ReadGrammarProperty()); break; case EGTRecord.TableCounts: GrammarTables = egtReader.ReadGrammarTables(); break; case EGTRecord.InitialStates: //DFA, LALR ushort dfaState = egtReader.ReadUInt16(); ushort lalrState = egtReader.ReadUInt16(); Debug.Assert(dfaState == 0, "The initial DFA State is not 0!"); Debug.Assert(lalrState == 0, "The initial LALR State is not 0!"); break; case EGTRecord.Symbol: Symbol sym = egtReader.ReadSymbol(); GrammarTables.Symbols[sym.TableIndex] = sym; break; case EGTRecord.Group: Group group = egtReader.ReadGroup(); GrammarTables.Groups[group.TableIndex] = group; break; case EGTRecord.CharRanges: CharacterSet charSet = egtReader.ReadCharacterSet(); GrammarTables.CharacterSets[charSet.Index] = charSet; break; case EGTRecord.Production: Production prod = egtReader.ReadProduction(); GrammarTables.Productions[prod.TableIndex] = prod; break; case EGTRecord.DFAState: FAState faState = egtReader.ReadFAState(); GrammarTables.FAStates[faState.TableIndex] = faState; break; case EGTRecord.LRState: LRActionList actionList = egtReader.ReadLRActionList(); GrammarTables.LRActionLists[actionList.Index] = actionList; break; } } } }
private void CheckErrorsDFA(GrammarTables result) { bool hasErrors = false; if (m_dfa[result.DfaStartState].AcceptList.Count > 0) { hasErrors = true; foreach (var item in m_dfa[result.DfaStartState].AcceptList) { Console.WriteLine($"The terminal '{item.Symbol.Name}' can be zero length."); Console.WriteLine("The definition of this terminal allows it to contain no characters."); } } if (!hasErrors) { foreach (var build in m_dfa) { if (build.AcceptList.Count >= 2) { hasErrors = true; Console.WriteLine($"DFA State '{build.TableIndex}' cannot distinguish between: "); foreach (var item in build.AcceptList) { Console.WriteLine($" {item.Symbol.Name}"); } } } } if (!hasErrors) { var symbols = new HashSet <Symbol>(result.Symbols.OfType <SymbolTerminal>().Where(s => s.Expression != null)); foreach (var build in result.DFA) { symbols.Remove(build.Accept); } foreach (var build in symbols) { hasErrors = true; Console.WriteLine($"The terminal '{build.Name}' cannot be accepted by the DFA."); } } if (!hasErrors) { Console.WriteLine("The DFA State Table was successfully created."); Console.WriteLine($"The table contains a total of {result.DFA.Count} states."); } }
internal GrammarTables ReadGrammarTables() { ushort symbolsSize = ReadUInt16(); ushort charSetsSize = ReadUInt16(); ushort productionsSize = ReadUInt16(); ushort faStatesSize = ReadUInt16(); ushort lrActionsListsSize = ReadUInt16(); ushort groupsSize = ReadUInt16(); //Keep it for later use in addition to reading it grammarTables = new GrammarTables(symbolsSize, charSetsSize, productionsSize, faStatesSize, lrActionsListsSize, groupsSize); return(grammarTables); }
private void InternalBuild(GrammarTables result) { var startSymbol = m_grammar.StartSymbol; if (ReferenceEquals(startSymbol, null)) { throw new Exception("ERROR: Start symbol is invalid or missing"); } Console.WriteLine("Computing LALR Tables"); SetupTempTables(); Console.WriteLine("LALR Tables Completed"); }
private void InternalBuild(GrammarTables result, Grammar grammar) { Console.WriteLine("Computing DFA States"); foreach (var terminal in grammar.BuildSymbols.Select(s => s.Symbol).OfType <SymbolTerminal>()) { if (terminal.Expression == null) { continue; } var target = AddState(); var source = AddState(); foreach (Sequence sequence in terminal.Expression) { Automata type = sequence.CreateAutomata(this); m_nfa[target].AddLambdaEdge(type.Head); m_nfa[type.Tail].AddLambdaEdge(source); m_nfa[type.Tail].AddAccept(terminal, sequence.Priority); } m_nfa[m_root].AddLambdaEdge(target); } for (int i = 0; i < m_nfa.Count; ++i) { var reachable = new HashSet <int> { i }; ClosureNFA(reachable); m_nfa[i].NFAClosure = reachable; } var nfaList = new HashSet <int> { m_root }; result.DfaStartState = BuildDFAState(nfaList); foreach (var build in m_dfa) { Debug.Assert(build.TableIndex == result.DFA.Count); var state = new DFAState { TableIndex = build.TableIndex }; // copy edges. foreach (var edge in build.Edges) { state.Edges.Add(edge); //result.AddCharacterSet(edge.Value); } // get accept symbol. if (build.AcceptList.Count == 0) { state.Accept = null; } else if (build.AcceptList.Count == 1) { state.Accept = build.AcceptList[0].Symbol; } else { var accept = build.AcceptList[0]; var priority = accept.Priority; var list = new List <Symbol>(); list.Add(accept.Symbol); for (int i = 1; i < build.AcceptList.Count; ++i) { accept = build.AcceptList[i]; if (accept.Priority == priority) { list.Add(accept.Symbol); } else if (accept.Priority < priority) { list.Clear(); list.Add(accept.Symbol); priority = accept.Priority; } } build.AcceptList.Clear(); foreach (var symbol in list) { build.AddAccept(symbol, priority); } if (list.Count == 1) { state.Accept = list[0]; } } result.DFA.Add(state); } CheckErrorsDFA(result); Console.WriteLine("DFA States Completed"); }
internal GrammarTables ReadGrammarTables() { ushort symbolsSize = ReadUInt16(); ushort charSetsSize = ReadUInt16(); ushort productionsSize = ReadUInt16(); ushort faStatesSize = ReadUInt16(); ushort lrActionsListsSize = ReadUInt16(); ushort groupsSize = ReadUInt16(); //Keep it for later use in addition to reading it grammarTables = new GrammarTables(symbolsSize, charSetsSize, productionsSize, faStatesSize, lrActionsListsSize, groupsSize); return grammarTables; }