tolmasky / language

A fast PEG parser written in JavaScript with first class errors
languagejs.com
MIT License
411 stars 48 forks source link

Line number in "rule is not defined" error #19

Open shamrin opened 12 years ago

shamrin commented 12 years ago

When referencing undefined symbol in the grammar rule, the following is throwed:

It's nice, but line number would be even better.

I tried implementing this, but got stuck at traverseRulesAnchoredAtName. At that point information about rule syntax nodes is lost. The function also seems to be highly optimized: uses its own stack instead of recursion.

Any suggestions on how to implement it?

tolmasky commented 12 years ago

If you look at SyntaxNode.prototype.message you will see a way to calculate a lineNumber for a given SyntaxNode. This should probably be factored out into something like SyntaxNode.prototype.lineNumber.

After this you would want to add the defining node to the rule object in buildRulesFromSyntaxTree. This would actually go into the individual rule builders (e.g. https://github.com/tolmasky/language/blob/master/lib/compiledgrammar.js#L251 ). You would just add node:aNode to that object creation line.

Now finally in traverseRulesAnchoredAtName when you throw you can just use rule.node.lineNumber() to get the line number in question.

shamrin commented 12 years ago

Thanks! The problem with your suggestion is that rule is undefined at this point... And no easy way to find out what rule produced the hash...

I decided to do it the other way, with firstUsageNodes object:

https://github.com/tolmasky/language/pull/20

Here's how the message looks like:

multiplicative = primary ([*/] miltiplicative)?
                               ^^^^^^^^^^^^^^
ERROR line 6: Rule "miltiplicative" is not defined.

What do you think?

shamrin commented 12 years ago

Francisco, could you please comment on my patch? Is idea good or bad? I can completely rewrite my patch if needed.