2

私は皮肉なプログラミングが初めてです。私が取り組んでいる最初のテスト例は、数学的形状 (面積、体積、...) を計算することです。

シンプルモードでは正常に動作しています。しかし、課題は、それをオプションにしたいということです。たとえば、形状として円を選択した場合、必要なのは半径だけです。さらに、形状として長方形を選択した場合、高さと幅が必要です。そこで、形が円の場合は半径として1つの数値を取得する方法と、形状が長方形の場合は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 のパラメーターが間違っていることがわかっています。

4

2 に答える 2

1

あなたがやろうとしていることは理解できますが、そのような「条件付き」の動作は文法を使用して行われるわけではありません.

代わりに、あなたはあなたが持っているものを手に入れるでしょう。入力文字列を Irony に渡すと、「解析ツリー」が返されます: Irony を使用して C# で式の ParseTree を生成および表示する方法

解析ツリーはさらに AST (abstract synax tree) に変換することもできます。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 には、インタープリターを使用して実際のプログラミング言語を構築する方法の簡単な例もあります。

于 2014-12-26T21:11:21.307 に答える
0

ルールをオプションにするには、メソッドを使用しQ()ます。

于 2014-12-01T11:45:38.513 に答える