Подразделы

Другие разделы

Дата и время

21/11/2024 19:02:24

Авторизация

Имя:
Пароль:
Зарегистрироваться
Восстановить пароль
 

printПримеры для средств разработки трасляторов

printIrony

Пример калькулятора на Irony.
using System;
using System.Collections.Generic;
using Irony.Parsing;

namespace Irony.SampleApp
{
    [Language("Expression Grammar", "1.0", "A simple arithmetic expression grammar.")]
    public class ExpressionGrammar : Grammar
    {
        public ExpressionGrammar() : base(false)
        {
            // 1. Терминальные символы
            var number = new NumberLiteral("Number");
            // 2. Нетерминальные символы
            var Expr = new NonTerminal("Expr");
            var Term = new NonTerminal("Term");
            var BinExpr = new NonTerminal("BinExpr");
            var ParExpr = new NonTerminal("ParExpr");
            var UnExpr = new NonTerminal("UnExpr");
            var BinOp = new NonTerminal("BinOp", "operator");

            // 3. правила БНФ
            Expr.Rule = Term | UnExpr | BinExpr;
            Term.Rule = number | ParExpr ;
            ParExpr.Rule = "(" + Expr + ")";
            UnExpr.Rule = ToTerm("-") + Term;
            BinExpr.Rule = Expr + BinOp + Expr;
            BinOp.Rule = ToTerm("+") | "-" | "*" | "/" | "^";
            this.Root = Expr;

            // 4. Приоритет операций
            RegisterOperators(1, "+", "-");
            RegisterOperators(2, "*", "/");
            RegisterOperators(3, Associativity.Right, "^");

            MarkPunctuation("(", ")");
            MarkTransient(Term, Expr, BinOp, ParExpr);
        }
    }
    internal sealed class Evaluator
    {

        public double PerformEvaluate(ParseTreeNode node)
        {
            switch (node.Term.Name)
            {
                case "BinExpr":
                    {
                        double left = PerformEvaluate(node.ChildNodes[0]);
                        double right = PerformEvaluate(node.ChildNodes[2]);
                        switch (node.ChildNodes[1].Term.Name)
                        {
                            case "+": return left + right;
                            case "-": return left - right;
                            case "*": return left * right;
                            case "/": return left / right;
                            case "^": return Math.Pow(left, right);
                        }
                    }
                    break;
                case "UnExpr":
                    {
                        double left = PerformEvaluate(node.ChildNodes[1]);
                        return -left;
                    }
                case "Number":
                    return Convert.ToDouble(node.Token.Text);
            }

            throw new InvalidOperationException("Unrecognizable term " + node.Term.Name);
        }
        
    }
    public class Program
    {
        public static void Main(string[] args)
        {
            Grammar grammar = new ExpressionGrammar();
            Parser parser = new Parser(grammar);
            ParseTree parseTree = parser.Parse("2 * -(5 + 1)+4^3");
            var evaluator = new Evaluator();
            Console.WriteLine("Result={0}",evaluator.PerformEvaluate(parseTree.Root));
        }
    }
}
loading