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: | 3011 / 3795 |
| Version history: | 68 change(s) |
| Referenced in: | [show references] |