Парсекит дали неожиданные звонки селекторам
У меня есть следующий очень простой (тестовый) файл грамматики
@start = expression+;
expression = keyword | otherWord;
otherWord = Word;
keyword = a | the;
a = 'a';
the = 'the';
Затем я запускаю следующий код:
// Grammer contains the contents of the above grammer file.
PKParser *parser = [[PKParserFactory factory] parserFromGrammar:grammer assembler:self];
NSString *s = @"The parrot";
[parser parse:s];
PKReleaseSubparserTree(parser);
И следующие методы:
- (void)didMatchA:(PKAssembly *)a{
[self log:a type:@"didMatchA "];
}
- (void)didMatchThe:(PKAssembly *)a{
[self log:a type:@"didMatchThe "];
}
- (void)didMatchKeyword:(PKAssembly *)a{
[self log:a type:@"didMatchKeyword "];
}
- (void)didMatchExpression:(PKAssembly *)a{
[self log:a type:@"didMatchExpression "];
}
- (void)didMatchOtherWord:(PKAssembly *)a{
[self log:a type:@"didMatchOtherWord "];
}
-(void) log:(PKAssembly *) assembly type:(NSString *) type{
PKToken * token = [assembly top];
NSLog(@"Method: [%@], token: %@, assembly: %@", type, token, assembly);
}
И наконец я получаю эти сообщения в журнале:
[1] Method: [didMatchThe ], token: The, assembly: [The]The^parrot
[2] Method: [didMatchKeyword ], token: The, assembly: [The]The^parrot
[3] Method: [didMatchOtherWord ], token: The, assembly: [The]The^parrot
[4] Method: [didMatchExpression ], token: The, assembly: [The]The^parrot
[5] Method: [didMatchExpression ], token: The, assembly: [The]The^parrot
[6] Method: [didMatchOtherWord ], token: parrot, assembly: [The, parrot]The/parrot^
[7] Method: [didMatchExpression ], token: parrot, assembly: [The, parrot]The/parrot^
Это имеет смысл, но я не могу понять, почему происходит%5. Я действительно хотел бы иметь возможность удалить двойное соответствие, чтобы ключевые слова, такие как "The", вызывали только didMatchThe, а не didMatchKeyword.
К сожалению, документация по parsekit, кажется, не существует из-за синтаксиса грамматики и того, как она решает запускать методы. Да, я тоже проверил исходный код:-)
Кто-нибудь получил опыт работы с парсекитом и может пролить свет на это?
1 ответ
Я разработчик ParseKit, и это на самом деле правильное поведение. Вот несколько вещей, которые помогут прояснить это:
Лучший способ узнать о том, как работает ParseKit, - это купить "Создание парсеров с Java" Стивена Джона Метскера. ParseKit почти полностью основан на разработанных там проектах.
Парсерный компонент ParseKit чрезвычайно динамичен и имеет бесконечный прогноз. Это делает его идеальным для быстрой разработки или простого анализа небольших входных данных, но это также означает, что ParseKit демонстрирует крайне низкую производительность при анализе больших документов.
Благодаря бесконечному прогнозированию ParseKit, методы ассемблера, которые вы реализуете, будут вызываться много раз. На самом деле, они будут вызываться слишком много раз, как вы описали выше. Это нормально. ParseKit изучает каждый возможный путь синтаксического анализа, доступный для него в любое время, поэтому вы получаете "слишком много" обратных вызовов.
Ответ заключается в том, чтобы никогда не работать с ivars в ваших методах обратного вызова ассемблера. В ваших методах Ассемблера вы должны всегда сохранять состояние того, над чем вы работаете в текущем
PKAssembly
"starget
Ивар.цель
Электрический ток PKAssembly
это тот, который передается в ваш метод обратного вызова.
Надеюсь, это поможет.