9

I'm using ParseKit for objective-C which takes a BNF-like syntax for specifying grammers:

@start = command+;
command = new;
new = 'new' object ';';
object = 'house' | other;

Inclusion of the last line causes an error. Basically I want to say an object can be a house or something else. The non-terminal element "other" is supposed to catch whatever word was there that wasn't house.

Am I going about the "anything-here" idea the wrong way?

Thanks!

Todd Ditchendorf
  • 11,217
  • 14
  • 69
  • 123
FBryant87
  • 4,273
  • 2
  • 44
  • 72
  • It isn't, I want that to collect any word that isn't "house". – FBryant87 Jul 21 '11 at 14:20
  • For example: "new hotel" I thought that would allow any word to be inserted after 'new' and I could match 'other' to find its contents. – FBryant87 Jul 21 '11 at 14:22
  • Did you create a rule for other? – Joe Jul 21 '11 at 14:28
  • nope, as I mentioned above. This is what I think I'm going about wrong, how can I match 'anything'. Look at this grammer for an email address: email = username '@' domain '.com' username and domain could be anything, so how would I specify rules for them? – FBryant87 Jul 21 '11 at 14:40
  • I have not worked with parsekit and its BNF syntax but I have used flex/bison and it should support regex. Replace `other` with \w+ (just to test) – Joe Jul 21 '11 at 14:46
  • 1
    Looking at the source code there may be built in values to do this. Try replacing other with `Word` – Joe Jul 21 '11 at 14:52
  • ah great thanks it seemed to accept that. Could you possiby please sum up what 'Word' is for? – FBryant87 Jul 21 '11 at 15:08
  • 1
    I am looking it up give me some time, the definition looks to be buried deep in the source code. When I find I will post an answer, Also Word is not going to be what you want because it allows names to start with numbers and such. – Joe Jul 21 '11 at 15:22
  • Ok thanks a lot for your help, I tried looking at the source but couldn't make much sense of it. – FBryant87 Jul 21 '11 at 15:58
  • 3
    I can't speak for how ParseKit works, but it seems your fundamental problem is that you aren't in control of the definition of "other", and you appear to have no way to define it with ParseKit (frankly, I'd be amazed to find a parser generator system that wouldn't let you define tokens somehow, but the world is full of odd stuff). So, either find out how ParseKit lets you define your own token, or switch to a parser generator system in which how to do this is clear (the canonical answer is, Flex and YACC). – Ira Baxter Jul 21 '11 at 19:15

2 Answers2

6

Developer of ParseKit here. Carmine's answer above is excellent and you should take his advice. One small additional note:

If you want to make it easy for your Parser delegate to notice when 'house' was matched vs. any other random word, I would change the last line of your grammar above to:

object = house | other;
house = 'house';
other = Word;

Then you should implement the two following callback methods in your Parser delegate:

- (void)parser:(PKParser *)p didMatchHouse:(PKAssembly *)a;
- (void)parser:(PKParser *)p didMatchOther:(PKAssembly *)a;

If you want to allow other to match any token at all (not just words, but also numbers, symbols, quoted strings, etc), you can use the builtin Any type. In that case, you would change the last line of my example above to:

other = Any;
Todd Ditchendorf
  • 11,217
  • 14
  • 69
  • 123
4

As suggested in the comments, you should either replace other with Word or add a new rule:

other = Word;

Since 'house' is a Word, you can also directly replace the object rule with:

object = Word;

A Word in ParseKit is a contiguous sequence of characters ([a-zA-Z]), numbers ([0-9]), and the symbols -, _, and ', that starts with a character. You can find more information about ParseKit tokens in the documentation.

Carmine Paolino
  • 2,749
  • 20
  • 21