optional expressions in Irony

1.1k views Asked by At

I'm new in Irony programming. the first test example that I'm working on is to calculate mathematical shapes (Area, Volume ,...)

in simple mode, it is working fine. but the challenge is that I want to make it optional. For example, if I choose circle as shape then I only need radius. plus, if I choose rectangle as shape I need height and width. So, I want to know how to get one number as radius when shape is circle and how to get 2 or 3 numbers when shape is rectangle.

            var program = new NonTerminal("program");
            var shapeType = new NonTerminal("shapeType");
            var shapeTypes = new NonTerminal("shapeTypes");
            var circle = new NonTerminal("circle");
            var square = new NonTerminal("square");
            var rectangle = new NonTerminal("rectangle");
            var triangle = new NonTerminal("triangle");
            var commandList = new NonTerminal("commandList");
            var command = new NonTerminal("command");
            var width = new NonTerminal("width");
            var height = new NonTerminal("height");
            var length = new NonTerminal("length");
            var radius = new NonTerminal("radius");
            var number = new NumberLiteral("number");
            var operation = new NonTerminal("operation");

            this.Root = program;

            program.Rule = shapeType + radius + commandList |
                shapeType + length + commandList |
                shapeType + width + commandList |
                shapeType + length + width + commandList |
                shapeType + height + commandList |
            shapeType + length + width + height + commandList;
            shapeType.Rule = Symbol("set") + "shape" + ":" + shapeTypes + ".";
            shapeTypes.Rule = Symbol("circle") | "square" | "rectangle" | "triangle";
            radius.Rule = Symbol("set") + "radius" + ":" + number + ".";
            height.Rule = Symbol("set") + "height" + ":" + number + ".";
            width.Rule = Symbol("set") + "width" + ":" + number + ".";
            length.Rule = Symbol("set") + "length" + ":" + number + ".";

            triangle.Rule = height + width | height + width + length;
            rectangle.Rule = height + width | height + width + length;
            square.Rule = height + width | height + width + length;
            circle.Rule = radius;
            operation.Rule = Symbol("area") | "volume";
            commandList.Rule = MakeStarRule(commandList, null, command);
            command.Rule = Symbol("what") + "is" + operation + ".";

It behaves like this: for circle shape example, I want my code to receive only radius and no more (like the code below - listing 1). but, it can work also when the syntax is like the listing 2. so, I want specific circumstances in compilation.

Listing 1

set shape : circle.
set radius : 10.
what is area.

Listing 2

set shape : circle.
set length : 10.
set width : 5.
what is area.

they both result the same answer which we know that the Listing 2 parameters are wrong.

2

There are 2 answers

1
svick On

To make a rule optional, use the Q() method on it.

0
Erti-Chris Eelmaa On

I understand what you're trying to do, however, such "conditional" behavior is not done using grammars - this will make grammars harder to understand, and hell to maintance, plus it's not that easy too.

Instead, you will have what you have. After you pass in input string to Irony, it will give you back a "parse tree": How to Generate and display ParseTree for an expression in C# using Irony?

The parse tree can also be further transformed into AST(abstract synax tree), Irony has samples on that too.

Once you have parse tree/AST, you will have to do simple analysis over tokens, and flag all the inappropriate behavior.

By analysis, I mean, iterate over the tokens, keep some kind of "context information".

Essentially, the logic will look like this:

if set shape was set to circle:
  if set length exists
     return true; // nothing wrong here, we can calculate area.
  if set length exists and set width exists
     return true;

  return false; // error: we can't decide it..

Hope it helps. Irony has also simple examples how to build an actual programming language with interpreter.