lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


I use the following pattern:

function Assert(patt, ctx)
return patt + function(s, i)
local line, col = linecol(s, i)
error(format("parsing error: %s at %d:%d", ctx, line, col))
return false
end
end

Rule = rule1 * rule2 * Assert(rule3, "Rule.rule3")

The idea is that if a part of a rule fails to match, you throw an error at that point, passing in helpful info for diagnosing the problem.  The "ctx" variable is used as a marker as to where in the grammar tree the error was thrown.  You can use the markers to map to more verbose error messages.  For example, rule3 in the above example might be a semicolon at the end of an _expression_ statement.  If the semicolon doesn't exist, throw an error.

The other technique I use is to trace the rule stack as the parser moves through the grammar hierarchy.  You can do this by adding functions to the grammar that track which rules have been matched.  It's quite a but of work to do this by hand and having it done automatically requires abstracting LPEG so that you're not working directly with it but with some higher level concepts that know how to distribute the rule tracing functions amongst the grammar rules.

In my DSL Lua module, you can find both of these techniques.  DSL does both token and rule tracing if you want it.  It can always be disabled.

DSL: https://github.com/weshoke/DSL

wes


On Mon, Oct 28, 2013 at 10:54 AM, David Given <dg@cowlark.com> wrote:
I want to write a non-trivial grammar in, hopefully, LPEG. The big
stumbling block I can see is that handling incorrect input files appears
to be quite hard in LPEG --- the grammar will just fail to match, rather
than producing a diagnostic, recovering, and continuing to parse.

I've seen some references on the mailing list to a few techniques for
doing error handling, which basically boil down to having a grammar
which can stop matching before the end of the file; by looking to see
how much of the grammar matched, you can tell where it failed. But that
doesn't really work for me, because I'm going to have some deeply nested
patterns.

Are there any good techniques for handling this in a sensible way?

--
┌─── dg@cowlark.com ───── http://www.cowlark.com ─────

│ "Home is where, when you have to go there, they have to take you in."
│ --- Cordelia Naismith (via Robert Frost)