0

私はパーサー文法を書こうとしていますが、現在、(Antlr で) LL 文法の次のプロダクションを持っています。右結合である「#」で区切られた 1 つ以上 (数字または文字列) を解析しようとしています。現時点で 1 つだけではなく、「#」で区切られた 1 つ以上の文字列を解析できるように、プロダクションを変更するにはどうすればよいですか?

A ::= B
    | Number
    | String

B ::= C "->" A

C ::= Number
    | String

この文法の言語の例:

ABC # 123
123 # ABC
ABC # DEF # 123
ABC # DEF # (123 # 456)
ABC # (DEF # 123) # 456

EBNFフォームを使ってみた

A ::= B
    | Number
    | String
    | "(" A ")"

B ::= C ("#" A)?

C ::= Number
    | String

しかし、それは私の文法があいまいになります。このあいまいさをどのように修正しますか?

4

2 に答える 2

0

あなたが探しているものはかなり単純だと思います:

A ::= B ( "#" B )*
B ::= Number | String | "(" A ")"

ANTLR の専門家ではないので、どのように#右結合としてマークするかはわかりませんが、規則の目的は のリストを作成することなBので、セマンティック規則でそれらを右に関連付けることができると思われます。

かっこで囲まれた式のルールを (いわば) 階層の一番下に置くことが重要です。そうしないと、 を解析できません( first # second ) # third

于 2016-03-05T19:25:16.453 に答える
0

あいまいさは、直接-> 、または-> -> -> (および同様に) の 2Numberつの方法で導出できるという事実から生じます。明白な修正は、直接的なプロダクションを取り除くことです:StringANumberABCNumberString

A ::= B
    | "(" A ")"

B ::= C ("#" A)?

C ::= Number
    | String
于 2016-03-05T06:41:37.790 に答える