From 5a4165922a1a6e0ed9cdb65446157c453667ed9c Mon Sep 17 00:00:00 2001 From: Sergio Queiroz Date: Fri, 18 Nov 2016 16:42:15 -0300 Subject: Updating examples. Example recoveryFabio is not complete --- examples/listIdCatch.lua | 28 ----------- examples/listIdCatchRe.lua | 34 ------------- examples/recovery.lua | 2 +- examples/recoveryFabio.lua | 119 ++++++++++++++++++++++++++++++++++++++++++++ examples/recoveryOpFail.lua | 2 +- examples/tiny.lua | 84 ++++++++++++++----------------- 6 files changed, 157 insertions(+), 112 deletions(-) delete mode 100644 examples/listIdCatch.lua delete mode 100644 examples/listIdCatchRe.lua create mode 100644 examples/recoveryFabio.lua diff --git a/examples/listIdCatch.lua b/examples/listIdCatch.lua deleted file mode 100644 index 5ad6f2d..0000000 --- a/examples/listIdCatch.lua +++ /dev/null @@ -1,28 +0,0 @@ -local m = require'lpeglabel' - -local terror = {} - -local function newError(s) - table.insert(terror, s) - return #terror -end - -local errUndef = newError("undefined") -local errId = newError("expecting an identifier") -local errComma = newError("expecting ','") - -local g = m.P{ - "S", - S = m.Lc(m.Lc(m.V"Id" * m.V"List", m.V"ErrId", errId), - m.V"ErrComma", errComma), - List = -m.P(1) + (m.V"Comma" + m.T(errComma)) * (m.V"Id" + m.T(errId)) * m.V"List", - Id = m.V"Sp" * m.R'az'^1, - Comma = m.V"Sp" * ",", - Sp = m.S" \n\t"^0, - ErrId = m.Cc(errId) / terror, - ErrComma = m.Cc(errComma) / terror -} - -print(m.match(g, "one,two")) -print(m.match(g, "one two")) -print(m.match(g, "one,\n two,\nthree,")) diff --git a/examples/listIdCatchRe.lua b/examples/listIdCatchRe.lua deleted file mode 100644 index 8971191..0000000 --- a/examples/listIdCatchRe.lua +++ /dev/null @@ -1,34 +0,0 @@ -local re = require'relabel' - -local terror = {} - -local function newError(l, msg) - table.insert(terror, { l = l, msg = msg } ) -end - -newError("errId", "Error: expecting an identifier") -newError("errComma", "Error: expecting ','") - -local labelCode = {} -local labelMsg = {} -for k, v in ipairs(terror) do - labelCode[v.l] = k - labelMsg[v.l] = v.msg -end - -re.setlabels(labelCode) - -local p = re.compile([[ - S <- Id List /{errId} ErrId /{errComma} ErrComma - List <- !. / Comma Id List - Id <- [a-z]+ / %{errId} - Comma <- ',' / %{errComma} - ErrId <- '' -> errId - ErrComma <- '' -> errComma -]], labelMsg) - -print(p:match("a,b")) -print(p:match("a b")) -print(p:match(",b")) - - diff --git a/examples/recovery.lua b/examples/recovery.lua index 3272ae7..bb17b54 100644 --- a/examples/recovery.lua +++ b/examples/recovery.lua @@ -1,4 +1,4 @@ -local lpeg = require"lpeglabel" +local lpeg = require"lpeglabelrec" local R, S, P, V = lpeg.R, lpeg.S, lpeg.P, lpeg.V local C, Cc, Ct, Cmt = lpeg.C, lpeg.Cc, lpeg.Ct, lpeg.Cmt diff --git a/examples/recoveryFabio.lua b/examples/recoveryFabio.lua new file mode 100644 index 0000000..f16c9e7 --- /dev/null +++ b/examples/recoveryFabio.lua @@ -0,0 +1,119 @@ +local lpeg = require"lpeglabelrec" + +local R, S, P, V = lpeg.R, lpeg.S, lpeg.P, lpeg.V +local C, Cc, Ct, Cmt = lpeg.C, lpeg.Cc, lpeg.Ct, lpeg.Cmt +local T, Rec = lpeg.T, lpeg.Rec + +local labels = { + {"NoExp", "no expression found"}, + {"Extra", "extra characters found after the expression"}, + {"ExpTerm", "expected a term after the operator"}, + {"ExpExp", "expected an expression after the parenthesis"}, + {"MisClose", "missing a closing ')' after the expression"}, +} + +local function labelindex(labname) + for i, elem in ipairs(labels) do + if elem[1] == labname then + return i + end + end + error("could not find label: " .. labname) +end + +local errors = {} + +local function expect(patt, labname, recpatt) + local i = labelindex(labname) + function recorderror(input, pos) + table.insert(errors, {i, pos}) + return true + end + return patt + T(i) +end + +local num = R("09")^1 / tonumber +local op = S("+-") + +local function compute(tokens) + local result = tokens[1] + for i = 2, #tokens, 2 do + if tokens[i] == '+' then + result = result + tokens[i+1] + elseif tokens[i] == '-' then + result = result - tokens[i+1] + else + error('unknown operation: ' .. tokens[i]) + end + end + return result +end + +local g = P { + "Exp", + Exp = Ct(V"Operand" * (C(op) * V"Operand")^0) / compute, + Operand = expect(V"Term", "ExpTerm"), + Term = num + V"Group", + Group = "(" * V"InnerExp" * expect(")", "MisClose", ""); + InnerExp = expect(V"Exp", "ExpExp", (P(1) - ")")^0 * Cc(0)); + +} + +local subject, errors + +function recorderror(pos, lab) + local line, col = re.calcline(subject, pos) + table.insert(errors, { line = line, col = col, msg = terror[lab] }) +end + +function record (labname) + return (m.Cp() * m.Cc(labelindex(labname))) / recorderror +end + +function sync (p) + return (-p * m.P(1))^0 +end + +function defaultValue () + return m.Cc"NONE" +end + +local recg = P { + "S", + S = Rec(m.V"A", Cc(0), labelindex("ExpTerm")), -- default value is 0 + A = Rec(m.V"B", Cc(0), labelindex("ExpExp")), + B = Rec(m.V"Sg", Cc(0), labelindex("InnerExp")), + Sg = Rec(g, Cc(0), labelindex("MisClose")), + ErrExpTerm = record(labelindex("ExpTerm")) * sync() * defaultValue() +} + + +local function eval(input) + local result, label, suffix = recg:match(input) + if #errors == 0 then + return result + else + local out = {} + for i, err in ipairs(errors) do + local pos = err[2] + local msg = labels[err[1]][2] + table.insert(out, "syntax error: " .. msg .. " (at index " .. pos .. ")") + end + errors = {} + return nil, table.concat(out, "\n") + end +end + +print(eval "90-70*5") +--> 20 + +print(eval "2+") +--> 2 + 0 + +print(eval "-2") +--> 0 - 2 + + +print(eval "1+3+-9") +--> 1 + 3 + 0 - 9 + diff --git a/examples/recoveryOpFail.lua b/examples/recoveryOpFail.lua index d65b9e0..bd1beb7 100644 --- a/examples/recoveryOpFail.lua +++ b/examples/recoveryOpFail.lua @@ -1,4 +1,4 @@ -local lpeg = require"lpeglabel" +local lpeg = require"lpeglabelrec" local R, S, P, V = lpeg.R, lpeg.S, lpeg.P, lpeg.V local C, Cc, Ct, Cmt = lpeg.C, lpeg.Cc, lpeg.Ct, lpeg.Cmt diff --git a/examples/tiny.lua b/examples/tiny.lua index 99c3144..784e031 100644 --- a/examples/tiny.lua +++ b/examples/tiny.lua @@ -1,4 +1,4 @@ -local re = require 'relabel' +local re = require 'relabelrec' local terror = {} @@ -25,21 +25,6 @@ newError("errFactor", "Error: expected '(', ID, or number after '*' or '/'") newError("errExpFac", "Error: expected expression after '('") newError("errClosePar", "Error: expected ')' after expression") -local line - -local function incLine() - line = line + 1 - return true -end - -local function countLine(s, i) - line = 1 - local p = re.compile([[ - S <- (%nl -> incLine / .)* - ]], { incLine = incLine}) - p:match(s:sub(1, i)) - return true -end local labelCode = {} for k, v in ipairs(terror) do @@ -48,7 +33,7 @@ end re.setlabels(labelCode) -local g = re.compile([[ +local g = re.compile[[ Tiny <- CmdSeq CmdSeq <- (Cmd (SEMICOLON / ErrSemi)) (Cmd (SEMICOLON / ErrSemi))* Cmd <- IfCmd / RepeatCmd / ReadCmd / WriteCmd / AssignCmd @@ -61,25 +46,24 @@ local g = re.compile([[ SimpleExp <- Term ((ADD / SUB) (Term / ErrTerm))* Term <- Factor ((MUL / DIV) (Factor / ErrFactor))* Factor <- OPENPAR (Exp / ErrExpFac) (CLOSEPAR / ErrClosePar) / NUMBER / NAME - ErrSemi <- ErrCount %{errSemi} - ErrExpIf <- ErrCount %{errExpIf} - ErrThen <- ErrCount %{errThen} - ErrCmdSeq1 <- ErrCount %{errCmdSeq1} - ErrCmdSeq2 <- ErrCount %{errCmdSeq2} - ErrEnd <- ErrCount %{errEnd} - ErrCmdSeqRep <- ErrCount %{errCmdSeqRep} - ErrUntil <- ErrCount %{errUntil} - ErrExpRep <- ErrCount %{errExpRep} - ErrAssignOp <- ErrCount %{errAssignOp} - ErrExpAssign <- ErrCount %{errExpAssign} - ErrReadName <- ErrCount %{errReadName} - ErrWriteExp <- ErrCount %{errWriteExp} - ErrSimpExp <- ErrCount %{errSimpExp} - ErrTerm <- ErrCount %{errTerm} - ErrFactor <- ErrCount %{errFactor} - ErrExpFac <- ErrCount %{errExpFac} - ErrClosePar <- ErrCount %{errClosePar} - ErrCount <- '' => countLine + ErrSemi <- %{errSemi} + ErrExpIf <- %{errExpIf} + ErrThen <- %{errThen} + ErrCmdSeq1 <- %{errCmdSeq1} + ErrCmdSeq2 <- %{errCmdSeq2} + ErrEnd <- %{errEnd} + ErrCmdSeqRep <- %{errCmdSeqRep} + ErrUntil <- %{errUntil} + ErrExpRep <- %{errExpRep} + ErrAssignOp <- %{errAssignOp} + ErrExpAssign <- %{errExpAssign} + ErrReadName <- %{errReadName} + ErrWriteExp <- %{errWriteExp} + ErrSimpExp <- %{errSimpExp} + ErrTerm <- %{errTerm} + ErrFactor <- %{errFactor} + ErrExpFac <- %{errExpFac} + ErrClosePar <- %{errClosePar} ADD <- Sp '+' ASSIGNMENT <- Sp ':=' CLOSEPAR <- Sp ')' @@ -102,12 +86,17 @@ local g = re.compile([[ WRITE <- Sp 'write' RESERVED <- (IF / ELSE / END / READ / REPEAT / THEN / UNTIL / WRITE) ![a-z]+ Sp <- %s* -]], { countLine = countLine }) +]] -local function printError(n, e) - assert(n == nil) - print("Line " .. line .. ": " .. terror[e].msg) +local function mymatch(g, s) + local r, e, sfail = g:match(s) + if not r then + local line, col = re.calcline(s, #s - #sfail) + local msg = "Error at line " .. line .. " (col " .. col .. "): " + return r, msg .. terror[e].msg + end + return r end local s = [[ @@ -118,7 +107,7 @@ repeat n := n - 1 until (n < 1); write f;]] -printError(g:match(s)) +print(mymatch(g, s)) s = [[ n := 5; @@ -128,14 +117,14 @@ repeat n := n - 1; until (n < 1); read ;]] -printError(g:match(s)) +print(mymatch(g, s)) s = [[ if a < 1 then b := 2; else b := 3;]] -printError(g:match(s)) +print(mymatch(g, s)) s = [[ n := 5; @@ -145,7 +134,7 @@ repeat n := n - 1; untill (n < 1); ]] -printError(g:match(s)) +print(mymatch(g, s)) s = [[ n := 5; @@ -155,9 +144,8 @@ repeat n := n - 1; 3 (n < 1); ]] -printError(g:match(s)) - -printError(g:match("a : 2")) -printError(g:match("a := (2")) +print(mymatch(g, s)) +print(mymatch(g, "a : 2")) +print(mymatch(g, "a := (2")) -- cgit v1.2.3-55-g6feb