の排他的サブセットであるIDENTIFIER_ONE
2つの識別子のセットを定義しました。次のようなパーサーを書きたいと思います。IDENTIFIER_TWO
IDENTIFIER
"i1(arg) EOS" can't be parsed (1)
"i2(arg) EOS" can be parsed (2)
"i1(arg) = value EOS" can be parsed (3)
"i2(arg) = value EOS" can be parsed (4)
どこでi1
(resp., ) は( resp., i2
) に属します。に属します。以下は、私が求めているすべてのポイントをすでに実現しています。IDENTIFIER_ONE
IDENTIFIER_TWO
arg
value
IDENTIFIER
parser.mly
(4)
identifier:
| IDENTIFIER_ONE { $1 }
| IDENTIFIER_TWO { $1 }
block_statement_EOS:
| identifier LPAREN identifier RPAREN EQUAL identifier EOS { BSE_Let ($1, $3, $6) }
| IDENTIFIER_TWO LPAREN identifier RPAREN EOS { BSE_I_I ($1, $3) }
入力として与えられるi1(arg) = value EOS
と、目標として(3)
正しく読み取られBSE_Let (i1, arg, value)
ます。ただし、i2(arg) = value EOS
入力として与えられると、読み取り後に解析が停止しますEQUAL
。i2(arg)
解析が を満たすと、 の 2 番目のルールに進みblock_statement_EOS
、後でEQUAL
解析できないためだと思います。
理想的には、2 番目のルールが失敗した場合、パーサーが 1 番目のルールを試行できることを願っていblock_statement_EOS
ます。これを可能にするために誰か助けてもらえますか?
PS : 次のように記述すればparser.mly
、すべての目標を達成できます。誰かが理由を知っていますか?さらに、他の多くのルールでは 2 つのサブセットの代わりに記述する必要があるため、この回避策は本当に好きではありませんidentifier
。よりエレガントなソリューションを期待しています...
block_statement_EOS:
| IDENTIFIER_ONE LPAREN identifier RPAREN EQUAL identifier EOS { BSE_Let ($1, $3, $6) }
| IDENTIFIER_TWO LPAREN identifier RPAREN EQUAL identifier EOS { BSE_Let ($1, $3, $6) }
| IDENTIFIER_TWO LPAREN identifier RPAREN EOS { BSE_I_I ($1, $3) }