diff options
-rw-r--r-- | examples/listId2Rec2.lua | 4 | ||||
-rw-r--r-- | examples/listId2Rec2Cap.lua | 4 | ||||
-rw-r--r-- | examples/recoveryRecCap.lua (renamed from examples/recoveryFabio.lua) | 76 |
3 files changed, 43 insertions, 41 deletions
diff --git a/examples/listId2Rec2.lua b/examples/listId2Rec2.lua index a347a5b..ab8f1dd 100644 --- a/examples/listId2Rec2.lua +++ b/examples/listId2Rec2.lua | |||
@@ -41,8 +41,8 @@ end | |||
41 | local grec = m.P{ | 41 | local grec = m.P{ |
42 | "S", | 42 | "S", |
43 | S = m.Rec(m.Rec(g, m.V"ErrComma", errComma), m.V"ErrId", errId), | 43 | S = m.Rec(m.Rec(g, m.V"ErrComma", errComma), m.V"ErrId", errId), |
44 | ErrComma = record(errComma) * sync(-m.P(1) + id), | 44 | ErrComma = record(errComma) * sync(id), |
45 | ErrId = record(errId) * sync(-m.P(1) + ",") | 45 | ErrId = record(errId) * sync(m.P",") |
46 | } | 46 | } |
47 | 47 | ||
48 | 48 | ||
diff --git a/examples/listId2Rec2Cap.lua b/examples/listId2Rec2Cap.lua index f9fc2bd..1c22c88 100644 --- a/examples/listId2Rec2Cap.lua +++ b/examples/listId2Rec2Cap.lua | |||
@@ -45,8 +45,8 @@ end | |||
45 | local grec = m.P{ | 45 | local grec = m.P{ |
46 | "S", | 46 | "S", |
47 | S = m.Rec(m.Rec(g, m.V"ErrComma", errComma), m.V"ErrId", errId), | 47 | S = m.Rec(m.Rec(g, m.V"ErrComma", errComma), m.V"ErrId", errId), |
48 | ErrComma = record(errComma) * sync(-m.P(1) + id), | 48 | ErrComma = record(errComma) * sync(id), |
49 | ErrId = record(errId) * sync(-m.P(1) + ",") * defaultValue() | 49 | ErrId = record(errId) * sync(m.P",") * defaultValue(), |
50 | } | 50 | } |
51 | 51 | ||
52 | 52 | ||
diff --git a/examples/recoveryFabio.lua b/examples/recoveryRecCap.lua index f16c9e7..c1b3a53 100644 --- a/examples/recoveryFabio.lua +++ b/examples/recoveryRecCap.lua | |||
@@ -1,14 +1,13 @@ | |||
1 | local lpeg = require"lpeglabelrec" | 1 | local m = require"lpeglabelrec" |
2 | local re = require"relabelrec" | ||
2 | 3 | ||
3 | local R, S, P, V = lpeg.R, lpeg.S, lpeg.P, lpeg.V | 4 | local R, S, P, V = m.R, m.S, m.P, m.V |
4 | local C, Cc, Ct, Cmt = lpeg.C, lpeg.Cc, lpeg.Ct, lpeg.Cmt | 5 | local C, Cc, Ct, Cmt = m.C, m.Cc, m.Ct, m.Cmt |
5 | local T, Rec = lpeg.T, lpeg.Rec | 6 | local T, Rec = m.T, m.Rec |
6 | 7 | ||
7 | local labels = { | 8 | local labels = { |
8 | {"NoExp", "no expression found"}, | 9 | {"ExpTermFirst", "expected an expression"}, |
9 | {"Extra", "extra characters found after the expression"}, | 10 | {"ExpTermOp", "expected a term after the operator"}, |
10 | {"ExpTerm", "expected a term after the operator"}, | ||
11 | {"ExpExp", "expected an expression after the parenthesis"}, | ||
12 | {"MisClose", "missing a closing ')' after the expression"}, | 11 | {"MisClose", "missing a closing ')' after the expression"}, |
13 | } | 12 | } |
14 | 13 | ||
@@ -21,17 +20,14 @@ local function labelindex(labname) | |||
21 | error("could not find label: " .. labname) | 20 | error("could not find label: " .. labname) |
22 | end | 21 | end |
23 | 22 | ||
24 | local errors = {} | 23 | local errors, subject |
25 | 24 | ||
26 | local function expect(patt, labname, recpatt) | 25 | local function expect(patt, labname, recpatt) |
27 | local i = labelindex(labname) | 26 | local i = labelindex(labname) |
28 | function recorderror(input, pos) | ||
29 | table.insert(errors, {i, pos}) | ||
30 | return true | ||
31 | end | ||
32 | return patt + T(i) | 27 | return patt + T(i) |
33 | end | 28 | end |
34 | 29 | ||
30 | |||
35 | local num = R("09")^1 / tonumber | 31 | local num = R("09")^1 / tonumber |
36 | local op = S("+-") | 32 | local op = S("+-") |
37 | 33 | ||
@@ -51,19 +47,16 @@ end | |||
51 | 47 | ||
52 | local g = P { | 48 | local g = P { |
53 | "Exp", | 49 | "Exp", |
54 | Exp = Ct(V"Operand" * (C(op) * V"Operand")^0) / compute, | 50 | Exp = Ct(V"OperandFirst" * (C(op) * V"Operand")^0) / compute, |
55 | Operand = expect(V"Term", "ExpTerm"), | 51 | OperandFirst = expect(V"Term", "ExpTermFirst"), |
52 | Operand = expect(V"Term", "ExpTermOp"), | ||
56 | Term = num + V"Group", | 53 | Term = num + V"Group", |
57 | Group = "(" * V"InnerExp" * expect(")", "MisClose", ""); | 54 | Group = "(" * V"Exp" * expect(")", "MisClose"), |
58 | InnerExp = expect(V"Exp", "ExpExp", (P(1) - ")")^0 * Cc(0)); | ||
59 | |||
60 | } | 55 | } |
61 | 56 | ||
62 | local subject, errors | ||
63 | |||
64 | function recorderror(pos, lab) | 57 | function recorderror(pos, lab) |
65 | local line, col = re.calcline(subject, pos) | 58 | local line, col = re.calcline(subject, pos) |
66 | table.insert(errors, { line = line, col = col, msg = terror[lab] }) | 59 | table.insert(errors, { line = line, col = col, msg = labels[lab][2] }) |
67 | end | 60 | end |
68 | 61 | ||
69 | function record (labname) | 62 | function record (labname) |
@@ -74,34 +67,35 @@ function sync (p) | |||
74 | return (-p * m.P(1))^0 | 67 | return (-p * m.P(1))^0 |
75 | end | 68 | end |
76 | 69 | ||
77 | function defaultValue () | 70 | function defaultValue (p) |
78 | return m.Cc"NONE" | 71 | return p or m.Cc(0) |
79 | end | 72 | end |
80 | 73 | ||
81 | local recg = P { | 74 | local recg = P { |
82 | "S", | 75 | "S", |
83 | S = Rec(m.V"A", Cc(0), labelindex("ExpTerm")), -- default value is 0 | 76 | S = Rec(V"A", V"ErrExpTermFirst", labelindex("ExpTermFirst")), -- default value is 0 |
84 | A = Rec(m.V"B", Cc(0), labelindex("ExpExp")), | 77 | A = Rec(V"Sg", V"ErrExpTermOp", labelindex("ExpTermOp")), |
85 | B = Rec(m.V"Sg", Cc(0), labelindex("InnerExp")), | 78 | Sg = Rec(g, V"ErrMisClose", labelindex("MisClose")), |
86 | Sg = Rec(g, Cc(0), labelindex("MisClose")), | 79 | ErrExpTermFirst = record("ExpTermFirst") * sync(op + ")") * defaultValue(), |
87 | ErrExpTerm = record(labelindex("ExpTerm")) * sync() * defaultValue() | 80 | ErrExpTermOp = record("ExpTermOp") * sync(op + ")") * defaultValue(), |
81 | ErrMisClose = record("MisClose") * sync(P")") * defaultValue(m.P""), | ||
88 | } | 82 | } |
89 | 83 | ||
90 | 84 | ||
91 | local function eval(input) | 85 | local function eval(input) |
86 | errors = {} | ||
87 | subject = input | ||
92 | local result, label, suffix = recg:match(input) | 88 | local result, label, suffix = recg:match(input) |
93 | if #errors == 0 then | 89 | if #errors > 0 then |
94 | return result | ||
95 | else | ||
96 | local out = {} | 90 | local out = {} |
97 | for i, err in ipairs(errors) do | 91 | for i, err in ipairs(errors) do |
98 | local pos = err[2] | 92 | local pos = err.col |
99 | local msg = labels[err[1]][2] | 93 | local msg = err.msg |
100 | table.insert(out, "syntax error: " .. msg .. " (at index " .. pos .. ")") | 94 | table.insert(out, "syntax error: " .. msg .. " (at index " .. pos .. ")") |
101 | end | 95 | end |
102 | errors = {} | 96 | print(table.concat(out, "\n")) |
103 | return nil, table.concat(out, "\n") | ||
104 | end | 97 | end |
98 | return result | ||
105 | end | 99 | end |
106 | 100 | ||
107 | print(eval "90-70*5") | 101 | print(eval "90-70*5") |
@@ -113,7 +107,15 @@ print(eval "2+") | |||
113 | print(eval "-2") | 107 | print(eval "-2") |
114 | --> 0 - 2 | 108 | --> 0 - 2 |
115 | 109 | ||
116 | |||
117 | print(eval "1+3+-9") | 110 | print(eval "1+3+-9") |
118 | --> 1 + 3 + 0 - 9 | 111 | --> 1 + 3 + [0] - 9 |
112 | |||
113 | print(eval "1+()3+") | ||
114 | --> 1 + ([0]) [+] 3 + [0] | ||
115 | |||
116 | print(eval "8-(2+)-5") | ||
117 | --> 8 - (2 + [0]) - 5 | ||
118 | |||
119 | print(eval "()") | ||
119 | 120 | ||
121 | print(eval "") | ||