示例#1
0
 private Core.GrammarElements.Production GetAugmentedProduction(NonTerminal start, GrammarSymbol root, GrammarSymbol endOfStream)
 {
     return new Core.GrammarElements.Production(_productionId++,
                                                start,
                                                new[]
                                                {
                                                    root, endOfStream
                                                });
 }
示例#2
0
        private CodeTypeMember ImplementReducerGoto(NonTerminal head)
        {
            var result = new CodeMemberMethod()
            {
                Name = Constants.ReductionGotoMethodName,
                ReturnType = new CodeTypeReference(typeof(void)),
                Attributes = MemberAttributes.Public | MemberAttributes.Final

            };
            result.Parameters.Add(new CodeParameterDeclarationExpression(Constants.StateStackType, Constants.StateStackVarName));
            var states = new CodeArgumentReferenceExpression(Constants.StateStackVarName);
            result.Statements.Add(DeclareVariable(new CodeTypeReference(typeof(int)), "currentState", new CodeMethodInvokeExpression(states, "Peek")));

            foreach (var state in _transitionTable.StateMap.States)
            {
                var action = _transitionTable[state, head];
                if (action.Action == ParserAction.Goto)
                {
                    var ifState = new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("currentState"), CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(state.StateId)));
                    ifState.TrueStatements.Add(new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(states, "Push"), new CodePrimitiveExpression(action.NextState.StateId)));
                    ifState.TrueStatements.Add(new CodeMethodReturnStatement());
                    result.Statements.Add(ifState);
                }
            }
            result.Statements.Add(new CodeThrowExceptionStatement(new CodeObjectCreateExpression(typeof(Exception), new CodePrimitiveExpression("Unexpected GOTO operation."))));
            return result;
        }
示例#3
0
        public Grammar GetGrammar()
        {
            string fileContents = File.ReadAllText(_fileName);

            var tokenStream = Lexer.Run(fileContents);

            var parser = new Parser();

            var parseTree = parser.Parse(tokenStream);

            var grammarCreator = new GrammarTreeVisitor();

            parseTree.AcceptVisitor(grammarCreator);

            var isValid = ValidateGrammar(grammarCreator.Tokens, grammarCreator.Productions);

            var terminals = (from symbolName in grammarCreator.Tokens
                             select new Terminal(_symbolId++, symbolName))
                             .ToDictionary(terminal => terminal.Name);

            var nonTerminals = grammarCreator.Productions
                                .Select(production => production.ProductionHead)
                                .Distinct()
                                .Select(symbolName => new NonTerminal(_symbolId++, symbolName))
                                .ToDictionary(nonTerminal => nonTerminal.Name);

            var productions = new List<Core.GrammarElements.Production>();

            foreach (var nonTerminal in nonTerminals.Keys)
            {
                foreach (var production in grammarCreator.Productions.Where(x => x.ProductionHead == nonTerminal))
                {
                    var tail = new GrammarSymbol[production.ProductionTail.Count];
                    for (int i = 0; i < tail.Length; i++)
                    {
                        var productionToken = production.ProductionTail[i];
                        if (terminals.ContainsKey(productionToken))
                        {
                            tail[i] = terminals[productionToken];
                        }
                        else if(nonTerminals.ContainsKey(productionToken))
                        {
                            tail[i] = nonTerminals[productionToken];
                        }
                        else
                        {
                            throw new Exception("Unknown production head.");
                        }
                    }
                    productions.Add(new Core.GrammarElements.Production(_productionId++, nonTerminals[nonTerminal], tail));
                }
            }

            var endOfStream = EndOfStream.Instance;
            terminals.Add(endOfStream.Name, endOfStream);

            var startAugmentedSymbol = new NonTerminal(_symbolId++, AugmentedStart);
            nonTerminals.Add(AugmentedStart, startAugmentedSymbol);

            var root = GetGrammarRoot(productions);
            var augmentedProduction = GetAugmentedProduction(startAugmentedSymbol, root, endOfStream);

            productions.Add(augmentedProduction);

            return new Grammar(productions, terminals.Values.Cast<GrammarSymbol>().Concat(nonTerminals.Values).ToList(), new Item(augmentedProduction));
        }
示例#4
0
 private void AddSymbol(NonTerminal head, IEnumerable<Production> productions)
 {
     var nonTermAbstractBase = new CodeTypeDeclaration(head.Name);
     nonTermAbstractBase.BaseTypes.Add(new CodeTypeReference(Constants.ReductionInterfaceName));
     nonTermAbstractBase.TypeAttributes = TypeAttributes.Abstract | TypeAttributes.Public;
     nonTermAbstractBase.Members.Add(ImplementReducerGoto(head));
     var concreteTypes = GetConcreteTypesForProductions(nonTermAbstractBase, productions);
     _codeNamespace.Types.Add(nonTermAbstractBase);
     _codeNamespace.Types.AddRange(concreteTypes.ToArray());
 }