aboutsummaryrefslogtreecommitdiff
path: root/testlabel.lua
diff options
context:
space:
mode:
authorSergio Queiroz <sqmedeiros@gmail.com>2016-07-14 16:05:13 -0300
committerSergio Queiroz <sqmedeiros@gmail.com>2016-07-14 16:05:13 -0300
commit2f74ecc812c5ad7e95a55175c3d4de9ab9e0c551 (patch)
treec1f5541a90a0f2083acfb37e1d420a1614cf6a5b /testlabel.lua
parenta0891e8f58c5ea1ab777bf607949237894249907 (diff)
downloadlpeglabel-2f74ecc812c5ad7e95a55175c3d4de9ab9e0c551.tar.gz
lpeglabel-2f74ecc812c5ad7e95a55175c3d4de9ab9e0c551.tar.bz2
lpeglabel-2f74ecc812c5ad7e95a55175c3d4de9ab9e0c551.zip
Adding more tests
Diffstat (limited to 'testlabel.lua')
-rw-r--r--testlabel.lua138
1 files changed, 138 insertions, 0 deletions
diff --git a/testlabel.lua b/testlabel.lua
index 2243826..db16354 100644
--- a/testlabel.lua
+++ b/testlabel.lua
@@ -589,6 +589,144 @@ checkeqlab({nil, 0, "bc"}, g:match("bbc"))
589assert(g:match("xxc") == 4) 589assert(g:match("xxc") == 4)
590assert(g:match("c") == 2) 590assert(g:match("c") == 2)
591checkeqlab({nil, 0, ""}, g:match("fail")) 591checkeqlab({nil, 0, ""}, g:match("fail"))
592checkeqlab({nil, 0, ""}, g:match("aaxx"))
593
594--[[
595S -> (A //{99} (!c .)*) C
596A -> a+ (b / ^99)
597C -> c+
598]]
599g = m.P{
600 "S",
601 S = m.Rec(m.V"A", (-m.P"c" * m.P(1))^0, 99) * m.V"C",
602 A = m.P"a"^1 * ("b" + m.T(99)),
603 C = m.P"c"^1,
604}
605
606assert(g:match("abc") == 4)
607assert(g:match("aabc") == 5)
608assert(g:match("aadc") == 5)
609checkeqlab({nil, 0, "bc"}, g:match("bc"))
610checkeqlab({nil, 0, "bbc"}, g:match("bbc"))
611checkeqlab({nil, 0, "b"}, g:match("abb"))
612checkeqlab({nil, 0, ""}, g:match("axx"))
613assert(g:match("accc") == 5)
614assert(g:match("axxc") == 5)
615checkeqlab({nil, 0, "c"}, g:match("c"))
616checkeqlab({nil, 0, "fail"}, g:match("fail"))
617
618
619
620-- Matthew's recovery example
621lpeg = m
622
623local R, S, P, V = lpeg.R, lpeg.S, lpeg.P, lpeg.V
624local C, Cc, Ct, Cmt = lpeg.C, lpeg.Cc, lpeg.Ct, lpeg.Cmt
625local T, Lc = lpeg.T, lpeg.Lc
626
627local labels = {
628 {"NoExp", "no expression found"},
629 {"Extra", "extra characters found after the expression"},
630 {"ExpTerm", "expected a term after the operator"},
631 {"ExpExp", "expected an expression after the parenthesis"},
632 {"MisClose", "missing a closing ')' after the expression"},
633}
634
635local function labelindex(labname)
636 for i, elem in ipairs(labels) do
637 if elem[1] == labname then
638 return i
639 end
640 end
641 error("could not find label: " .. labname)
642end
643
644local errors = {}
645
646local function expect(patt, labname)
647 local i = labelindex(labname)
648 function recorderror(input, pos)
649 table.insert(errors, {i, pos})
650 return true
651 end
652 return patt + Cmt("", recorderror) * T(i)
653end
654
655local num = R("09")^1 / tonumber
656local op = S("+-*/")
657
658local function compute(tokens)
659 local result = tokens[1]
660 for i = 2, #tokens, 2 do
661 if tokens[i] == '+' then
662 result = result + tokens[i+1]
663 elseif tokens[i] == '-' then
664 result = result - tokens[i+1]
665 elseif tokens[i] == '*' then
666 result = result * tokens[i+1]
667 elseif tokens[i] == '/' then
668 result = result / tokens[i+1]
669 else
670 error('unknown operation: ' .. tokens[i])
671 end
672 end
673 return result
674end
675
676local g = P {
677 "Exp",
678 Exp = Ct(V"Term" * (C(op) * V"OpRecov")^0) / compute;
679 OpRecov = m.Rec(V"Operand", Cc(0), labelindex("ExpTerm"));
680 Operand = expect(V"Term", "ExpTerm");
681 Term = num + V"Group";
682 Group = "(" * V"InnerExp" * m.Rec(expect(")", "MisClose"), P"", labelindex("MisClose"));
683 InnerExp = m.Rec(expect(V"Exp", "ExpExp"), (P(1) - ")")^0 * Cc(0), labelindex("ExpExp"));
684}
685
686g = expect(g, "NoExp") * expect(-P(1), "Extra")
687
688local function eval(input)
689 local result, label, suffix = g:match(input)
690 if #errors == 0 then
691 return result
692 else
693 local out = {}
694 for i, err in ipairs(errors) do
695 local pos = err[2]
696 local msg = labels[err[1]][2]
697 table.insert(out, "syntax error: " .. msg .. " (at index " .. pos .. ")")
698 end
699 errors = {}
700 return nil, table.concat(out, "\n")
701 end
702end
703
704print(eval "98-76*(54/32)")
705--> 37.125
706
707print(eval "(1+1-1*2/2")
708--> syntax error: missing a closing ')' after the expression (at index 11)
709
710print(eval "(1+)-1*(2/2)")
711--> syntax error: expected a term after the operator (at index 4)
712
713print(eval "(1+1)-1*(/2)")
714--> syntax error: expected an expression after the parenthesis (at index 10)
715
716print(eval "1+(1-(1*2))/2x")
717--> syntax error: extra chracters found after the expression (at index 14)
718
719print(eval "-1+(1-(1*2))/2")
720--> syntax error: no expression found (at index 1)
721
722print(eval "(1+1-1*(2/2+)-():")
723--> syntax error: expected a term after the operator (at index 13)
724--> syntax error: expected an expression after the parenthesis (at index 16)
725--> syntax error: missing a closing ')' after the expression (at index 17)
726--> syntax error: extra characters found after the expression (at index
727
728
729
592 730
593print("OK") 731print("OK")
594 732