http://irony.codeplex.com/
今天刚有时间看看。还没看明白。这里先记录一点。
----------
这段写的很清楚,意思是说,这里不需与普通的LEX&YACC不同,这还真有点让我不太习惯。
好吧。
下载了之后,我的vs2010打不开。原因是vs2010的VSSDK,安装顺序是这样的:
vs 2010 ,然后装vssdk 2010 ,然后装vs sp1,然后vs sdk 1.1 。
否则可不成。我一开始状到了vs 2010 sp1 ,然后装不上。然后我unstall 了sp1,然后再装vssdk,然后,我就懒得动了。反正过程中弹出一个对话框:你这么干可能会导致永久性不能用了。我当然也没理它,就当我不认英文。
所以,装了vs 2013,
然后下载了这个包:
Irony_2013_12_12.zip
,然后编译过。
选这个工程:030.Irony.GrammarExplorer.2012
运行后,我找了半天,下一步干什么,后来找了个贴子:
-----------
http://www.hanselman.com/blog/TheWeeklySourceCode59AnOpenSourceTreasureIronyNETLanguageImplementationKit.aspx
不过,这个文章一点用也没有。
------------------
还是我来画吧:
1. 启动后,点:Add Grammar
2.选择下图目录的Irony.Samples.dll
3. 如下:
4. 选test页签
到这个页面,拷一下示例过来:
http://irony.codeplex.com/wikipage?title=expression%20grammar%20sample&referringTitle=Home
using System; using System.Collections.Generic; using System.Text; using Irony.Parsing; using Irony.Ast; namespace Irony.Samples { // This grammar describes programs that consist of simple expressions and assignments // for ex: // x = 3 // y = -x + 5 // the result of calculation is the result of last expression or assignment. // Irony's default runtime provides expression evaluation. // supports inc/dec operators (++,--), both prefix and postfix, // and combined assignment operators like +=, -=, etc. [Language("ExpressionEvaluator", "1.0", "Multi-line expression evaluator")] public class ExpressionEvaluatorGrammar : Irony.Parsing.Grammar { public ExpressionEvaluatorGrammar() { // 1. Terminals var number = new NumberLiteral("number"); //Let's allow big integers (with unlimited number of digits): number.DefaultIntTypes = new TypeCode[] { TypeCode.Int32, TypeCode.Int64, NumberLiteral.TypeCodeBigInt }; var identifier = new IdentifierTerminal("identifier"); var comment = new CommentTerminal("comment", "#", "\n", "\r"); //comment must to be added to NonGrammarTerminals list; it is not used directly in grammar rules, // so we add it to this list to let Scanner know that it is also a valid terminal. base.NonGrammarTerminals.Add(comment); // 2. Non-terminals var Expr = new NonTerminal("Expr"); var Term = new NonTerminal("Term"); var BinExpr = new NonTerminal("BinExpr", typeof(BinExprNode)); var ParExpr = new NonTerminal("ParExpr"); var UnExpr = new NonTerminal("UnExpr", typeof(UnExprNode)); var UnOp = new NonTerminal("UnOp"); var BinOp = new NonTerminal("BinOp", "operator"); var PostFixExpr = new NonTerminal("PostFixExpr", typeof(UnExprNode)); var PostFixOp = new NonTerminal("PostFixOp"); var AssignmentStmt = new NonTerminal("AssignmentStmt", typeof(AssigmentNode)); var AssignmentOp = new NonTerminal("AssignmentOp", "assignment operator"); var Statement = new NonTerminal("Statement"); var ProgramLine = new NonTerminal("ProgramLine"); var Program = new NonTerminal("Program", typeof(StatementListNode)); // 3. BNF rules Expr.Rule = Term | UnExpr | BinExpr | PostFixExpr; Term.Rule = number | ParExpr | identifier; ParExpr.Rule = "(" + Expr + ")"; UnExpr.Rule = UnOp + Term; UnOp.Rule = ToTerm("+") | "-" | "++" | "--"; BinExpr.Rule = Expr + BinOp + Expr; BinOp.Rule = ToTerm("+") | "-" | "*" | "/" | "**"; PostFixExpr.Rule = Term + PostFixOp; PostFixOp.Rule = ToTerm("++") | "--"; AssignmentStmt.Rule = identifier + AssignmentOp + Expr; AssignmentOp.Rule = ToTerm("=") | "+=" | "-=" | "*=" | "/="; Statement.Rule = AssignmentStmt | Expr | Empty; ProgramLine.Rule = Statement + NewLine; Program.Rule = MakeStarRule(Program, ProgramLine); this.Root = Program; // Set grammar root // 4. Operators precedence RegisterOperators(1, "+", "-"); RegisterOperators(2, "*", "/"); RegisterOperators(3, Associativity.Right, "**"); // 5. Punctuation and transient terms RegisterPunctuation("(", ")"); RegisterBracePair("(", ")"); MarkTransient(Term, Expr, Statement, BinOp, UnOp, PostFixOp, AssignmentOp, ProgramLine, ParExpr); //automatically add NewLine before EOF so that our BNF rules work correctly when there's no final line break in source this.LanguageFlags = LanguageFlags.CreateAst | LanguageFlags.NewLineBeforeEOF | LanguageFlags.CanRunSample; } } }//namespace
粘上之后,点Parser
然后选一个点,点locate,右侧的语法树就展示出来了。