private void BuildConflictTable() { var conflictList = new List <int>(); foreach (var conflict in transitionToConflict.Values) { var refAction = new ParserAction { Kind = ParserActionKind.Conflict, Value1 = conflictList.Count, Size = (short)conflict.Actions.Count }; actionTable.Set(conflict.State, conflict.Token, ParserAction.Encode(refAction)); foreach (var action in conflict.Actions) { conflictList.Add(ParserAction.Encode(action)); } } this.conflictActionTable = conflictList.ToArray(); }
private bool FillAmbiguousTokenActions(DotState[] states, bool isGlr) { for (int i = 0; i != states.Length; ++i) { var state = states[i]; foreach (var ambToken in grammar.AmbiguousSymbols) { var validTokenActions = new Dictionary <int, int>(); foreach (int token in ambToken.Tokens) { int cell = data.Get(i, token); if (cell == 0) { continue; } validTokenActions.Add(token, cell); } switch (validTokenActions.Count) { case 0: // AmbToken is entirely non-acceptable for this state data.Set(i, ambToken.Index, 0); break; case 1: { var pair = validTokenActions.First(); if (pair.Key == ambToken.MainToken) { // ambToken action is the same as for the main token data.Set(i, ambToken.Index, pair.Value); } else { // Resolve ambToken to a one of the underlying tokens. // In runtime transition will be acceptable when this token // is in Msg and non-acceptable when this particular token // is not in Msg. var action = new ParserAction { Kind = ParserActionKind.Resolve, Value1 = pair.Key }; data.Set(i, ambToken.Index, ParserAction.Encode(action)); } } break; default: if (validTokenActions.Values.Distinct().Count() == 1) { // Multiple tokens but with the same action goto case 1; } if (!isGlr) { return(false); } // This kind of ambiguity requires GLR to follow all alternate tokens { var pair = validTokenActions.First(); var forkAction = new ParserAction { Kind = ParserActionKind.Fork, Value1 = pair.Key }; data.Set(i, ambToken.Index, ParserAction.Encode(forkAction)); } break; } } } return(true); }