lua-users home
lua-l archive

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




On 30/07/16 01:20 AM, Sean Conner wrote:
It was thus said that the Great Soni L. once stated:
As seen in http://stackoverflow.com/q/38664815/3691554

`Line` and `Data` are the things that when `:match()`ed should return
`nil, errmsg` on parsing error. Note that only `Line` decides whether a
line is valid or not, so that's where parsing errors happen. `Data` only
extracts the data from a (valid) line.
   Make sure Line always matches the entirety of a valid line.  Then you can
modify it to return nil,errmsg, like:

local Line = lpeg.C((wsc + (backslashEscaped + 1 - nl))^0)
            / function(x) return x end
            * nl
            * lpeg.Cp()
            + lpeg.Cc(nil) * lpeg.Cc("Invalid parse of a line")


local Data = lpeg.S(" \t")^0
            * lpeg.Cs((ws / " " + inlineComment / "" + backslashEscaped + 1 - (lpeg.S(" \t")^0 * nl))^0)
            * lpeg.S(" \t")^0
            * nl
            + lpeg.Cc(nil) * lpeg.Cc("Invalid data")
Data isn't needed :P because Line already validates the line.

   If you want more specific errors, then you can do something like this:

local escape = lpeg.P"\\ "  / " "
              + lpeg.P"\\\\" / "\\"
              + lpeg.P"\\#"  / "#"
              + lpeg.P"\\>"  / ">"
              + lpeg.P"\\"  / ""
              + lpeg.P"\\n"  / "\n"
              + lpeg.P"\\" * lpeg.Cmt(lpeg.Carg(1) * lpeg.C(1),
                                       function(subject,pos,e,c)
                                         table.insert(e,"Bad escape " .. c)
                                         return nil
                                       end)
local char    = lpeg.R(" [","]~")

Right. Does the "utf-8" on the MDXML spec[1] not mean anything to you?

local cleanup = lpeg.Cs((escape + char)^0) * lpeg.P"\n"

local function test(s)
   local e = {}
   local r = cleanup:match(s,1,e)
   if not r then
     print(e[1])
   end
end

test [[Hello\ There\# foob
]]
test [[Hello\aThere\bfoob
]]

   I'm using lpeg.Carg() to pass in a table to accumulate the errors (this
keeps this reentrant).  lpeg.Cmt() does a match-time capture and if this
returns nil, then that particular capture fails.  I've set up this example
such that if cleanup returns nil, then the passed in table will contain the
error.

I see. I'd still prefer :match itself to emit nil, errmsg with a dynamically generated errmsg.


   -spc



[1] https://github.com/SoniEx2/MDXML#encoding

--
Disclaimer: these emails may be made public at any given time, with or without reason. If you don't agree with this, DO NOT REPLY.