aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md114
1 files changed, 0 insertions, 114 deletions
diff --git a/README.md b/README.md
index 9484b3d..9bc162d 100644
--- a/README.md
+++ b/README.md
@@ -74,15 +74,6 @@ Otherwise, the result of the matching of `p1` is the pattern's result.
74 74
75 75
76 76
77#### <a name="f-rec"></a><code>lpeglabel.Rec(p1, p2 [, l1, ..., ln])</code>
78
79The *recovery operator* is similar to labeled order choice except
80that the matching of `p2` is tried from the failure position of `p1`.
81
82If no label is provided, the regular PEG failure is caught
83i.e. `lpeg.Rec(p1, p2)` is equivalent to `lpeg.Rec(p1, p2, 0)`.
84
85
86#### <a name="re-t"></a><code>%{l}</code> 77#### <a name="re-t"></a><code>%{l}</code>
87 78
88Syntax of *relabelrec* module. Equivalent to `lpeg.T(l)`. 79Syntax of *relabelrec* module. Equivalent to `lpeg.T(l)`.
@@ -698,108 +689,3 @@ print(eval "3)")
698-- syntax error: extra characters found after the expression (at index 2) 689-- syntax error: extra characters found after the expression (at index 2)
699-- Result = 3 690-- Result = 3
700``` 691```
701
702#### Error Recovery
703
704By using labeled ordered choice or the recovery operator, when a label
705is thrown, the parser may record the error and still continue parsing
706to find more errors. We can even record the error right away without
707actually throwing a label (relying on the regular PEG failure instead).
708Below we rewrite the arithmetic expression example and modify
709the `expect` function to use the recovery operator for error recovery:
710
711```lua
712local lpeg = require"lpeglabel"
713
714local R, S, P, V = lpeg.R, lpeg.S, lpeg.P, lpeg.V
715local C, Cc, Ct, Cmt, Carg = lpeg.C, lpeg.Cc, lpeg.Ct, lpeg.Cmt, lpeg.Carg
716local T, Lc, Rec = lpeg.T, lpeg.Lc, lpeg.Rec
717
718local labels = {
719 {"NoExp", "no expression found"},
720 {"Extra", "extra characters found after the expression"},
721 {"ExpTerm", "expected a term after the operator"},
722 {"ExpExp", "expected an expression after the parenthesis"},
723 {"MisClose", "missing a closing ')' after the expression"},
724}
725
726local function labelindex(labname)
727 for i, elem in ipairs(labels) do
728 if elem[1] == labname then
729 return i
730 end
731 end
732 error("could not find label: " .. labname)
733end
734
735local function expect(patt, labname, recpatt)
736 local i = labelindex(labname)
737 local function recorderror(input, pos, errors)
738 table.insert(errors, {i, pos})
739 return true
740 end
741 if not recpatt then recpatt = P"" end
742 return Rec(patt, Cmt(Carg(1), recorderror) * recpatt)
743end
744
745local num = R("09")^1 / tonumber
746local op = S("+-*/")
747
748local function compute(tokens)
749 local result = tokens[1]
750 for i = 2, #tokens, 2 do
751 if tokens[i] == '+' then
752 result = result + tokens[i+1]
753 elseif tokens[i] == '-' then
754 result = result - tokens[i+1]
755 elseif tokens[i] == '*' then
756 result = result * tokens[i+1]
757 elseif tokens[i] == '/' then
758 result = result / tokens[i+1]
759 else
760 error('unknown operation: ' .. tokens[i])
761 end
762 end
763 return result
764end
765
766
767local g = P {
768 "Exp",
769 Exp = Ct(V"Term" * (C(op) * V"Operand")^0) / compute;
770 Operand = expect(V"Term", "ExpTerm", Cc(0));
771 Term = num + V"Group";
772 Group = "(" * V"InnerExp" * expect(")", "MisClose");
773 InnerExp = expect(V"Exp", "ExpExp", (P(1) - ")")^0 * Cc(0));
774}
775
776g = expect(g, "NoExp", P(1)^0) * expect(-P(1), "Extra")
777
778local function eval(input)
779 local errors = {}
780 local result, label, suffix = g:match(input, 1, errors)
781 if #errors == 0 then
782 return result
783 else
784 local out = {}
785 for i, err in ipairs(errors) do
786 local pos = err[2]
787 local msg = labels[err[1]][2]
788 table.insert(out, "syntax error: " .. msg .. " (at index " .. pos .. ")")
789 end
790 return nil, table.concat(out, "\n")
791 end
792end
793
794print(eval "98-76*(54/32)")
795--> 37.125
796
797print(eval "-1+(1-(1*2))/2")
798--> syntax error: no expression found (at index 1)
799
800print(eval "(1+1-1*(2/2+)-():")
801--> syntax error: expected a term after the operator (at index 13)
802--> syntax error: expected an expression after the parenthesis (at index 16)
803--> syntax error: missing a closing ')' after the expression (at index 17)
804--> syntax error: extra characters found after the expression (at index 17)
805```