lua-users home
lua-l archive

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


Alex Bradbury wrote:
On 15 December 2011 10:46, steve donovan<steve.j.donovan@gmail.com>  wrote:
Still immature, of course; languages take time and getting good error
messages out of LPeg grammars is a bit of an art.

When playing with lpeg grammars that's always been the part I've found
less easy (and of course the part which is easiest to just ignore).
Does anyone know of any lpeg examples which do a particularly good job
of this?

This thread is a bit old by now, but for my JSON parser <http://chiselapp.com/user/dhkolf/repository/dkjson/> I used match-time captures to generate error messages. The error message is saved in a state table which is passed as argument to the match function.

  local function loc (str, where)
    local line, pos, linepos = 1, 1, 1
    while true do
      pos = strfind (str, "\n", pos, true)
      if pos and pos < where then
        line = line + 1
        linepos = pos
        pos = pos + 1
      else
        break
      end
    end
    return "line " .. line .. ", column " .. (where - linepos)
  end

  local g = require ("lpeg")
  local P, S, R, V = g.P, g.S, g.R, g.V

  local function ErrorCall (str, pos, msg, state)
    if not state.msg then
      state.msg = msg .. " at " .. loc (str, pos)
      state.pos = pos
    end
    return false
  end

  local function Err (msg)
    return g.Cmt (g.Cc (msg) * g.Carg (2), ErrorCall)
  end

  -- Usage examples:

  local EscapeSequence =
    (P"\\" * g.C (S"\"\\/bfnrt" + Err "unsupported escape sequence")) /
    escapechars
  local String = P"\"" * g.Cs (Char ^ 0) * (P"\"" +
    Err "unterminated string")
  local Pair = g.Cg (Space * String * Space * (P":" +
    Err "colon expected") * ExpectedValue)