Libraryless. Click here for Pure Java version (23982L/144K).
1 | sclass SimpleLeftToRightParser > Meta { |
2 | S text; |
3 | LS tok; |
4 | gettable TokPtr ptr; |
5 | TokPtr mainLoopPtr; |
6 | S currentToken; |
7 | bool caseInsensitive; |
8 | new L warnings; |
9 | |
10 | settable bool internIdentifiers; |
11 | |
12 | *() {} |
13 | *(S *text) {} |
14 | *(LS *tok) {} |
15 | |
16 | swappable LS tokenize(S text) { ret javaTok(text); } |
17 | |
18 | S t aka token() { ret currentToken; } |
19 | S token(int i) { ret get(tok, ptr.idx()+i*2); } |
20 | S next aka consume aka tpp() { var t = t(); next(1); ret t; } |
21 | S lastSpace aka prevSpace() { ret get(tok, ptr.idx()-1); } |
22 | S nextSpace() { ret get(tok, ptr.idx()+1); } |
23 | S space(int i) { ret get(tok, ptr.idx()+i*2+1); } |
24 | |
25 | void unconsume() { next(-1); } |
26 | |
27 | bool tokEq aka eqTok(S a, S b) { ret eqOrEqic(caseInsensitive, a, b); } |
28 | bool tokEqOneOf(S a, S... l) { ret any(l, b -> tokEq(a, b)); } |
29 | |
30 | bool is(int i, S t) { ret tokEq(token(i), t); } |
31 | bool is(S t) { ret tokEq(currentToken, t); } |
32 | bool is(S a, S... more) { |
33 | if (!is(a)) false; |
34 | for i over more: |
35 | if (!is(i+1, more[i])) false; |
36 | true; |
37 | } |
38 | bool was(S t) { ret tokEq(token(-1), t); } |
39 | |
40 | bool isOneOf(S... tokens) { ret tokEqOneOf(currentToken, tokens); } |
41 | |
42 | S[] consumeArray(int n) { |
43 | S[] array = new[n]; |
44 | for i to n: array[i] = consume(); |
45 | ret array; |
46 | } |
47 | |
48 | meta-for isInteger also as isIdentifier { |
49 | bool isInteger() { ret isInteger(t()); } |
50 | bool isInteger(S s) { ret main isInteger(s); } |
51 | } |
52 | |
53 | S consumeIdentifier() { |
54 | S s = assertIdentifier(consume()); |
55 | if (internIdentifiers) |
56 | s = intern(s); |
57 | ret s; |
58 | } |
59 | |
60 | S consumeIdentifierOpt() { ret isIdentifier(t()) ? consumeIdentifier() : null; } |
61 | |
62 | int consumeInteger() { ret parseInt(assertInteger(consume())); } |
63 | |
64 | bool consumeOpt(S token) { |
65 | if (!is(token)) false; |
66 | consume(); |
67 | true; |
68 | } |
69 | |
70 | void consume(S token) { |
71 | if (!is(token)) |
72 | fail("Expected " + quote(token) + ", got " + describeToken(token()); |
73 | consume(); |
74 | } |
75 | |
76 | S describeToken(S token) { |
77 | ret token == null ? "EOF" : quote(token); |
78 | } |
79 | |
80 | S consumeOneOf(S... tokens) { |
81 | if (!isOneOf(tokens)) |
82 | fail("Expected one of " + asList(tokens)); |
83 | ret consume(); |
84 | } |
85 | |
86 | void ptr(TokPtr ptr) { this.ptr = ptr; fetch(); } |
87 | int idx aka tokIdx() { ret ptr.idx(); } |
88 | int lTok() { ret l(tok); } |
89 | int nRemainingTokens() { ret (lTok()-idx())/2; } |
90 | |
91 | bool atEnd aka endOfText() { ret ptr.atEnd(); } |
92 | |
93 | void fetch { currentToken = ptr!; } |
94 | |
95 | bool lineBreak() { ret containsLineBreak(get(tok, ptr.idx()-1)); } |
96 | bool atEndOrLineBreak() { ret atEnd() || lineBreak(); } |
97 | |
98 | void init { |
99 | tok if null = tokenize(text); |
100 | if (ptr == null) ptr(ListAndIndex(tok, 1)); |
101 | } |
102 | |
103 | bool mainLoop() { |
104 | init(); |
105 | if (atEnd()) false; |
106 | if (eq(mainLoopPtr, ptr)) |
107 | fail("main loop didn't advance (current token: " + quote(token()) + ")"); |
108 | mainLoopPtr = ptr; |
109 | true; |
110 | } |
111 | |
112 | class AssureAdvance { |
113 | TokPtr cur; |
114 | |
115 | { init(); } |
116 | |
117 | bool get() { |
118 | if (atEnd()) false; |
119 | if (eq(cur, ptr)) |
120 | fail("Parse loop didn't advance (current token: " + quote(token()) + ")"); |
121 | cur = ptr; |
122 | true; |
123 | } |
124 | } |
125 | |
126 | void unknownToken { |
127 | warn("Unknown token: " + t()); |
128 | } |
129 | |
130 | void warn(S msg) { |
131 | warnings.add(print(msg)); |
132 | } |
133 | |
134 | // can also move backwards for negative n |
135 | void next aka skip aka consume(int n) { |
136 | ptr(min(lTok(), ptr.idx()+n*2)); |
137 | } |
138 | |
139 | // if i points to an N token, it is incremented |
140 | void ptr(int i) { |
141 | ptr(ListAndIndex(tok, min(i | 1, l(tok)))); |
142 | } |
143 | |
144 | LineAndColumn lineAndColumn() { |
145 | ret tokenToLineAndColumn(ptr); |
146 | } |
147 | |
148 | LineAndColumn lineAndColumn(int idx) { |
149 | ret tokenToLineAndColumn(ptr.plus(idx*2)); |
150 | } |
151 | |
152 | S consumeUntilSpaceOr(IF0<Bool> pred) { |
153 | int i = idx(); |
154 | do next(); while (!atEnd() && empty(lastSpace()) && !pred!); |
155 | ret joinSubList(tok, i, idx()-1); |
156 | } |
157 | |
158 | void setText(S text) { |
159 | this.text = text; |
160 | tok = null; |
161 | ptr = null; |
162 | } |
163 | |
164 | int relativeIndexOf(S token) { |
165 | int n = nRemainingTokens(); |
166 | for i to n: |
167 | if (eqTok(token(i), token)) |
168 | ret i; |
169 | ret -1; |
170 | } |
171 | } |
Began life as a copy of #1033717
download show line numbers debug dex old transpilations
Travelled to 4 computer(s): bhatertpkbcr, ekrmjmnbrukm, mowyntqkapby, mqqgnosmbjvj
No comments. add comment
Snippet ID: | #1033967 |
Snippet name: | SimpleLeftToRightParser |
Eternal ID of this version: | #1033967/69 |
Text MD5: | 46b2c60d05edb2f40ab809d066652f5b |
Transpilation MD5: | 784caa2c19f32631bc4c4612cf28e36a |
Author: | stefan |
Category: | javax / parsing |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2025-01-03 20:44:53 |
Source code size: | 4226 bytes / 171 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 501 / 1030 |
Version history: | 68 change(s) |
Referenced in: | [show references] |