我是Irony编程的新手。 我正在研究的第一个测试例子是计算数学形状(面积,体积,......)
在简单模式下,它工作正常。但挑战在于我想让它成为可选的。例如,如果我选择圆形作为形状,那么我只需要半径。另外,如果我选择矩形作为形状,我需要高度和宽度。所以,我想知道当形状是圆时如何将一个数字作为半径,以及当形状是矩形时如何获得2或3个数字。
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 + ".";
它的行为如下: 对于圆形的例子,我希望我的代码只接收半径,而不是更多(如下面的代码 - 清单1)。但是,当语法类似于清单2时,它也可以工作。所以,我想要编译中的特定情况。
清单1
set shape : circle.
set radius : 10.
what is area.
清单2
set shape : circle.
set length : 10.
set width : 5.
what is area.
他们都得到了相同的答案,我们知道清单2的参数是错误的。
答案 0 :(得分:1)
我理解你正在尝试做什么,然而,这种“条件”行为并不是用语法来完成的 - 这会让语法难以理解,而且难以理解,加上它也不是那么容易。
相反,你会得到你拥有的东西。将输入字符串传递给Irony后,它会返回一个“解析树”:How to Generate and display ParseTree for an expression in C# using Irony?解析树也可以进一步转换为AST(抽象synax树),Irony也有样本。
一旦你有了解析树/ AST,就必须对令牌进行简单的分析,并标记所有不恰当的行为。
通过分析,我的意思是,迭代令牌,保留某种“上下文信息”。
基本上,逻辑将如下所示:
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..
希望它有所帮助。 Irony还有一些简单的例子,说明如何用解释器构建一个实际的编程语言。
答案 1 :(得分:0)
要使规则可选,use the Q()
method on it。