天天看點

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,右側的文法樹就展示出來了。