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();
        }
Exemple #2
0
        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);
        }