public void Init(string codeNamespace, IEnumerable<Production> productions, IEnumerable<GrammarSymbol> symbols, TransitionTable transTable) { _productions = productions; _symbols = symbols; _table = transTable; _codeNamespace = codeNamespace; }
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()); }
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(); }
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); }
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); }
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); } } } }
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; }