/// <summary> /// constructor, construct parser table /// </summary> public Parser(Grammar grammar) { _lrGotos = new List <int[]>(); _gotoPrecedence = new List <int[]>(); _lr0Items = new List <LR0Item>(); _lr1Items = new List <LR1Item>(); _lr0States = new List <HashSet <int> >(); _lr0Kernels = new List <HashSet <int> >(); _lalrStates = new List <HashSet <int> >(); _terminals = new HashSet <int>(); _nonterminals = new HashSet <int>(); _lalrPropogations = new List <IDictionary <int, IList <LALRPropogation> > >(); _grammar = grammar; _productions = new List <Production>(); _productionDerivation = new List <Derivation>(); _productionPrecedence = new List <int>(); var nTokens = _grammar.SymbolNames.Length; _firstSets = new HashSet <int> [nTokens]; PopulateProductions(); InitSymbols(); GenerateLR0Items(); ComputeFirstSets(); ConvertLR0ItemsToKernels(); var nLalrStates = InitLALRTables(); CalculateLookAheads(); _parseTable = new ParseTable(nLalrStates, nTokens); GenerateParseTable(); }
public Parser(ParserGenerator p) { parser_generator = p; parse_table = parser_generator.ParseTable; Reset(); int i = 0; foreach (string x in parser_generator.Grammar.Tokens) { token_type.Add(x, i++); } }
/// <summary> /// Generates the parse table given the lalr states, and grammar /// </summary> void GenerateParseTable() { m_parseTable = new ParseTable(); m_parseTable.Actions = new Action[m_lalrStates.Count, m_grammar.Tokens.Length + 1]; for (int nStateID = 0; nStateID < m_lalrStates.Count; nStateID++) { HashSet <int> lalrState = m_lalrStates[nStateID]; for (int nToken = -1; nToken < m_grammar.Tokens.Length; nToken++) { List <Action> actions = new List <Action>(); string sToken = "$"; if (nToken >= 0) { sToken = m_grammar.Tokens[nToken]; if (m_lrGotos[nStateID][nToken] >= 0) { actions.Add(new Action { ActionType = ActionType.Shift, ActionParameter = m_lrGotos[nStateID][nToken] }); } } foreach (int nLR1ItemID in lalrState) { LR1Item lr1Item = m_lr1Items[nLR1ItemID]; LR0Item lr0Item = m_lr0Items[lr1Item.LR0ItemID]; if ((lr0Item.Position == m_productions[lr0Item.Production].Right.Length) && lr1Item.LookAhead == nToken) { Action action = new Action { ActionType = ActionType.Reduce, ActionParameter = lr0Item.Production }; if (!ListContainsAction(actions, action)) { actions.Add(action); } } } int nMaxPrecedence = int.MinValue; List <Action> importantActions = new List <Action>(); foreach (Action action in actions) { int nActionPrecedence = int.MinValue; if (action.ActionType == ActionType.Shift) { nActionPrecedence = m_gotoPrecedence[nStateID][nToken]; //nToken will never be -1 } else if (action.ActionType == ActionType.Reduce) { nActionPrecedence = m_productionPrecedence[action.ActionParameter]; } if (nActionPrecedence > nMaxPrecedence) { nMaxPrecedence = nActionPrecedence; importantActions.Clear(); importantActions.Add(action); } else if (nActionPrecedence == nMaxPrecedence) { importantActions.Add(action); } } if (importantActions.Count == 1) { m_parseTable.Actions[nStateID, nToken + 1] = importantActions[0]; } else if (importantActions.Count > 1) { Action shiftAction = null; List <Action> reduceActions = new List <Action>(); foreach (Action action in importantActions) { if (action.ActionType == ActionType.Reduce) { reduceActions.Add(action); } else { shiftAction = action; } } Derivation derv = m_grammar.PrecedenceGroups[-nMaxPrecedence].Derivation; if (derv == Derivation.LeftMost && reduceActions.Count == 1) { m_parseTable.Actions[nStateID, nToken + 1] = reduceActions[0]; } else if (derv == Derivation.RightMost && shiftAction != null) { m_parseTable.Actions[nStateID, nToken + 1] = shiftAction; } else { if (derv == Derivation.None && reduceActions.Count == 1) { Debug.Console.WriteLine("Error, shift-reduce conflict in grammar"); } else { Debug.Console.WriteLine("Error, reduce-reduce conflict in grammar"); } m_parseTable.Actions[nStateID, nToken + 1] = new Action { ActionType = ActionType.Error, ActionParameter = nToken }; } } else { m_parseTable.Actions[nStateID, nToken + 1] = new Action { ActionType = ActionType.Error, ActionParameter = nToken }; } } } }