コード例 #1
0
ファイル: ParserCodeGenBase.cs プロジェクト: mattchamb/MParse
 public void Init(string codeNamespace, IEnumerable<Production> productions, IEnumerable<GrammarSymbol> symbols, TransitionTable transTable)
 {
     _productions = productions;
     _symbols = symbols;
     _table = transTable;
     _codeNamespace = codeNamespace;
 }
コード例 #2
0
ファイル: MParseFront.cs プロジェクト: mattchamb/MParse
 private static void CreateClasses(IEnumerable<Production> productions, IEnumerable<GrammarSymbol> symbols, TransitionTable tt)
 {
     //var parserBuilder = new ParserBuilder("TestNamespace", productions, symbols, tt);
     //var s = parserBuilder.GetCode(new CSharpCodeProvider(), new CodeGeneratorOptions());
     var pt = new ParserTemplate();
     pt.Init("GrammarParser", productions, symbols, tt);
     File.WriteAllText("grammargrammar.cs", pt.TransformText());
 }
コード例 #3
0
 public string GenerateOutput(TransitionTable transitionTable)
 {
     var builder = new StringBuilder();
     builder.AppendLine("digraph G {");
     builder.AppendLine("node[shape=box];");
     WriteTransitions(builder, transitionTable);
     builder.AppendLine("}");
     return builder.ToString();
 }
コード例 #4
0
ファイル: MParseFront.cs プロジェクト: mattchamb/MParse
        static void Main(string[] args)
        {
            //IGrammarProvider grammarProvider = new GGrammarProvider();
            IGrammarProvider grammarProvider = new FileProvider.FileGrammarProvider(@"..\..\..\MParse.GrammarProviders\FileProvider\grammar.gm");
            var grammar = grammarProvider.GetGrammar();

            var dotOutputGenerator = new DotOutputGenerator();

            var table = new TransitionTable(grammar);

            CreateClasses(grammar.Productions, grammar.Symbols, table);
        }
コード例 #5
0
ファイル: ParserBuilder.cs プロジェクト: mattchamb/MParse
        public ParserBuilder(string codeNamespace, IEnumerable<Production> productions, IEnumerable<GrammarSymbol> symbols, TransitionTable transTable)
        {
            _compileUnit = new CodeCompileUnit();
            _codeNamespace = new CodeNamespace(codeNamespace);
            _codeNamespace.Imports.Add(new CodeNamespaceImport("System"));
            _codeNamespace.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
            _compileUnit.Namespaces.Add(_codeNamespace);
            _productions = productions;
            _symbols = symbols;
            _transitionTable = transTable;

            _terminalBase = new CodeTypeDeclaration(Constants.TerminalBaseClassName)
            {
                TypeAttributes = TypeAttributes.Abstract | TypeAttributes.Public,
            };
            _terminalBase.Members.Add(GetAbstractActionMethod());
            _codeNamespace.Types.Add(_terminalBase);
            _codeNamespace.Types.Add(GetActionResultEnum());
            _codeNamespace.Types.Add(GetIReducerInterface());

            AddTerminalTextProperty(_terminalBase);
            AddTerminalToStringMethod(_terminalBase);

            foreach (var symbol in symbols)
            {
                if (symbol is Terminal)
                {
                    AddSymbol(symbol as Terminal);
                }
                else
                {
                    AddSymbol(symbol as NonTerminal, productions.Where(x => x.Head.Name == symbol.Name));
                }
            }
            var parserMethod = AddParserClass("Parser", productions.First().Head.Name);

            AddParserFunctionBody(parserMethod);
        }
コード例 #6
0
 private void WriteTransitions(StringBuilder output, TransitionTable table)
 {
     var visited = table.StateMap.States.ToDictionary(state => state, state => false);
     var plan = new Queue<ParserState>();
     plan.Enqueue(table.StateMap.States.First());
     while (plan.Count > 0)
     {
         var currState = plan.Dequeue();
         visited[currState] = true;
         if (table.StateMap.FromStateExists(currState))
         {
             foreach (var stateTransition in table.StateMap[currState])
             {
                 output.AppendFormat("\"{0}\" -> \"{1}\" [label=\"{2}\"];",
                                     StateToDotString(currState),
                                     StateToDotString(stateTransition.Value),
                                     stateTransition.Key);
                 output.AppendLine();
                 if (!visited[stateTransition.Value] && !plan.Contains(stateTransition.Value))
                     plan.Enqueue(stateTransition.Value);
             }
         }
     }
 }
コード例 #7
0
ファイル: ParserBuilder.cs プロジェクト: mattchamb/MParse
        private CodeMemberMethod GetOverrideActionMethod(GrammarSymbol currToken, TransitionTable table)
        {
            var result = new CodeMemberMethod
            {
                Name = Constants.TerminalActionMethodName,
                Attributes = MemberAttributes.Public | MemberAttributes.Override,
                ReturnType = new CodeTypeReference(Constants.ActionEnumName)
            };
            result.Parameters.Add(new CodeParameterDeclarationExpression(Constants.StateStackType, Constants.StateStackVarName));
            result.Parameters.Add(new CodeParameterDeclarationExpression(Constants.ParseStackType, Constants.ParseStackVarName));

            var states = new CodeArgumentReferenceExpression(Constants.StateStackVarName);
            var parseStack = new CodeArgumentReferenceExpression(Constants.ParseStackVarName);

            result.Statements.Add(new CodeVariableDeclarationStatement(new CodeTypeReference(typeof(int)), "currentState", new CodeMethodInvokeExpression(states, "Peek")));

            foreach (var state in table.StateMap.States)
            {
                var ifState = new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("currentState"), CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(state.StateId)));
                var action = table[state, currToken];
                if (action.Action == ParserAction.Shift)
                {
                    ifState.TrueStatements.Add(new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(states, "Push"), new CodePrimitiveExpression(action.NextState.StateId)));
                    ifState.TrueStatements.Add(new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(parseStack, "Push"), new CodeThisReferenceExpression()));
                    ifState.TrueStatements.Add(new CodeMethodReturnStatement(FieldReference(new CodeTypeReferenceExpression(Constants.ActionEnumName), "ShiftContinue")));
                }
                if (action.Action == ParserAction.Reduce)
                {
                    ifState.TrueStatements.Add(new CodeMethodInvokeExpression(parseStack, "Push", new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(GetClassName(action.ReduceByProduction)), Constants.ReduceByMethodName), parseStack)));
                    for (int i = 0; i < action.ReduceByProduction.Length; i++)
                    {
                        ifState.TrueStatements.Add(new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(states, "Pop")));
                    }
                    ifState.TrueStatements.Add(new CodeMethodReturnStatement(FieldReference(new CodeTypeReferenceExpression(Constants.ActionEnumName), "ReduceContinue")));
                }
                if (action.Action == ParserAction.Accept)
                {
                    ifState.TrueStatements.Add(new CodeMethodReturnStatement(FieldReference(new CodeTypeReferenceExpression(Constants.ActionEnumName), "Accept")));
                }
                if (action.Action == ParserAction.Error)
                {
                    ifState.TrueStatements.Add(new CodeMethodReturnStatement(FieldReference(new CodeTypeReferenceExpression(Constants.ActionEnumName), "Error")));
                }
                result.Statements.Add(ifState);
            }
            result.Statements.Add(new CodeMethodReturnStatement(FieldReference(new CodeTypeReferenceExpression(Constants.ActionEnumName), "Error")));
            return result;
        }