1 |
|
---|
2 | using System;
|
---|
3 | using Irony.Interpreter;
|
---|
4 | using Irony.Interpreter.Ast;
|
---|
5 | using Irony.Interpreter.Evaluator;
|
---|
6 | using Irony.Parsing;
|
---|
7 |
|
---|
8 | namespace Benchmark_Generator {
|
---|
9 | public class ExpressionGrammar : InterpretedLanguageGrammar {
|
---|
10 | public ExpressionGrammar() : this(caseSensitive: false) { }
|
---|
11 |
|
---|
12 | public ExpressionGrammar(bool caseSensitive)
|
---|
13 | : base(caseSensitive) {
|
---|
14 | // Define terminals
|
---|
15 | var number = new NumberLiteral("Number") {
|
---|
16 | DefaultIntTypes = new[] { TypeCode.Int32, TypeCode.Int64 },
|
---|
17 | DefaultFloatType = TypeCode.Double
|
---|
18 | };
|
---|
19 | var variable = new IdentifierTerminal("Variable");
|
---|
20 | var stringLit = new StringLiteral("String");
|
---|
21 |
|
---|
22 | // Define non-terminals
|
---|
23 | var term = new NonTerminal("Term");
|
---|
24 | var binExpr = new NonTerminal("BinExpr", typeof(BinaryOperatorMethod));
|
---|
25 | var binOp = new NonTerminal("BinOp", "operator");
|
---|
26 | var unExpr = new NonTerminal("UnExpr", typeof(UnaryOperatorMethod));
|
---|
27 | var unOp = new NonTerminal("UnOp", "operator");
|
---|
28 | var expr = new NonTerminal("Expr");
|
---|
29 | var parExpr = new NonTerminal("ParExpr");
|
---|
30 | var statement = new NonTerminal("Statement");
|
---|
31 | var program = new NonTerminal("Program", typeof(StatementListNode));
|
---|
32 |
|
---|
33 | // BNF rules
|
---|
34 | expr.Rule = term | unExpr | binExpr;
|
---|
35 | term.Rule = number | parExpr | stringLit | variable;
|
---|
36 | parExpr.Rule = "(" + expr + ")";
|
---|
37 | unExpr.Rule = unOp + term;
|
---|
38 | unOp.Rule = ToTerm("+") | "-";
|
---|
39 | binExpr.Rule = expr + binOp + expr;
|
---|
40 | binOp.Rule = ToTerm("+") | "-" | "*" | "/" | "^"; // add, sub, mul, div, pow
|
---|
41 | statement.Rule = expr | Empty;
|
---|
42 | program.Rule = MakePlusRule(program, NewLine, statement);
|
---|
43 | this.Root = program;
|
---|
44 |
|
---|
45 | // Operators precedence
|
---|
46 | RegisterOperators(1, "+", "-");
|
---|
47 | RegisterOperators(2, "*", "/");
|
---|
48 | RegisterOperators(3, Associativity.Right, "^");
|
---|
49 |
|
---|
50 | // Punctuation and braces
|
---|
51 | MarkPunctuation("(", ")", "[", "]");
|
---|
52 | RegisterBracePair("(", ")");
|
---|
53 | RegisterBracePair("[", "]");
|
---|
54 | MarkTransient(term, expr, binOp, unOp, parExpr);
|
---|
55 | // Language flags
|
---|
56 | // LanguageFlags = LanguageFlags.NewLineBeforeEOF | LanguageFlags.CreateAst;
|
---|
57 | LanguageFlags = LanguageFlags.NewLineBeforeEOF;
|
---|
58 | }
|
---|
59 |
|
---|
60 | public override LanguageRuntime CreateRuntime(LanguageData language) {
|
---|
61 | return new ExpressionEvaluatorRuntime(language);
|
---|
62 | }
|
---|
63 |
|
---|
64 | #region Running in Grammar Explorer
|
---|
65 | private static ExpressionEvaluator evaluator;
|
---|
66 | public override string RunSample(RunSampleArgs args) {
|
---|
67 | if (evaluator == null) {
|
---|
68 | evaluator = new ExpressionEvaluator(this);
|
---|
69 | evaluator.Globals.Add("null", evaluator.Runtime.NoneValue);
|
---|
70 | evaluator.Globals.Add("true", true);
|
---|
71 | evaluator.Globals.Add("false", false);
|
---|
72 |
|
---|
73 | }
|
---|
74 | evaluator.ClearOutput();
|
---|
75 | evaluator.Evaluate(args.ParsedSample);
|
---|
76 | return evaluator.GetOutput();
|
---|
77 | }
|
---|
78 | #endregion
|
---|
79 | }
|
---|
80 | }
|
---|