天天看点

Irony - .NET 学习笔记Irony - .NET Language Implementation Kit.

Irony - .NET Language Implementation Kit.

http://irony.codeplex.com/

今天刚有时间看看。还没看明白。这里先记录一点。

----------

Irony is a development kit for implementing languages on .NET platform. Unlike most existing yacc/lex-style solutions Irony does not employ any scanner or parser code generation from grammar specifications written in a specialized meta-language. In Irony the target language grammar is coded directly in c# using operator overloading to express grammar constructs. Irony's scanner and parser modules use the grammar encoded as c# class to control the parsing process. See the expression grammar sample for an example of grammar definition in c# class, and using it in a working parser.

Download contents

The download zip contains core Irony libraries implementing a parsing engine, an interpreter, a number of sample grammars, unit test projects, and Grammar Explorer tool for viewing and debugging your languages (see picture below).

We provide multiple sample grammars for languages like GW Basic, Java, c#, Scheme, SQL, JSON and some others. Irony includes a ready-to-use expression evaluator that can be easily plugged-in into a .NET application.

这段写的很清楚,意思是说,这里不需与普通的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

Irony - .NET 学习笔记Irony - .NET Language Implementation Kit.

2.选择下图目录的Irony.Samples.dll

Irony - .NET 学习笔记Irony - .NET Language Implementation Kit.

3. 如下:

Irony - .NET 学习笔记Irony - .NET Language Implementation Kit.

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
      
Irony - .NET 学习笔记Irony - .NET Language Implementation Kit.

粘上之后,点Parser

然后选一个点,点locate,右侧的语法树就展示出来了。