private static void DumpSyntaxParserCode( RegulationList grammar, LRParsingMap map, string grammarId, string LR0Directory, SyntaxParserMapAlgorithm algorithm) { var parserType = new CodeTypeDeclaration(GetParserName(grammarId, algorithm)); parserType.IsClass = true; parserType.BaseTypes.Add(typeof(LRSyntaxParser)); DumpSyntaxParserFields(grammar, parserType, grammarId, algorithm); DumpSyntaxParserMethod_GetGrammar(grammar, parserType); DumpSyntaxParserMethod_GetParsingMap(grammar, map, parserType); var parserNamespace = new CodeNamespace(GetNamespace(grammarId)); parserNamespace.Imports.Add(new CodeNamespaceImport(typeof(System.Object).Namespace)); parserNamespace.Imports.Add(new CodeNamespaceImport(typeof(System.Collections.Generic.List <int>).Namespace)); parserNamespace.Imports.Add(new CodeNamespaceImport(typeof(LALR1Compiler.HashCache).Namespace)); parserNamespace.Types.Add(parserType); //生成代码 string parserCodeFullname = Path.Combine(LR0Directory, GetParserName(grammarId, algorithm) + ".cs"); using (var stream = new StreamWriter(parserCodeFullname, false)) { CSharpCodeProvider codeProvider = new CSharpCodeProvider(); CodeGeneratorOptions geneOptions = new CodeGeneratorOptions();//代码生成选项 geneOptions.BlankLinesBetweenMembers = true; geneOptions.BracingStyle = "C"; geneOptions.ElseOnClosing = false; geneOptions.IndentString = " "; geneOptions.VerbatimOrder = true; codeProvider.GenerateCodeFromNamespace(parserNamespace, stream, geneOptions); } }
private static RegulationList GetProductionList(SyntaxTree syntaxTree) { RegulationList result = null; // <ProductionList> ::= <Production> <RegulationList> | null ; if (syntaxTree.NodeType.Type == ContextfreeGrammarTreeNodeType.__ProductionList) { if (syntaxTree.Children.Count == 2) { // <ProductionList> ::= <Production> <RegulationList> ; List <Regulation> production = GetProduction(syntaxTree.Children[0]); RegulationList regulationList = GetProductionList(syntaxTree.Children[1]); result = new RegulationList(); result.AddRange(production); result.AddRange(regulationList); } else if (syntaxTree.Children.Count == 0) { // <ProductionList> ::= null ; result = new RegulationList(); } } return(result); }
private static void DumpLexicalAnalyzer_GetKeywordList( RegulationList grammar, string grammarId, CodeTypeDeclaration lexiType) { { // private static readonly List<Keyword> keywords = new List<Keyword>(); var field = new CodeMemberField(typeof(List <Keyword>), "keywords"); field.Attributes = MemberAttributes.Private | MemberAttributes.Static; field.InitExpression = new CodeObjectCreateExpression(typeof(List <Keyword>)); lexiType.Members.Add(field); } { // protected override IEnumerable<Keyword> GetKeywords() var method = new CodeMemberMethod(); method.Name = "GetKeywords"; method.Attributes = MemberAttributes.Public | MemberAttributes.Override; method.ReturnType = new CodeTypeReference(typeof(IEnumerable <Keyword>)); var returnKeywords = new CodeMethodReturnStatement( new CodeVariableReferenceExpression("keywords")); method.Statements.Add(returnKeywords); lexiType.Members.Add(method); } { // static DemoLexicalAnalyzer() var method = new CodeTypeConstructor(); method.Name = GetLexicalAnalyzerName(grammarId); method.Attributes = MemberAttributes.Static; //{ // // List<Keyword> keyword = new List<Keyword>(); // var keyword = new CodeVariableDeclarationStatement("List<Keyword>", "keyword"); // keyword.InitExpression = new CodeObjectCreateExpression("List<Keyword>"); // method.Statements.Add(keyword); //} var convertor = new TreeNodeType2TokenType(); foreach (var node in grammar.GetAllTreeNodeLeaveTypes()) { // keywords.Add(new Keyword("__x", "x")); if (node.IsIdentifier()) { TokenType tokenType = convertor.GetTokenType(node); var ctor = new CodeObjectCreateExpression(typeof(Keyword), new CodePrimitiveExpression(tokenType.Type), new CodePrimitiveExpression(tokenType.Content)); var add = new CodeMethodInvokeExpression( new CodeVariableReferenceExpression("keywords"), "Add", ctor); method.Statements.Add(add); } } //{ // // DemoLexicalAnalyzer.keywords = keywords; // var assign = new CodeAssignStatement( // new CodeFieldReferenceExpression( // new CodeSnippetExpression(GetLexicalAnalyzerName(grammarId)), "keywords"), // new CodeVariableReferenceExpression("keywords")); // method.Statements.Add(assign); //} lexiType.Members.Add(method); } }
/// <summary> /// 为生成词法分析器,获取该文法的所有词法状态。 /// </summary> /// <param name="grammar"></param> /// <returns></returns> static List <LexiState> GetLexiStateList(this RegulationList grammar) { var result = new List <LexiState>(); List <TreeNodeType> nodeList = grammar.GetAllTreeNodeLeaveTypes(); foreach (var node in nodeList) { if (node.Type == "identifierLeave__")// ContextfreeGrammar的关键字 { TryInsertGetIdentifier(result); } else if (node.Type == "numberLeave__")// ContextfreeGrammar的关键字 { TryInsertGetNumber(result); } else if (node.Type == "constStringLeave__")// ContextfreeGrammar的关键字 { TryInserteGetConstString(result); } else if (node.Type == "charLeave__")// ContextfreeGrammar的关键字(暂未支持) { TryInserteGetChar(result); } else { CodeGetRegularToken(result, node); } } return(result); }
private static void DumpTreeNodeTypeConstCode( RegulationList grammar, LRParsingMap map, string grammarId, string LR0Directory, SyntaxParserMapAlgorithm algorithm) { var treeNodeConstType = new CodeTypeDeclaration(GetTreeNodeConstTypeName(grammarId, algorithm)); treeNodeConstType.IsClass = true; DumpTreeNodeConstFields(grammar, treeNodeConstType); var parserNamespace = new CodeNamespace(GetNamespace(grammarId)); parserNamespace.Imports.Add(new CodeNamespaceImport(typeof(System.Object).Namespace)); parserNamespace.Types.Add(treeNodeConstType); //生成代码 string fullname = Path.Combine(LR0Directory, GetTreeNodeConstTypeName(grammarId, algorithm) + ".cs"); using (var stream = new StreamWriter(fullname, false)) { CSharpCodeProvider codeProvider = new CSharpCodeProvider(); CodeGeneratorOptions geneOptions = new CodeGeneratorOptions();//代码生成选项 geneOptions.BlankLinesBetweenMembers = true; geneOptions.BracingStyle = "C"; geneOptions.ElseOnClosing = false; geneOptions.IndentString = " "; geneOptions.VerbatimOrder = true; codeProvider.GenerateCodeFromNamespace(parserNamespace, stream, geneOptions); } }
private static void DumpLexicalAnalyzerCode(RegulationList grammar, string grammarId, SyntaxParserMapAlgorithm algorithm, string directory) { var lexiType = new CodeTypeDeclaration(GetLexicalAnalyzerName(grammarId)); lexiType.IsClass = true; lexiType.IsPartial = true; lexiType.BaseTypes.Add(typeof(LexicalAnalyzer)); DumpLexicalAnalyzer_TryGetToken(grammar, lexiType); DumpLexicalAnalyzer_GetSymbol(grammar, lexiType, grammarId, algorithm); DumpLexicalAnalyzer_GetKeywordList(grammar, grammarId, lexiType); var lexiNamespace = new CodeNamespace(GetNamespace(grammarId)); lexiNamespace.Imports.Add(new CodeNamespaceImport(typeof(System.Object).Namespace)); lexiNamespace.Imports.Add(new CodeNamespaceImport(typeof(System.Collections.Generic.List <int>).Namespace)); lexiNamespace.Imports.Add(new CodeNamespaceImport(typeof(LALR1Compiler.HashCache).Namespace)); lexiNamespace.Types.Add(lexiType); //生成代码 string parserCodeFullname = Path.Combine(directory, GetLexicalAnalyzerName(grammarId) + ".cs"); using (var stream = new StreamWriter(parserCodeFullname, false)) { CSharpCodeProvider codeProvider = new CSharpCodeProvider(); CodeGeneratorOptions geneOptions = new CodeGeneratorOptions();//代码生成选项 geneOptions.BlankLinesBetweenMembers = true; geneOptions.BracingStyle = "C"; geneOptions.ElseOnClosing = false; geneOptions.IndentString = " "; geneOptions.VerbatimOrder = true; codeProvider.GenerateCodeFromNamespace(lexiNamespace, stream, geneOptions); } }
private static void DumpLexicalAnalyzer_GetSymbol( RegulationList grammar, CodeTypeDeclaration lexiType, string grammarId, SyntaxParserMapAlgorithm algorithm) { List <LexiState> lexiStateList = grammar.GetLexiStateList(); DivideState commentState = null;// 为了处理注释,"/"符号要特殊对待。 foreach (var state in lexiStateList) { if (state.CharTypeList.Contains(SourceCodeCharType.Divide)) { commentState = new DivideState(state); continue; } CodeMemberMethod method = state.GetMethodDefinitionStatement(grammarId, algorithm); if (method != null) { lexiType.Members.Add(method); } } { if (commentState == null) { commentState = LexiState.GetCommentState(); } CodeMemberMethod method = commentState.GetMethodDefinitionStatement(grammarId, algorithm); if (method != null) { lexiType.Members.Add(method); } } }
private static void DumpLexicalAnalyzer_TryGetToken( RegulationList grammar, CodeTypeDeclaration lexiType) { var method = new CodeMemberMethod(); method.Name = "TryGetToken"; method.Attributes = MemberAttributes.Family | MemberAttributes.Override; method.ReturnType = new CodeTypeReference(typeof(bool)); method.Parameters.Add(new CodeParameterDeclarationExpression("AnalyzingContext", "context")); method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(Token), "result")); method.Parameters.Add(new CodeParameterDeclarationExpression("SourceCodeCharType", "charType")); { // bool gotToken = false; string vargotToken = "gotToken"; // :( var varDeclaration = new CodeVariableDeclarationStatement(typeof(bool), vargotToken); varDeclaration.InitExpression = new CodePrimitiveExpression(false); method.Statements.Add(varDeclaration); } { List <LexiState> lexiStateList = grammar.GetLexiStateList(); DivideState commentState = null;// 为了处理注释,"/"符号要特殊对待。 foreach (var state in lexiStateList) { if (state.CharTypeList.Contains(SourceCodeCharType.Divide)) { commentState = new DivideState(state); continue; } var condition = new CodeConditionStatement( state.GetCondition(), state.GetMethodInvokeStatement()); method.Statements.Add(condition); } { if (commentState == null) { commentState = LexiState.GetCommentState(); } var condition = new CodeConditionStatement( commentState.GetCondition(), commentState.GetMethodInvokeStatement()); method.Statements.Add(condition); } { var getSpaceState = LexiState.GetSpaceState(); var condition = new CodeConditionStatement( getSpaceState.GetCondition(), getSpaceState.GetMethodInvokeStatement()); method.Statements.Add(condition); } { var getUnknownState = LexiState.GetUnknownState(); var lastCondition = getUnknownState.GetMethodInvokeStatement(); method.Statements.AddRange(lastCondition); } } lexiType.Members.Add(method); }
private static string GetLack(RegulationList grammar, out bool error) { StringBuilder builder = new StringBuilder(); List <TreeNodeType> lackList = new List <TreeNodeType>(); var nonLeaveNodeList = grammar.GetAllTreeNodeNonLeaveTypes(); foreach (var regulation in grammar) { foreach (var node in regulation.RightPart) { if ((!node.IsLeave) && (!nonLeaveNodeList.Contains(node)) && (!lackList.Contains(node))) { lackList.Add(node); } } } builder.AppendLine("===================================================================="); builder.AppendLine(string.Format("Lack of [{0}] regulation's definitions:", lackList.Count)); foreach (var item in lackList) { builder.AppendLine(string.Format("{0}", item.Dump())); } error = lackList.Count > 0; return(builder.ToString()); }
/// <summary> /// ContextfreeGrammar compiler的工作过程。 /// </summary> /// <param name="sourceCode"></param> /// <param name="directory"></param> /// <param name="grammarId"></param> /// <returns></returns> private static bool GetGrammar(string sourceCode, string directory, string grammarId, out RegulationList grammar, out string errorInfo) { grammar = null; errorInfo = string.Empty; Console.WriteLine(" Get grammar from source code..."); var lexi = new ContextfreeGrammarLexicalAnalyzer(); TokenList tokenList = lexi.Analyze(sourceCode); if (!tokenList.Check(out errorInfo)) { return(false); } Console.WriteLine(" Dump {0}", grammarId + ".TokenList.log"); tokenList.Dump(Path.Combine(directory, grammarId + ".TokenList.log")); var parser = new ContextfreeGrammarSyntaxParser(); SyntaxTree tree = parser.Parse(tokenList); Console.WriteLine(" Dump {0}", grammarId + ".Tree.log"); tree.Dump(Path.Combine(directory, grammarId + ".Tree.log")); grammar = tree.DumpGrammar(); Console.WriteLine(" Dump {0}", grammarId + ".FormatedGrammar.log"); grammar.Dump(Path.Combine(directory, grammarId + ".FormatedGrammar.log")); return(true); }
private static string GetUnused(RegulationList grammar, out bool error) { StringBuilder builder = new StringBuilder(); List <TreeNodeType> usedList = new List <TreeNodeType>(); usedList.Add(grammar[0].Left); bool changed = false; int index = 0; do { changed = false; int count = usedList.Count; for (; index < count; index++) { TreeNodeType node = usedList[index]; foreach (var regulation in grammar) { if (regulation.Left == node) { foreach (var item in regulation.RightPart) { if ((!item.IsLeave) && (!usedList.Contains(item))) { usedList.Add(item); changed = true; } } } } } } while (changed); List <TreeNodeType> unusedList = new List <TreeNodeType>(); List <TreeNodeType> allNonLeaveNodeList = grammar.GetAllTreeNodeNonLeaveTypes(); foreach (var node in allNonLeaveNodeList) { if (!usedList.Contains(node)) { unusedList.Add(node); } } builder.AppendLine("===================================================================="); builder.AppendLine(string.Format("{0} unused nodes:", unusedList.Count)); foreach (var item in unusedList) { builder.AppendLine(item.Dump()); } error = unusedList.Count > 0; return(builder.ToString()); }
private static void DumpTreeNodeConstFields(RegulationList grammar, CodeTypeDeclaration treeNodeConstType) { // public const string __Grammar = "__Grammar"; // public const string __colon_colon_equalLeave__ = "__colon_colon_equalLeave__"; foreach (var node in grammar.GetAllTreeNodeTypes()) { var field = new CodeMemberField(typeof(string), GetNodeNameInParser(node)); field.Attributes = MemberAttributes.Public | MemberAttributes.Const; field.InitExpression = new CodePrimitiveExpression(node.Type); treeNodeConstType.Members.Add(field); } }
/// <summary> /// 检测文法是否有什么直接要修改的问题。 /// </summary> /// <param name="grammar"></param> /// <returns></returns> public static bool SemanticCheck(this RegulationList grammar, out string errorInfo) { bool error = false; StringBuilder builder = new StringBuilder(); { bool innerError = false; // 重复的推导式 string reduplicative = Getduplication(grammar, out innerError); if (innerError) { builder.AppendLine(reduplicative); error = true; } } { bool innerError = false; // 某些非叶结点没有定义其产生式 string lack = GetLack(grammar, out innerError); if (innerError) { builder.AppendLine(lack); error = true; } } { bool innerError = false; // 某些非产生式没有被用到 string lack = GetUnused(grammar, out innerError); if (innerError) { builder.AppendLine(lack); error = true; } } { bool innerError = false; // constString里的内容也不是随便什么都可以 string lack = CheckConstStrings(grammar, out innerError); if (innerError) { builder.AppendLine(lack); error = true; } } errorInfo = builder.ToString(); return(!error); }
private static void DumpTokenTypeConstFields(RegulationList grammar, CodeTypeDeclaration tokenTypeConstType) { // public const string __colon_colon_equal = "__colon_colon_equal"; var convertor = new TreeNodeType2TokenType(); foreach (var node in grammar.GetAllTreeNodeLeaveTypes()) { var field = new CodeMemberField(typeof(string), GetNodeNameInParser(node)); field.Attributes = MemberAttributes.Public | MemberAttributes.Const; TokenType tokenType = convertor.GetTokenType(node); field.InitExpression = new CodePrimitiveExpression(tokenType.Type); tokenTypeConstType.Members.Add(field); } }
/// <summary> /// 遍历语法树,导出其中描述的文法。 /// </summary> /// <returns></returns> public static RegulationList DumpGrammar(this SyntaxTree syntaxTree) { RegulationList grammar = new RegulationList(); // <Grammar> ::= <Production> <ProductionList> ; if (syntaxTree.NodeType.Type == ContextfreeGrammarTreeNodeType.__Grammar) { List <Regulation> production = GetProduction(syntaxTree.Children[0]); grammar.AddRange(production); RegulationList regulationList = GetProductionList(syntaxTree.Children[1]); grammar.AddRange(regulationList); } return(grammar); }
private static void DumpSyntaxParserFields(RegulationList grammar, CodeTypeDeclaration parserType, string grammarId, SyntaxParserMapAlgorithm algorithm) { { // protected static LRParsingMap parsingMap; CodeMemberField field = new CodeMemberField(typeof(LRParsingMap), "parsingMap"); field.Attributes = MemberAttributes.Private | MemberAttributes.Static; parserType.Members.Add(field); } { // protected static RegulationList grammar; CodeMemberField field = new CodeMemberField(typeof(RegulationList), "grammar"); field.Attributes = MemberAttributes.Private | MemberAttributes.Static; parserType.Members.Add(field); } foreach (var node in grammar.GetAllTreeNodeTypes()) { //var field = new CodeSnippetTypeMember(string.Format( // " public static readonly {0} {1} = new {0}(\"{2}\", \"{3}\", \"{4}\");", // typeof(TreeNodeType).Name, GetNodeNameInParser(node), // node.Type, node.Content, node.Nickname)); //parserType.Members.Add(field); // private static TreeNodeType NODE__Grammar = new TreeNodeType(ContextfreeGrammarSLRTreeNodeType.NODE__Grammar, "Grammar", "<Grammar>"); CodeMemberField field = new CodeMemberField(typeof(TreeNodeType), GetNodeNameInParser(node)); // field.Attributes 不支持readonly,遗憾了。 field.Attributes = MemberAttributes.Private | MemberAttributes.Static; var ctor = new CodeObjectCreateExpression(typeof(TreeNodeType), new CodeFieldReferenceExpression( new CodeTypeReferenceExpression(GetTreeNodeConstTypeName(grammarId, algorithm)), GetNodeNameInParser(node)), new CodePrimitiveExpression(node.Content), new CodePrimitiveExpression(node.Nickname)); field.InitExpression = ctor; parserType.Members.Add(field); } { // private static readonly TreeNodeType end_of_token_listLeave__ = TreeNodeType.endOfTokenListNode; var node = TreeNodeType.endOfTokenListNode; CodeMemberField field = new CodeMemberField(typeof(TreeNodeType), GetNodeNameInParser(node)); field.Attributes = MemberAttributes.Private | MemberAttributes.Static; field.InitExpression = new CodeFieldReferenceExpression( new CodeTypeReferenceExpression(typeof(TreeNodeType)), "endOfTokenListNode"); parserType.Members.Add(field); } }
private static string Getduplication(RegulationList grammar, out bool error) { StringBuilder builder = new StringBuilder(); var duplications = (from a in grammar join b in grammar on a equals b where grammar.IndexOf(a) != grammar.IndexOf(b) select new { a, b }).ToList(); builder.AppendLine("===================================================================="); builder.AppendLine(string.Format("[{0}] duplicated regulation couples:", duplications.Count)); foreach (var item in duplications) { builder.AppendLine(string.Format("{0}: duplicated at index {1} and {2}", item.a, grammar.IndexOf(item.a), grammar.IndexOf(item.b))); } error = duplications.Count > 0; return(builder.ToString()); }
protected override RegulationList GetGrammar() { if (grammar != null) { return(grammar); } var list = new RegulationList(); // <Grammar> ::= <Production> <ProductionList> ; list.Add(new Regulation(__Grammar, __Production, __ProductionList)); // <ProductionList> ::= <Production> <RegulationList> | null ; list.Add(new Regulation(__ProductionList, __Production, __ProductionList)); list.Add(new Regulation(__ProductionList)); // <Production> ::= <Vn> "::=" <Canditate> <RightPartList> ";" ; list.Add(new Regulation(__Production, __Vn, __colon_colon_equalLeave__, __Canditate, __RightPartList, __semicolonLeave__)); // <Canditate> ::= <V> <VList> ; list.Add(new Regulation(__Canditate, __V, __VList)); // <VList> ::= <V> <VList> | null ; list.Add(new Regulation(__VList, __V, __VList)); list.Add(new Regulation(__VList)); // <RightPartList> ::= "|" <Canditate> <RightPartList> | null ; list.Add(new Regulation(__RightPartList, __vertical_barLeave__, __Canditate, __RightPartList)); list.Add(new Regulation(__RightPartList)); // <V> ::= <Vn> | <Vt> ; list.Add(new Regulation(__V, __Vn)); list.Add(new Regulation(__V, __Vt)); // <Vn> ::= "<" identifier ">" ; list.Add(new Regulation(__Vn, __left_angleLeave__, identifierLeave__, __right_angleLeave__)); // <Vt> ::= "null" | "identifier" | "number" | "constString" | constString ; list.Add(new Regulation(__Vt, __nullLeave__)); list.Add(new Regulation(__Vt, __identifierLeave__)); list.Add(new Regulation(__Vt, __numberLeave__)); list.Add(new Regulation(__Vt, __constStringLeave__)); list.Add(new Regulation(__Vt, constStringLeave__)); grammar = list; return(grammar); }
private static string CheckConstStrings(RegulationList grammar, out bool error) { error = false; StringBuilder builder = new StringBuilder(); foreach (var node in grammar.GetAllTreeNodeLeaveTypes()) { if (contextfreeGrammarKeywordList.Contains(node.Nickname)) { continue; } bool innderError = false; string lack = CheckNode(node, out innderError); builder.Append(innderError); if (innderError) { error = true; } } return(builder.ToString()); }
/// <summary> /// 生成给定文法的compiler。 /// </summary> /// <param name="grammar"></param> /// <param name="directory"></param> /// <param name="grammarId"></param> private static void DumpCode(RegulationList grammar, string directory, string grammarId) { { Dictionary <TreeNodeType, bool> nullableDict; grammar.GetNullableDict(out nullableDict); FIRSTCollection firstCollection; grammar.GetFirstCollection(out firstCollection, nullableDict); Console.WriteLine(" Dump {0}", grammarId + ".FIRST.log"); using (StreamWriter stream = new StreamWriter( Path.Combine(directory, grammarId + ".FIRST.log"))) { firstCollection.Dump(stream); } FOLLOWCollection followCollection; grammar.GetFollowCollection(out followCollection, nullableDict, firstCollection); Console.WriteLine(" Dump {0}", grammarId + ".FOLLOW.log"); using (StreamWriter stream = new StreamWriter( Path.Combine(directory, grammarId + ".FOLLOW.log"))) { followCollection.Dump(stream); } } { Console.WriteLine(" LR(0) parsing..."); LR0StateCollection stateCollection; LR0EdgeCollection edgeCollection; LRParsingMap parsingMap; grammar.GetLR0ParsingMap( out parsingMap, out stateCollection, out edgeCollection, Program.consoleOriginalOut); string LR0Directory = Path.Combine(directory, "LR(0)"); if (!Directory.Exists(LR0Directory)) { Directory.CreateDirectory(LR0Directory); } Console.WriteLine(" Dump {0}", grammarId + ".State.log"); using (StreamWriter stream = new StreamWriter( Path.Combine(LR0Directory, grammarId + ".State.log"))) { stateCollection.Dump(stream); } Console.WriteLine(" Dump {0}", grammarId + ".Edge.log"); using (StreamWriter stream = new StreamWriter( Path.Combine(LR0Directory, grammarId + ".Edge.log"))) { edgeCollection.Dump(stream); } Console.WriteLine(" Dump LR(0) Compiler's source code..."); DumpTreeNodeTypeConstCode(grammar, parsingMap, grammarId, LR0Directory, SyntaxParserMapAlgorithm.LR0); DumpTokenTypeConstCode(grammar, parsingMap, grammarId, LR0Directory, SyntaxParserMapAlgorithm.LR0); DumpSyntaxParserCode(grammar, parsingMap, grammarId, LR0Directory, SyntaxParserMapAlgorithm.LR0); DumpLexicalAnalyzerCode(grammar, grammarId, SyntaxParserMapAlgorithm.LR0, LR0Directory); TestParsingMap(LR0Directory, parsingMap); } { Console.WriteLine(" SLR parsing..."); LRParsingMap parsingMap; LR0StateCollection stateCollection; LR0EdgeCollection edgeCollection; grammar.GetSLRParsingMap( out parsingMap, out stateCollection, out edgeCollection, Program.consoleOriginalOut); string SLRDirectory = Path.Combine(directory, "SLR"); if (!Directory.Exists(SLRDirectory)) { Directory.CreateDirectory(SLRDirectory); } Console.WriteLine(" Dump {0}", grammarId + ".State.log"); using (StreamWriter stream = new StreamWriter( Path.Combine(SLRDirectory, grammarId + ".State.log"))) { stateCollection.Dump(stream); } Console.WriteLine(" Dump {0}", grammarId + ".Edge.log"); using (StreamWriter stream = new StreamWriter( Path.Combine(SLRDirectory, grammarId + ".Edge.log"))) { edgeCollection.Dump(stream); } Console.WriteLine(" Dump SLR Compiler's source code..."); DumpTreeNodeTypeConstCode(grammar, parsingMap, grammarId, SLRDirectory, SyntaxParserMapAlgorithm.SLR); DumpTokenTypeConstCode(grammar, parsingMap, grammarId, SLRDirectory, SyntaxParserMapAlgorithm.SLR); DumpSyntaxParserCode(grammar, parsingMap, grammarId, SLRDirectory, SyntaxParserMapAlgorithm.SLR); DumpLexicalAnalyzerCode(grammar, grammarId, SyntaxParserMapAlgorithm.SLR, SLRDirectory); TestParsingMap(SLRDirectory, parsingMap); } { Console.WriteLine(" LALR(1) parsing..."); LRParsingMap parsingMap; LALR1StateCollection stateCollection; LALR1EdgeCollection edgeCollection; grammar.GetLALR1ParsingMap( out parsingMap, out stateCollection, out edgeCollection, Program.consoleOriginalOut); string LALR1Directory = Path.Combine(directory, "LALR(1)"); if (!Directory.Exists(LALR1Directory)) { Directory.CreateDirectory(LALR1Directory); } Console.WriteLine(" Dump {0}", grammarId + ".State.log"); using (StreamWriter stream = new StreamWriter( Path.Combine(LALR1Directory, grammarId + ".State.log"))) { stateCollection.Dump(stream); } Console.WriteLine(" Dump {0}", grammarId + ".Edge.log"); using (StreamWriter stream = new StreamWriter( Path.Combine(LALR1Directory, grammarId + ".Edge.log"))) { edgeCollection.Dump(stream); } Console.WriteLine(" Dump LALR(1) Compiler's source code..."); DumpTreeNodeTypeConstCode(grammar, parsingMap, grammarId, LALR1Directory, SyntaxParserMapAlgorithm.LALR1); DumpTokenTypeConstCode(grammar, parsingMap, grammarId, LALR1Directory, SyntaxParserMapAlgorithm.LALR1); DumpSyntaxParserCode(grammar, parsingMap, grammarId, LALR1Directory, SyntaxParserMapAlgorithm.LALR1); DumpLexicalAnalyzerCode(grammar, grammarId, SyntaxParserMapAlgorithm.LALR1, LALR1Directory); TestParsingMap(LALR1Directory, parsingMap); } { Console.WriteLine(" LR(1) parsing..."); LRParsingMap parsingMap; LR1StateCollection stateCollection; LR1EdgeCollection edgeCollection; grammar.GetLR1ParsingMap( out parsingMap, out stateCollection, out edgeCollection, Program.consoleOriginalOut); string LR1Directory = Path.Combine(directory, "LR(1)"); if (!Directory.Exists(LR1Directory)) { Directory.CreateDirectory(LR1Directory); } Console.WriteLine(" Dump {0}", grammarId + ".State.log"); using (StreamWriter stream = new StreamWriter( Path.Combine(LR1Directory, grammarId + ".State.log"))) { stateCollection.Dump(stream); } Console.WriteLine(" Dump {0}", grammarId + ".Edge.log"); using (StreamWriter stream = new StreamWriter( Path.Combine(LR1Directory, grammarId + ".Edge.log"))) { edgeCollection.Dump(stream); } Console.WriteLine(" Dump LR(1) Compiler's source code..."); DumpTreeNodeTypeConstCode(grammar, parsingMap, grammarId, LR1Directory, SyntaxParserMapAlgorithm.LR1); DumpTokenTypeConstCode(grammar, parsingMap, grammarId, LR1Directory, SyntaxParserMapAlgorithm.LR1); DumpSyntaxParserCode(grammar, parsingMap, grammarId, LR1Directory, SyntaxParserMapAlgorithm.LR1); DumpLexicalAnalyzerCode(grammar, grammarId, SyntaxParserMapAlgorithm.LR1, LR1Directory); TestParsingMap(LR1Directory, parsingMap); } }
private static void DumpSyntaxParserMethod_GetGrammar(RegulationList grammar, CodeTypeDeclaration parserType) { var method = new CodeMemberMethod(); method.Name = "GetGrammar"; method.Attributes = MemberAttributes.Override | MemberAttributes.Family; method.ReturnType = new CodeTypeReference(typeof(RegulationList)); { // if (grammar != null) { return grammar; } var ifStatement = new CodeConditionStatement( new CodeBinaryOperatorExpression( new CodeVariableReferenceExpression("grammar"), CodeBinaryOperatorType.IdentityInequality, new CodeSnippetExpression("null")), new CodeMethodReturnStatement( new CodeVariableReferenceExpression("grammar"))); method.Statements.Add(ifStatement); } string varName = "list"; { // LALR1Compiler.RegulationList list = new LALR1Compiler.RegulationList(); var varDeclaration = new CodeVariableDeclarationStatement(typeof(RegulationList), varName); varDeclaration.InitExpression = new CodeObjectCreateExpression(typeof(RegulationList)); method.Statements.Add(varDeclaration); } int id = 1; foreach (var regulation in grammar) { // <S> ::= null ; // private static LALR1Compiler.TreeNodeType NODE__S = new LALR1Compiler.TreeNodeType("__S", "S", "<S>"); string str = regulation.Dump(); var commentStatement = new CodeCommentStatement(new CodeComment( string.Format("{0}: {1}", id++, str), false)); method.Statements.Add(commentStatement); var parametes = new List <CodeExpression>(); parametes.Add(new CodeVariableReferenceExpression(GetNodeNameInParser(regulation.Left))); parametes.AddRange( from item in regulation.RightPart select new CodeVariableReferenceExpression(GetNodeNameInParser(item))); var ctor = new CodeObjectCreateExpression(typeof(Regulation), parametes.ToArray()); var AddMethod = new CodeMethodReferenceExpression( new CodeVariableReferenceExpression(varName), "Add"); var addRegulation = new CodeMethodInvokeExpression(AddMethod, ctor); method.Statements.Add(addRegulation); } { // grammar = list; var assign = new CodeAssignStatement( new CodeVariableReferenceExpression("grammar"), new CodeVariableReferenceExpression("list")); method.Statements.Add(assign); } { // return grammar; var returnGrammar = new CodeMethodReturnStatement( new CodeVariableReferenceExpression("grammar")); method.Statements.Add(returnGrammar); } parserType.Members.Add(method); }
private static void DumpSyntaxParserMethod_GetParsingMap( RegulationList grammar, LRParsingMap map, CodeTypeDeclaration parserType) { var method = new CodeMemberMethod(); method.Name = "GetParsingMap"; method.Attributes = MemberAttributes.Override | MemberAttributes.Family; method.ReturnType = new CodeTypeReference(typeof(LRParsingMap)); // if (parsingMap != null) { return parsingMap; } DumpSyntaxParserMethod_GetParsingMap_1(method); string varName = "map"; // LALR1Compiler.LRParsingMap map = new LALR1Compiler.LRParsingMap(); DumpSyntaxParserMethod_GetParsingMap_2(method, varName); int setActionCount = 0; foreach (var action in map) { setActionCount += action.Value.Count; //var parametes = new List<CodeExpression>(); string[] parts = action.Key.Split('+'); var stateId = new CodePrimitiveExpression(int.Parse(parts[0])); var nodeType = new CodeVariableReferenceExpression( GetNodeNameInParser(new TreeNodeType(parts[1], parts[1], parts[1]))); if (action.Value.Count > 1) { // action.Value超过1项,就说明有冲突。列出这些冲突应该是有价值的。 method.Comments.Add(new CodeCommentStatement( string.Format("{0} confilicts:", action.Value.Count), false)); foreach (var value in action.Value) { string str = string.Format("map.SetAction({0}, {1}, new {2}({3}));", parts[0], GetNodeNameInParser(new TreeNodeType(parts[1], parts[1], parts[1])), value.GetType().Name, value.ActionParam()); method.Comments.Add(new CodeCommentStatement(str, false)); } } foreach (var value in action.Value) { // map.SetAction(1, NODE__S, new LALR1Compiler.LR1GotoAction(2)); Type t = value.GetType(); CodeObjectCreateExpression ctor = null; string actionParam = value.ActionParam(); if (t == typeof(LR1AceptAction)) { ctor = new CodeObjectCreateExpression(value.GetType()); } else { ctor = new CodeObjectCreateExpression(t, new CodePrimitiveExpression(int.Parse(actionParam))); } var SetActionMethod = new CodeMethodReferenceExpression( new CodeVariableReferenceExpression(varName), "SetAction"); var setAction = new CodeMethodInvokeExpression( SetActionMethod, stateId, nodeType, ctor); method.Statements.Add(setAction); } } { method.Comments.Insert(0, new CodeCommentStatement(string.Format( "{0} SetAction() items", setActionCount))); } { // parsingMap = map; var assign = new CodeAssignStatement( new CodeVariableReferenceExpression("parsingMap"), new CodeVariableReferenceExpression("map")); method.Statements.Add(assign); } { // return map; var returnMap = new CodeMethodReturnStatement( new CodeVariableReferenceExpression("parsingMap")); method.Statements.Add(returnMap); } parserType.Members.Add(method); }