aboutsummaryrefslogtreecommitdiff
path: root/examples/typedlua/tllexer.lua
diff options
context:
space:
mode:
Diffstat (limited to 'examples/typedlua/tllexer.lua')
-rw-r--r--examples/typedlua/tllexer.lua106
1 files changed, 106 insertions, 0 deletions
diff --git a/examples/typedlua/tllexer.lua b/examples/typedlua/tllexer.lua
new file mode 100644
index 0000000..6517ba5
--- /dev/null
+++ b/examples/typedlua/tllexer.lua
@@ -0,0 +1,106 @@
1local tllexer = {}
2
3local lpeg = require "lpeglabel"
4lpeg.locale(lpeg)
5
6local tlerror = require "tlerror"
7
8function tllexer.try (pat, label)
9 return pat + lpeg.T(tlerror.labels[label])
10end
11
12function tllexer.catch (pat, label)
13 return lpeg.Lc(pat, lpeg.P(false), tlerror.labels[label])
14end
15
16local function setffp (s, i, t, n)
17 if not t.ffp or i > t.ffp then
18 t.ffp = i
19 t.list = {}
20 t.list[n] = true
21 t.expected = "'" .. n .. "'"
22 elseif i == t.ffp then
23 if not t.list[n] then
24 t.list[n] = true
25 t.expected = "'" .. n .. "', " .. t.expected
26 end
27 end
28 return false
29end
30
31local function updateffp (name)
32 return lpeg.Cmt(lpeg.Carg(1) * lpeg.Cc(name), setffp)
33end
34
35tllexer.Shebang = lpeg.P("#") * (lpeg.P(1) - lpeg.P("\n"))^0 * lpeg.P("\n")
36
37local Space = lpeg.space^1
38
39local Equals = lpeg.P("=")^0
40local Open = "[" * lpeg.Cg(Equals, "init") * "[" * lpeg.P("\n")^-1
41local Close = "]" * lpeg.C(Equals) * "]"
42local CloseEQ = lpeg.Cmt(Close * lpeg.Cb("init"),
43 function (s, i, a, b) return a == b end)
44
45local LongString = Open * (lpeg.P(1) - CloseEQ)^0 * tllexer.try(Close, "LongString") /
46 function (s, o) return s end
47
48local Comment = lpeg.Lc(lpeg.P("--") * LongString / function () return end,
49 lpeg.T(tlerror.labels["LongComment"]), tlerror.labels["LongString"]) +
50 lpeg.P("--") * (lpeg.P(1) - lpeg.P("\n"))^0
51
52tllexer.Skip = (Space + Comment)^0
53
54local idStart = lpeg.alpha + lpeg.P("_")
55local idRest = lpeg.alnum + lpeg.P("_")
56
57local Keywords = lpeg.P("and") + "break" + "do" + "elseif" + "else" + "end" +
58 "false" + "for" + "function" + "goto" + "if" + "in" +
59 "local" + "nil" + "not" + "or" + "repeat" + "return" +
60 "then" + "true" + "until" + "while"
61
62tllexer.Reserved = Keywords * -idRest
63
64local Identifier = idStart * idRest^0
65
66tllexer.Name = -tllexer.Reserved * Identifier * -idRest
67
68function tllexer.token (pat, name)
69 return pat * tllexer.Skip + updateffp(name) * lpeg.P(false)
70end
71
72function tllexer.symb (str)
73 return tllexer.token(lpeg.P(str), str)
74end
75
76function tllexer.kw (str)
77 return tllexer.token(lpeg.P(str) * -idRest, str)
78end
79
80local Hex = (lpeg.P("0x") + lpeg.P("0X")) * tllexer.try(lpeg.xdigit^1, "Number")
81local Expo = lpeg.S("eE") * lpeg.S("+-")^-1 * tllexer.try(lpeg.digit^1, "Number")
82local Float = (((lpeg.digit^1 * lpeg.P(".") * lpeg.digit^0 * tllexer.try(-lpeg.P("."), "Number")) +
83 (lpeg.P(".") * lpeg.digit^1)) * Expo^-1) +
84 (lpeg.digit^1 * Expo)
85local Int = lpeg.digit^1
86
87tllexer.Number = Hex + Float + Int
88
89local ShortString = lpeg.P('"') *
90 ((lpeg.P('\\') * lpeg.P(1)) + (lpeg.P(1) - lpeg.P('"')))^0 *
91 tllexer.try(lpeg.P('"'), "String") +
92 lpeg.P("'") *
93 ((lpeg.P("\\") * lpeg.P(1)) + (lpeg.P(1) - lpeg.P("'")))^0 *
94 tllexer.try(lpeg.P("'"), "String")
95
96tllexer.String = LongString + ShortString
97
98-- for error reporting
99tllexer.OneWord = tllexer.Name +
100 tllexer.Number +
101 tllexer.String +
102 tllexer.Reserved +
103 lpeg.P("...") +
104 lpeg.P(1)
105
106return tllexer