ここでParseKitの開発者。
ParseKitには2つの機能があり、入力で発生した解析エラーを説明するユーザーが読み取り可能なヒントを提供するために使用できます。
-[PKParser bestMatchFor:]
PKTrack
クラス_
-bestMatchFor:
この場合、期待どおりに機能していなくても、メソッドを認識しているようです。
PKTrack
ここでは授業がもっと役立つと思います。Metskerの本で説明されているように、は、サブパーサーが必要であり、すべてのサブパーサーが一致しない場合にエラーがスローされる(有用なエラーメッセージが表示される)ことを除いて、PKTrack
まったく同じです。PKSequence
したがって、入力例の文法は次のとおりです。
@start = '(' expr ')' | expr;
expr = ('+' | '-') term term;
term = '(' expr ')' | Word;
連続してリストされているプロダクションはすべてシーケンスですが、代わりにトラックである可能性があります。
これらのシーケンスをトラックに変更する利点はNSException
、入力が一致しない場合に、人間が読める形式の解析エラーメッセージとともにスローされることです。欠点は、これらのTrack例外をキャッチするために、工場で生成されたパーサーのすべての使用法をtry/catchブロックでラップする必要があることです。
現在(または少なくとも今まで)の問題は、PKParserFactory
Tracksを使用してパーサーを作成したことがないことです。代わりに、常にシーケンスを使用します。
そこで、 Google Codeのトランクの先頭に新しいオプションを追加しました(更新する必要があります)。
#define USE_TRACK 0
の
PKParserFactory.m
0
デフォルトです。この定義をに変更すると1
、シーケンスの代わりにトラックが使用されます。したがって、上記の文法と次のような無効な入力が与えられます。
(+ a - b c))
そしてこのクライアントコード:
NSString *g = // fetch grammar above
PKParser *p = [[PKParserFactory factory] parserFromGrammar:g assembler:self];
NSString *s = @"(+ a - b c))";
@try {
PKAssembly *res = [p parse:s];
NSLog(@"res %@", res);
}
@catch (NSException *exception) {
NSLog(@"Parse Error:%@", exception);
}
人間が読める形式のエラーが発生します。
Parse Error:
After : ( + a
Expected : Alternation (term)
Found : -
お役に立てば幸いです。