示例#1
0
        /// <summary>
        /// Constructs a new <see cref="Parser"/> which can recoganize the specified <see cref="IGrammar"/>.
        /// </summary>
        /// <param name="grammar">The <see cref="IGrammar"/> to be recognized by the <see cref="Parser"/>.</param>
        /// <returns>A <see cref="ParserGeneratorResult"/> containing <see cref="Parser"/> and information pertaining to the
        /// success or failure of the generation process.
        /// </returns>
        public ParserGeneratorResult GenerateParser(IGrammar grammar)
        {
            List <ParserGeneratorParserConflict> conflicts = new List <ParserGeneratorParserConflict>();

            List <GeneratorState> states = CreateStates(grammar);

            // Create a parser state for each generator state.
            //
            Dictionary <GeneratorState, ParserState> parserStates = new Dictionary <GeneratorState, ParserState>();

            foreach (GeneratorState state in states)
            {
                parserStates.Add(state, new ParserState(state.Id));
            }

            foreach (GeneratorState state in states)
            {
                LinguaTrace.TraceEvent(TraceEventType.Verbose, LinguaTraceId.ID_GENERATE_PROCESS_STATE, "{0}", state);

                List <GeneratorStateItem> items = new List <GeneratorStateItem>(state.Items);
                items.Sort();

                // Construct the list of actions associated with the parser state.
                //
                Dictionary <TerminalType, ParserAction>      actions     = new Dictionary <TerminalType, ParserAction>();
                Dictionary <ParserAction, GeneratorRuleItem> actionRules = new Dictionary <ParserAction, GeneratorRuleItem>();
                foreach (GeneratorStateItem item in items)
                {
                    LinguaTrace.TraceEvent(TraceEventType.Verbose, LinguaTraceId.ID_GENERATE_PROCESS_ITEM, "{0}", item);

                    if (item.RuleItem.DotElement == null)
                    {
                        foreach (TerminalType terminal in item.RuleItem.Rule.Lhs.Follow)
                        {
                            LinguaTrace.TraceEvent(TraceEventType.Verbose, LinguaTraceId.ID_GENERATE_PROCESS_TERMINAL, "{0}", terminal);

                            if (actions.ContainsKey(terminal))
                            {
                                ParserGeneratorParserConflict conflict = new ParserGeneratorParserConflict(
                                    actionRules[actions[terminal]].ToString(),
                                    item.RuleItem.ToString());

                                LinguaTrace.TraceEvent(TraceEventType.Information, LinguaTraceId.ID_GENERATE_PROCESS_CONFLICT, "{0}", conflict);

                                conflicts.Add(conflict);
                            }
                            else if (item.RuleItem.Rule.Lhs.IsStart &&
                                     terminal.IsStop)
                            {
                                ParserAction action = new ParserActionAccept(item.RuleItem.Rule);

                                LinguaTrace.TraceEvent(TraceEventType.Information, LinguaTraceId.ID_GENERATE_PROCESS_ACTION, "{0}", action);

                                actions.Add(terminal, action);
                                actionRules.Add(action, item.RuleItem);
                            }
                            else
                            {
                                ParserAction action = new ParserActionReduce(item.RuleItem.Rule);

                                LinguaTrace.TraceEvent(TraceEventType.Information, LinguaTraceId.ID_GENERATE_PROCESS_ACTION, "{0}", action);

                                actions.Add(terminal, action);
                                actionRules.Add(action, item.RuleItem);
                            }
                        }
                    }
                    else if (item.RuleItem.DotElement.ElementType == LanguageElementTypes.Terminal)
                    {
                        TerminalType terminal = (TerminalType)item.RuleItem.DotElement;

                        if (actions.ContainsKey(terminal))
                        {
                            ParserGeneratorParserConflict conflict = new ParserGeneratorParserConflict(
                                actionRules[actions[terminal]].ToString(),
                                item.RuleItem.ToString());

                            LinguaTrace.TraceEvent(TraceEventType.Information, LinguaTraceId.ID_GENERATE_PROCESS_CONFLICT, "{0}", conflict);

                            conflicts.Add(conflict);
                        }
                        else
                        {
                            ParserAction action = new ParserActionShift(parserStates[state.Transitions[terminal]]);

                            LinguaTrace.TraceEvent(TraceEventType.Information, LinguaTraceId.ID_GENERATE_PROCESS_ACTION, "{0}", action);

                            actions.Add(terminal, action);
                            actionRules.Add(action, item.RuleItem);
                        }
                    }
                }

                // Construct the GOTO table
                //
                Dictionary <NonterminalType, ParserState> gotos = new Dictionary <NonterminalType, ParserState>();
                foreach (KeyValuePair <LanguageElementType, GeneratorState> transition in state.Transitions)
                {
                    if (transition.Key.ElementType == LanguageElementTypes.Nonterminal)
                    {
                        NonterminalType nonterminal = (NonterminalType)transition.Key;
                        gotos.Add(nonterminal, parserStates[transition.Value]);
                    }
                }

                // Update the parser state.
                //
                ParserState parserState = parserStates[state];
                foreach (KeyValuePair <TerminalType, ParserAction> action in actions)
                {
                    parserState.Actions.Add(action.Key, action.Value);
                }

                foreach (KeyValuePair <NonterminalType, ParserState> gotoItem in gotos)
                {
                    parserState.Gotos.Add(gotoItem.Key, gotoItem.Value);
                }
            }

            Parser parser = new Parser(parserStates[states[0]]);

            ParserGeneratorResult result = new ParserGeneratorResult(parser, conflicts);

            return(result);
        }
示例#2
0
        /// <summary>
        /// Constructs a new <see cref="Parser"/> which can recoganize the specified <see cref="IGrammar"/>.
        /// </summary>
        /// <param name="grammar">The <see cref="IGrammar"/> to be recognized by the <see cref="Parser"/>.</param>
        /// <returns>A <see cref="ParserGeneratorResult"/> containing <see cref="Parser"/> and information pertaining to the
        /// success or failure of the generation process.
        /// </returns>
        public ParserGeneratorResult GenerateParser(IGrammar grammar)
        {
            List<ParserGeneratorParserConflict> conflicts = new List<ParserGeneratorParserConflict>();

            List<GeneratorState> states = CreateStates(grammar);

            // Create a parser state for each generator state.
            //
            Dictionary<GeneratorState, ParserState> parserStates = new Dictionary<GeneratorState, ParserState>();
            foreach (GeneratorState state in states)
            {
                parserStates.Add(state, new ParserState(state.Id));
            }

            foreach (GeneratorState state in states)
            {
                LinguaTrace.TraceEvent(TraceEventType.Verbose, LinguaTraceId.ID_GENERATE_PROCESS_STATE, "{0}", state);

                List<GeneratorStateItem> items = new List<GeneratorStateItem>(state.Items);
                items.Sort();

                // Construct the list of actions associated with the parser state.
                //
                Dictionary<TerminalType, ParserAction> actions = new Dictionary<TerminalType, ParserAction>();
                Dictionary<ParserAction, GeneratorRuleItem> actionRules = new Dictionary<ParserAction, GeneratorRuleItem>();
                foreach (GeneratorStateItem item in items)
                {
                    LinguaTrace.TraceEvent(TraceEventType.Verbose, LinguaTraceId.ID_GENERATE_PROCESS_ITEM, "{0}", item);

                    if (item.RuleItem.DotElement == null)
                    {
                        foreach (TerminalType terminal in item.RuleItem.Rule.Lhs.Follow)
                        {
                            LinguaTrace.TraceEvent(TraceEventType.Verbose, LinguaTraceId.ID_GENERATE_PROCESS_TERMINAL, "{0}", terminal);

                            if (actions.ContainsKey(terminal))
                            {
                                ParserGeneratorParserConflict conflict = new ParserGeneratorParserConflict(
                                    actionRules[actions[terminal]].ToString(),
                                    item.RuleItem.ToString());

                                LinguaTrace.TraceEvent(TraceEventType.Information, LinguaTraceId.ID_GENERATE_PROCESS_CONFLICT, "{0}", conflict);

                                conflicts.Add(conflict);
                            }
                            else if (item.RuleItem.Rule.Lhs.IsStart
                                     && terminal.IsStop)
                            {
                                ParserAction action = new ParserActionAccept(item.RuleItem.Rule);

                                LinguaTrace.TraceEvent(TraceEventType.Information, LinguaTraceId.ID_GENERATE_PROCESS_ACTION, "{0}", action);

                                actions.Add(terminal, action);
                                actionRules.Add(action, item.RuleItem);
                            }
                            else
                            {
                                ParserAction action = new ParserActionReduce(item.RuleItem.Rule);

                                LinguaTrace.TraceEvent(TraceEventType.Information, LinguaTraceId.ID_GENERATE_PROCESS_ACTION, "{0}", action);

                                actions.Add(terminal, action);
                                actionRules.Add(action, item.RuleItem);
                            }
                        }
                    }
                    else if (item.RuleItem.DotElement.ElementType == LanguageElementTypes.Terminal)
                    {
                        TerminalType terminal = (TerminalType)item.RuleItem.DotElement;

                        if (actions.ContainsKey(terminal))
                        {
                            ParserGeneratorParserConflict conflict = new ParserGeneratorParserConflict(
                                actionRules[actions[terminal]].ToString(),
                                item.RuleItem.ToString());

                            LinguaTrace.TraceEvent(TraceEventType.Information, LinguaTraceId.ID_GENERATE_PROCESS_CONFLICT, "{0}", conflict);

                            conflicts.Add(conflict);
                        }
                        else
                        {
                            ParserAction action = new ParserActionShift(parserStates[state.Transitions[terminal]]);

                            LinguaTrace.TraceEvent(TraceEventType.Information, LinguaTraceId.ID_GENERATE_PROCESS_ACTION, "{0}", action);

                            actions.Add(terminal, action);
                            actionRules.Add(action, item.RuleItem);
                        }
                    }
                }

                // Construct the GOTO table
                //
                Dictionary<NonterminalType, ParserState> gotos = new Dictionary<NonterminalType, ParserState>();
                foreach (KeyValuePair<LanguageElementType, GeneratorState> transition in state.Transitions)
                {
                    if (transition.Key.ElementType == LanguageElementTypes.Nonterminal)
                    {
                        NonterminalType nonterminal = (NonterminalType)transition.Key;
                        gotos.Add(nonterminal, parserStates[transition.Value]);
                    }
                }

                // Update the parser state.
                //
                ParserState parserState = parserStates[state];
                foreach (KeyValuePair<TerminalType, ParserAction> action in actions)
                {
                    parserState.Actions.Add(action.Key, action.Value);
                }

                foreach (KeyValuePair<NonterminalType, ParserState> gotoItem in gotos)
                {
                    parserState.Gotos.Add(gotoItem.Key, gotoItem.Value);
                }
            }

            Parser parser = new Parser(parserStates[states[0]]);

            ParserGeneratorResult result = new ParserGeneratorResult(parser, conflicts);
            return result;
        }