1

私は Xtext を使用していますが、次の 2 つの問題について提案が必要です。

問題#1

a、b、c の 3 つのルールがあるとします。そして、b と c が 1 回だけ出現することを除いて、これらの規則の任意のシーケンスを許可したいと思います。そのような文法をどのように書くのが最善でしょうか?

これが私が思いついたものです:

root:
  a+=a*
  b=b
  a+=a*
  c=c
  a+=a*
;
a: 'a';
b: 'b';
c: 'c';

ルート文法を記述するより良い方法はありますか? b と c は依然として厳密な順序である必要があり、これは理想的ではありません。

問題#2

この文法を見てください:

root:
    any+=any*
    x=x
    any+=any*
;

any:
    name=ID
    '{'
        any+=any*
    '}'
;

x:
    name='x' '{' y=y '}'
;

y:
    name='y' '{' z=z '}'
;

z:
    name='z' '{' any+=any* '}'
;

この文法を使用して、次のような言語を記述できると予想しました。

a {
    b {

    }

    c {
        y {

        }
    }
}

x {
    y {
        z {
            the_end {}
        }
    }
}

ただし、「c」の下にノード「y」が表示されるため、エラーが発生します。何故ですか?「y」がルールの 1 つでターミナルとして使用されているため、文法の他の場所には表示されないためですか?

この文法を修正するには?

4

2 に答える 2

1

問題#1の場合:

root: a+=a* (b=b a+=a* & c=c a+=a*);

問題 2 については、次のようなデータ型ルールが必要です。

IdOrABC: ID | 'a' | 'b' | 'c' ;

の代わりにanyルールで使用する必要があります。name=IdOrABCname=ID

于 2016-10-19T10:25:09.650 に答える
0

問題#1については、以下のように文法を調整できます。

root:
  a+=a*
  (
    b=b a+=a* c=c
    |
    c=c a+=a* b=b
  )
  a+=a*
;
a: 'a';
b: 'b';
c: 'c';

一方、パーサーは ID と特別なキーワード「x」、「y」、または「z」を区別できないため、問題 #2 は文法では実際には解決できません。おそらく、以下のように文法を単純にする方がより良い戦略になるでしょう: root: any+=any+ ;

any:
  name=ID
  '{'
    any+=any+
  '}'
;

また、バリデーターを介して特別な x/y/z 階層を適用します。

于 2016-09-09T21:18:18.257 に答える