diff options
Diffstat (limited to 'examples/typedlua/tllexer.lua')
-rw-r--r-- | examples/typedlua/tllexer.lua | 106 |
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 @@ | |||
1 | local tllexer = {} | ||
2 | |||
3 | local lpeg = require "lpeglabel" | ||
4 | lpeg.locale(lpeg) | ||
5 | |||
6 | local tlerror = require "tlerror" | ||
7 | |||
8 | function tllexer.try (pat, label) | ||
9 | return pat + lpeg.T(tlerror.labels[label]) | ||
10 | end | ||
11 | |||
12 | function tllexer.catch (pat, label) | ||
13 | return lpeg.Lc(pat, lpeg.P(false), tlerror.labels[label]) | ||
14 | end | ||
15 | |||
16 | local 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 | ||
29 | end | ||
30 | |||
31 | local function updateffp (name) | ||
32 | return lpeg.Cmt(lpeg.Carg(1) * lpeg.Cc(name), setffp) | ||
33 | end | ||
34 | |||
35 | tllexer.Shebang = lpeg.P("#") * (lpeg.P(1) - lpeg.P("\n"))^0 * lpeg.P("\n") | ||
36 | |||
37 | local Space = lpeg.space^1 | ||
38 | |||
39 | local Equals = lpeg.P("=")^0 | ||
40 | local Open = "[" * lpeg.Cg(Equals, "init") * "[" * lpeg.P("\n")^-1 | ||
41 | local Close = "]" * lpeg.C(Equals) * "]" | ||
42 | local CloseEQ = lpeg.Cmt(Close * lpeg.Cb("init"), | ||
43 | function (s, i, a, b) return a == b end) | ||
44 | |||
45 | local LongString = Open * (lpeg.P(1) - CloseEQ)^0 * tllexer.try(Close, "LongString") / | ||
46 | function (s, o) return s end | ||
47 | |||
48 | local 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 | |||
52 | tllexer.Skip = (Space + Comment)^0 | ||
53 | |||
54 | local idStart = lpeg.alpha + lpeg.P("_") | ||
55 | local idRest = lpeg.alnum + lpeg.P("_") | ||
56 | |||
57 | local 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 | |||
62 | tllexer.Reserved = Keywords * -idRest | ||
63 | |||
64 | local Identifier = idStart * idRest^0 | ||
65 | |||
66 | tllexer.Name = -tllexer.Reserved * Identifier * -idRest | ||
67 | |||
68 | function tllexer.token (pat, name) | ||
69 | return pat * tllexer.Skip + updateffp(name) * lpeg.P(false) | ||
70 | end | ||
71 | |||
72 | function tllexer.symb (str) | ||
73 | return tllexer.token(lpeg.P(str), str) | ||
74 | end | ||
75 | |||
76 | function tllexer.kw (str) | ||
77 | return tllexer.token(lpeg.P(str) * -idRest, str) | ||
78 | end | ||
79 | |||
80 | local Hex = (lpeg.P("0x") + lpeg.P("0X")) * tllexer.try(lpeg.xdigit^1, "Number") | ||
81 | local Expo = lpeg.S("eE") * lpeg.S("+-")^-1 * tllexer.try(lpeg.digit^1, "Number") | ||
82 | local 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) | ||
85 | local Int = lpeg.digit^1 | ||
86 | |||
87 | tllexer.Number = Hex + Float + Int | ||
88 | |||
89 | local 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 | |||
96 | tllexer.String = LongString + ShortString | ||
97 | |||
98 | -- for error reporting | ||
99 | tllexer.OneWord = tllexer.Name + | ||
100 | tllexer.Number + | ||
101 | tllexer.String + | ||
102 | tllexer.Reserved + | ||
103 | lpeg.P("...") + | ||
104 | lpeg.P(1) | ||
105 | |||
106 | return tllexer | ||