Example #1
0
 /// <summary>
 /// Gets the <see cref="ParserAction"/> associated with a <see cref="TerminalType"/> as defined by <see cref="Actions"/>.
 /// </summary>
 /// <param name="terminalType">A <see cref="TerminalType"/> object.</param>
 /// <returns>The <see cref="ParserAction"/> associated with <paramref name="terminalType"/> as defined by <see cref="Actions"/>.
 /// Returns <value>null</value> if no such <see cref="ParserAction"/> exists.</returns>
 public ParserAction GetAction(TerminalType terminalType)
 {
     ParserAction action;
     if (m_actions.TryGetValue(terminalType, out action))
     {
         return action;
     }
     return null;
 }
Example #2
0
 /// <summary>
 /// Gets all terminals defined by the <see cref="Grammar" />.
 /// </summary>
 /// <returns>An array of <see cref="TerminalType" /> that represents all terminals defined by the <see cref="Grammar" />.</returns>
 public TerminalType[] GetTerminals()
 {
     TerminalType[] terminals = new TerminalType[m_terminals.Values.Count];
     m_terminals.Values.CopyTo(terminals, 0);
     return(terminals);
 }
Example #3
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);
        }
Example #4
0
 /// <summary>
 /// Gets the <see cref="ParserAction"/> associated with a <see cref="TerminalType"/> as defined by <see cref="Actions"/>.
 /// </summary>
 /// <param name="terminalType">A <see cref="TerminalType"/> object.</param>
 /// <returns>The <see cref="ParserAction"/> associated with <paramref name="terminalType"/> as defined by <see cref="Actions"/>.
 /// Returns <value>null</value> if no such <see cref="ParserAction"/> exists.</returns>
 public ParserAction GetAction(TerminalType terminalType)
 {
     ParserAction action;
     return _actions.TryGetValue(terminalType, out action) ? action : null;
 }
Example #5
0
 /// <summary>
 /// Gets all terminals defined by the <see cref="Grammar" />.
 /// </summary>
 /// <returns>An array of <see cref="TerminalType" /> that represents all terminals defined by the <see cref="Grammar" />.</returns>
 public TerminalType[] GetTerminals()
 {
     TerminalType[] terminals = new TerminalType[m_terminals.Values.Count];
     m_terminals.Values.CopyTo(terminals, 0);
     return terminals;
 }
Example #6
0
        /// <summary>
        /// Retrieves the terminal or nonterminal definition from the specified <see cref="Type"/> and adds it to the
        /// <see cref="Grammar"/>.
        /// </summary>
        /// <param name="type">A <see cref="Type"/> containing a terminal or nonterminal definition.</param>
        /// <param name="name">The name of the grammar being loaded as defined by <see cref="GrammarAttribute"/>.  Specify <value>null</value> to load <paramref name="type"/> regardless of grammar name.</param>
        /// <returns>The <see cref="LanguageElementType"/> added to the <see cref="Grammar"/>.  If the specified <see cref="Type"/>
        /// did not represent a terminal or nonterminal definition, <value>null</value> is returned.
        /// </returns>
        public LanguageElementType Load(Type type, string name)
        {
            if (TypeIsTerminal(type, name))
            {
                TerminalType terminalType = new TerminalType(type);
                m_terminals.Add(type, terminalType);
                return terminalType;
            }

            if (TypeIsNonterminal(type, name))
            {
                NonterminalType nonterminalType = new NonterminalType(type);
                m_nonterminals.Add(type, nonterminalType);
                return nonterminalType;
            }

            return null;
        }
Example #7
0
 /// <summary>
 /// Gets all terminals defined by the <see cref="Grammar" />.
 /// </summary>
 /// <returns>An array of <see cref="TerminalType" /> that represents all terminals defined by the <see cref="Grammar" />.</returns>
 public TerminalType[] GetTerminals()
 {
     var terminals = new TerminalType[_terminals.Values.Count];
     _terminals.Values.CopyTo(terminals, 0);
     return terminals;
 }
Example #8
0
 /// <summary>
 /// Initializes a new instance of the <see cref="TerminalReader"/> class.
 /// </summary>
 /// <param name="terminalTypes">A collection of <see cref="TerminalType"/> objects recognized by the <see cref="TerminalReader"/></param>
 /// <param name="stopTerminal">The <see cref="TerminalType"/> of the stopping terminal.</param>
 public TerminalReader(IEnumerable <TerminalType> terminalTypes, TerminalType stopTerminal)
 {
     _terminalTypes.AddRange(terminalTypes);
     _stopTerminal = stopTerminal;
     _regex        = new Regex(CreatePattern());
 }
Example #9
0
 /// <summary>
 /// Initializes a new instance of the <see cref="TerminalReader"/> class.
 /// </summary>
 /// <param name="terminalTypes">A collection of <see cref="TerminalType"/> objects recognized by the <see cref="TerminalReader"/></param>
 /// <param name="stopTerminal">The <see cref="TerminalType"/> of the stopping terminal.</param>
 public TerminalReader(IEnumerable<TerminalType> terminalTypes, TerminalType stopTerminal)
 {
     _terminalTypes.AddRange(terminalTypes);
     _stopTerminal = stopTerminal;
     _regex = new Regex(CreatePattern());
 }
Example #10
0
 /// <summary>
 /// Gets the <see cref="ParserAction"/> associated with a <see cref="TerminalType"/> as defined by <see cref="Actions"/>.
 /// </summary>
 /// <param name="terminalType">A <see cref="TerminalType"/> object.</param>
 /// <returns>The <see cref="ParserAction"/> associated with <paramref name="terminalType"/> as defined by <see cref="Actions"/>.
 /// Returns <value>null</value> if no such <see cref="ParserAction"/> exists.</returns>
 public ParserAction GetAction(TerminalType terminalType)
 {
     ParserAction action;
     return _actions.TryGetValue(terminalType, out action) ? action : null;
 }