• Stars
    star
    152
  • Rank 243,434 (Top 5 %)
  • Language
    C#
  • License
    MIT License
  • Created over 7 years ago
  • Updated over 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A modified version of the Irony project (https://irony.codeplex.com) with .NET Core support

Irony

A modified version of the Irony project (https://irony.codeplex.com) with .NET Core support.

Build status

Irony is a .NET Language Implementation Kit written originally by Roman Ivantsov, you should be able to find his blog related to Irony via http://irony-roman.blogspot.com/. He also developed an ORM framework, VITA, which can be found here.

Based on the fact that the project on its official site hasn't been updated for a long time (last commit was on Dec 13th 2013) and cannot support .NET Core, I just made a copy of the project and made some modifications in order to support .NET Core. I still kept the MIT license and made the project to be licensed under Roman's name.

Major Changes

  • Fixed the compile issues found during .NET Core migration
    • Changed StringComparer.InvariantCulture(IgnoreCase) to StringComparer.CurrentCulture(IgnoreCase)
    • Changed char.GetUnicodeCategory() to CharUnicodeInfo.GetUnicodeCategory(current)
    • Temporary removed ParseTreeExtensions implementation
    • Migrated the unit test project to xUnit
    • Removed the original Test, Sample, GrammarExplorer projects from the Visual Studio solution. And the GrammarExplorer is supposed to be provided in another repo

Adding the NuGet Package

The Irony and Irony.Interpreter packages have been published to NuGet, with the package id Irony.NetCore and Irony.Interpreter.NetCore, in distinguishing from the original Irony and Irony.Interpreter packages published by Roman.

Example

This repo contains a full example of an arithmetic expression evaluator, which accepts an arithmetic expression as a string and evaluates and calculates the result. You can find the source code under Irony.SampleApp folder. The expression grammar can be represented by the following C# class:

using Irony.Interpreter.Ast;
using Irony.Parsing;
using System;

namespace Irony.SampleApp
{
    /// <summary>
    /// Represents the grammar of a custom expression.
    /// </summary>
    /// <seealso cref="Irony.Parsing.Grammar" />
    [Language("Expression Grammar", "1.0", "abc")]
    public class ExpressionGrammar : Grammar
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="ExpressionGrammar"/> class.
        /// </summary>
        public ExpressionGrammar() : base(false)
        {
            var number = new NumberLiteral("Number");
            number.DefaultIntTypes = new TypeCode[] { TypeCode.Int16, TypeCode.Int32, TypeCode.Int64 };
            number.DefaultFloatType = TypeCode.Single;

            var identifier = new IdentifierTerminal("Identifier");
            var comma = ToTerm(",");

            var BinOp = new NonTerminal("BinaryOperator", "operator");
            var ParExpr = new NonTerminal("ParenthesisExpression");
            var BinExpr = new NonTerminal("BinaryExpression", typeof(BinaryOperationNode));
            var Expr = new NonTerminal("Expression");
            var Term = new NonTerminal("Term");

            var Program = new NonTerminal("Program", typeof(StatementListNode));

            Expr.Rule = Term | ParExpr | BinExpr;
            Term.Rule = number | identifier;

            ParExpr.Rule = "(" + Expr + ")";
            BinExpr.Rule = Expr + BinOp + Expr;
            BinOp.Rule = ToTerm("+") | "-" | "*" | "/";

            RegisterOperators(10, "+", "-");
            RegisterOperators(20, "*", "/");

            MarkPunctuation("(", ")");
            RegisterBracePair("(", ")");
            MarkTransient(Expr, Term, BinOp, ParExpr);

            this.Root = Expr;
        }
    }
}

The following class diagram illustrates the object model that can represent an arithmetic expression, the classes shown in this diagram can be found under Irony.SampleApp.Evaluations namespace.

The Evaluator class under Irony.SampleApp.Evaluations namespace is responsible for creating the parser based on the above expression grammar definition and parse the input string and finally comes out the evaluated value.

using Irony.Parsing;
using System;
using System.Text;

namespace Irony.SampleApp.Evaluations
{
    internal sealed class Evaluator
    {
        public Evaluation Evaluate(string input)
        {
            var language = new LanguageData(new ExpressionGrammar());
            var parser = new Parser(language);
            var syntaxTree = parser.Parse(input);

            if (syntaxTree.HasErrors())
            {
                throw new InvalidOperationException(BuildParsingErrorMessage(syntaxTree.ParserMessages));
            }

            return PerformEvaluate(syntaxTree.Root);
        }

        private Evaluation PerformEvaluate(ParseTreeNode node)
        {
            switch (node.Term.Name)
            {
                case "BinaryExpression":
                    var leftNode = node.ChildNodes[0];
                    var opNode = node.ChildNodes[1];
                    var rightNode = node.ChildNodes[2];
                    Evaluation left = PerformEvaluate(leftNode);
                    Evaluation right = PerformEvaluate(rightNode);
                    BinaryOperation op = BinaryOperation.Add;
                    switch (opNode.Term.Name)
                    {
                        case "+":
                            op = BinaryOperation.Add;
                            break;
                        case "-":
                            op = BinaryOperation.Sub;
                            break;
                        case "*":
                            op = BinaryOperation.Mul;
                            break;
                        case "/":
                            op = BinaryOperation.Div;
                            break;
                    }
                    return new BinaryEvaluation(left, right, op);
                case "Number":
                    var value = Convert.ToSingle(node.Token.Text);
                    return new ConstantEvaluation(value);
            }

            throw new InvalidOperationException($"Unrecognizable term {node.Term.Name}.");
        }

        private static string BuildParsingErrorMessage(LogMessageList messages)
        {
            var sb = new StringBuilder();
            sb.AppendLine("Parsing failed with the following errors:");
            messages.ForEach(msg => sb.AppendLine($"\t{msg.Message}"));
            return sb.ToString();
        }
    }
}

And the Program.Main method simply creates the evaluator and output the evaluated value:

using Irony.SampleApp.Evaluations;
using System;

namespace Irony.SampleApp
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var evaluator = new Evaluator();
            var evaluation = evaluator.Evaluate("2.5+(3-1)*5");
            Console.WriteLine(evaluation.Value);
        }
    }
}

Program output:

More Repositories

1

Apworks

Apworks is a flexible, scalable, configurable and efficient .NET based application development framework that helps software developers to easily build enterprise applications by applying either Classic Layering or Command-Query Responsibility Segregation (CQRS) architectural patterns.
C#
372
star
2

ByteartRetail

一个演示.NET企业应用开发技术以及领域驱动设计的案例代码,业务背景是一个简单的在线零售系统。
C#
311
star
3

we-text

WeText is a sample application that demonstrates the implementation of DDD/CQRS and microservice architectural patterns in C#.
C#
257
star
4

apworks-core

Apworks framework supporting .NET Core
C#
203
star
5

edasample

A sample project demonstrating EDA in ASP.NET Core
C#
99
star
6

ByteartRetail_Apworks

集成了Apworks框架的Byteart Retail案例,所有核心组件都由Apworks框架提供。是展示Apworks框架的一个很好的案例。
JavaScript
49
star
7

hal

The C#/.NET Core implementation of Hypertext Application Language (HAL) specification.
C#
45
star
8

CloudNotes

A personal note system running on the cloud.
C#
43
star
9

raspkate

A simple and small web server that can run on either Windows or Linux.
C#
33
star
10

apworks-examples

Example projects demonstrating Apworks framework.
C#
30
star
11

daxnet-blog

A blog web site for daxnet.
C#
27
star
12

tetris-sharp

A Tetris game made with CSharp and MonoGame
C#
26
star
13

wizard-framework

A Windows Forms based framework for building wizards.
C#
21
star
14

abacuza

Easing your on-premise Data Processing
JavaScript
21
star
15

logo-sharp

Logo programming language for managed world.
C#
17
star
16

mlnet-trainer

一个基于ML.NET监督式(Supervised)机器学习进行学生成绩预测的案例程序
C#
17
star
17

identity-demo

A demonstration app showing Angular SPA authentication and authorization based on Ocelot and IdentityServer4.
C#
14
star
18

UnifiedQueries

Unified Queries defined a Domain-Specific Language (DSL) to describe a common schema of a query specification.
C#
13
star
19

ocelot-sample

Examples using Ocelot API Gateway in ASP.NET Core applications.
C#
13
star
20

Starwar

A star war game developed with MonoGame
C#
12
star
21

irony-explorer

A project contains both the sample grammars as well as the Windows Forms based grammar explorer for Irony.
C#
9
star
22

CalculateIt2

A calculation generation engine for students.
C#
9
star
23

forms-ui

A Windows Forms library for solving real life problems.
C#
8
star
24

Json2DataSet

Converts the json string to the ADO.NET DataSet object
C#
8
star
25

tasklist

Task list example building for demonstration.
TypeScript
7
star
26

easymemo

一个展示企业级系统设计和架构的简单案例。
C#
5
star
27

name-list

一个演示容器化单页面应用访问后端RESTful API的案例
TypeScript
4
star
28

adaptive-console

A framework of building complex console applications with C#
C#
4
star
29

form-file-upload

Demonstrating file upload in ASP.NET MVC on .NET 5 and the using of Rook-Ceph on Kubernetes.
C#
2
star
30

byteart-retail-msa

Microservices architecture implementation sample of Byteart Retail
C#
2
star
31

guluwin

C#
1
star
32

live-writer-plugins

Some personal used plugins for Open Live Writer
C#
1
star
33

ovow

2D Gaming Engine for MonoGame
C#
1
star
34

OcelotDemo

C#
1
star
35

mdocwriter

Markdown Document Writer
C#
1
star
36

booking

A sample meeting room booking system.
C#
1
star
37

simple-store

A simple demonstration for utilizing value store via a backend service.
1
star
38

NesEmulator

Nintendo Entertainment System (NES) emulator written in C#
C#
1
star
39

link-game

A link game written in C# - 连连看小游戏
C#
1
star
40

tetris

Tetris game
1
star
41

pkiwhosnext

The internal lottery application of PerkinElmer Informatics R&D.
TypeScript
1
star
42

sphinx-demo

A demonstration project of sphinx and readthedocs.org.
1
star