私はSpirit Qiに比較的慣れておらず、アセンブラーのような言語を解析しようとしています.
たとえば、次を解析したいと思います。
Func Ident{
Mov name, "hello"
Push 5
Exit
}
ここまでは順調ですね。ちゃんと分解できます。ただし、エラー ハンドラーによって奇妙なエラーの場所が表示されることがあります。たとえば、次の欠陥のあるコードを見てください。
Func Ident{
Mov name "hello" ; <-- comma is missing here
Push 5
Exit
}
この解析に関連するルールは次のとおりです。
gr_function = lexeme["Func" >> !(alnum | '_')] // Ensure whole words
> gr_identifier
> "{"
> *( gr_instruction
|gr_label
|gr_vardecl
|gr_paramdecl)
> "}";
gr_instruction = gr_instruction_names
> gr_operands;
gr_operands = -(gr_operand % ',');
パースはエラーに気づきますが、Mov の後に "}" がないことを訴えます。問題は「Func」の定義にあるような気がしますが、特定できません。 パーサーに「,」の欠落について文句を言っ てもらいたいのですが、結果的なエラーについて文句を言っても問題ありませんが、カンマの欠落を原因として間違いなく特定する必要があります。
次のようなバリエーションを試しました。
gr_operands = -(gr_operand
>> *(','
> gr_operand)
);
その他、その他の奇妙なエラーがあります。
「わかりました、オペランドのない命令があるかもしれませんが、オペランドを見つけて、次の前にコンマがない場合は、コンマで失敗します」と言う方法を知っている人はいますか?
アップデート
これまでのご回答ありがとうございます。gr_operand は次のように定義されます。
gr_operand = ( gr_operand_intlit
|gr_operand_flplit
|gr_operand_strlit
|gr_operand_register
|gr_operand_identifier);
gr_operand_intlit = int_;
gr_operand_flplit = double_;
gr_operand_strlit = '"'
> strlitcont
> '"'
;
gr_operand_register = gr_register_names;
// TODO: Must also not accept the keywords from the statement grammar
gr_operand_identifier = !(gr_instruction_names | gr_register_names)
>> raw[
lexeme[(alpha | '_') >> *(alnum | '_')]
];
escchar.name("\\\"");
escchar = '\\' >> char_("\"");
strlitcont.name("String literal content");
strlitcont = *( escchar | ~char_('"') );