私は、あいまいなトークンをJavaCCでエレガントに(または何らかの形で)処理する方法を理解する上で、すでに多くの問題を抱えていました。この例を見てみましょう:
XML処理命令をパースしたい。
形式は次のとおりです: :は"<?" <target> <data> "?>"
XML名target
です。data
?>
それでは、JavaCC でこれを定義しましょう:
(この場合は語彙状態を使用しDEFAULT
、PROC_INST
)
TOKEN : <#NAME : (very-long-definition-from-xml-1.1-goes-here) >
TOKEN : <WSS : (" " | "\t")+ > // WSS = whitespaces
<DEFAULT> TOKEN : {<PI_START : "<?" > : PROC_INST}
<PROC_INST> TOKEN : {<PI_TARGET : <NAME> >}
<PROC_INST> TOKEN : {<PI_DATA : ~[] >} // accept everything
<PROC_INST> TOKEN : {<PI_END : "?>" > : DEFAULT}
処理命令を認識する部分:
void PROC_INSTR() : {} {
(
<PI_START>
(t=<PI_TARGET>){System.out.println("target: " + t.image);}
<WSS>
(t=<PI_DATA>){System.out.println("data: " + t.image);}
<PI_END>
) {}
}
でテストしましょう<?mytarget here-goes-some-data?>
:
ターゲットが認識されました: "target: mytarget"
。しかし今、お気に入りのJavaCC 解析エラーが発生します。
!! procinstparser.ParseException: Encountered "" at line 1, column 15.
!! Was expecting one of:
!!
何も遭遇しませんでしたか?何も期待していませんでしたか?または何?ありがとう、JavaCC!
JavaCCのキーワードを使用できることはわかっていますMORE
が、これにより処理命令全体が1つのトークンとして提供されるため、自分でさらに解析/トークン化する必要がありました。なぜそれをすべきなのか?解析しないパーサーを書いていますか?
問題は(私が推測する)です:したがって<PI_DATA>
、「すべて」を認識します。私の定義は間違っています。JavaCC に「」以外のすべてを?>
処理命令データとして認識するように指示する必要があります。
しかし、どうすればそれを行うことができますか?
注: を使用して単一の文字のみを除外できます。またはなどの文字列を除外することはできません。JavaCC のもう 1 つの優れたアンチ機能です。~["a"|"b"|"c"]
~["abc"]
~["?>"]
ありがとうございました。