Skip to content

Commit c42d678

Browse files
refactor: minor parser improvements
1 parent d2127dc commit c42d678

File tree

2 files changed

+46
-62
lines changed

2 files changed

+46
-62
lines changed

assembly/parser/parser.ts

+44-60
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,7 @@ function isSpecialCharacter(code: u32): bool {
7474
}
7575

7676
class Range {
77-
from: i32 = -1;
78-
to: i32 = -1;
77+
constructor(public from: i32, public to: i32) {}
7978
}
8079

8180
export class Parser {
@@ -157,64 +156,54 @@ export class Parser {
157156
return new CharacterNode(this.eatToken());
158157
}
159158

160-
private maybeParseRepetitionRange(): Range | null {
161-
// snapshot
162-
const iteratorCopy = this.iterator.copy();
163-
this.eatToken(Char.LeftCurlyBrace);
164-
165-
let range = new Range();
166-
167-
let firstDigit = true;
159+
private maybeParseDigit(): i32 {
168160
let digitStr = "";
169161
while (this.iterator.more()) {
170162
const token = this.iterator.current;
171-
if (token == Char.RightParenthesis) break;
172-
if (firstDigit) {
173-
if (isDigit(token)) {
174-
// if it is a digit, keep eating
175-
digitStr += this.iterator.currentAsString();
176-
} else {
177-
range.from = digitStr.length ? <i32>parseInt(digitStr) : -1;
178-
range.to = range.from;
179-
if (token == Char.Comma) {
180-
// if we meet a comma, start parsing the next digit
181-
firstDigit = false;
182-
digitStr = "";
183-
range.to = -1;
184-
} else if (token == Char.RightCurlyBrace) {
185-
this.eatToken(Char.RightCurlyBrace);
186-
// close brace, this is a single value range
187-
return range;
188-
} else {
189-
// anything else, we got a problem
190-
break;
191-
}
192-
}
163+
if (isDigit(token)) {
164+
digitStr += this.iterator.currentAsString();
193165
} else {
194-
if (isDigit(token)) {
195-
// if it is a digit, keep eating
196-
digitStr += this.iterator.currentAsString();
197-
} else {
198-
range.to = digitStr.length ? <i32>parseInt(digitStr) : -1;
199-
if (token == Char.RightCurlyBrace) {
200-
this.eatToken(Char.RightCurlyBrace);
201-
// close brace, end of range
202-
return range;
203-
} else {
204-
// anything else, we got a problem
205-
break;
206-
}
207-
}
166+
return digitStr == "" ? -1 : <i32>parseInt(digitStr);
208167
}
209168
this.eatToken();
210169
}
170+
return digitStr == "" ? -1 : <i32>parseInt(digitStr);
171+
}
211172

212-
// repetition not found - reset state
213-
this.iterator = iteratorCopy;
173+
private maybeParseRepetitionRange(): Range | null {
174+
// snapshot
175+
const iteratorCopy = this.iterator.copy();
176+
this.eatToken(Char.LeftCurlyBrace);
177+
178+
const from = this.maybeParseDigit();
179+
if (from == -1) {
180+
return null;
181+
}
182+
if (this.iterator.current == Char.RightCurlyBrace) {
183+
this.eatToken();
184+
return new Range(from, from);
185+
} else if (this.iterator.current == Char.Comma) {
186+
this.eatToken();
187+
const to = this.maybeParseDigit();
188+
// @ts-ignore
189+
if (this.iterator.current == Char.RightCurlyBrace) {
190+
this.eatToken();
191+
return new Range(from, to);
192+
}
193+
}
214194

195+
this.iterator = iteratorCopy;
215196
return null;
216197
}
217198

199+
private isGreedy(): bool {
200+
if (this.iterator.current == Char.Question) {
201+
this.eatToken();
202+
return false;
203+
}
204+
return true;
205+
}
206+
218207
// parses a sequence of chars
219208
private parseSequence(): Node {
220209
let nodes = new Array<Node>();
@@ -236,13 +225,13 @@ export class Parser {
236225
const range = this.maybeParseRepetitionRange();
237226
if (range != null) {
238227
const expression = nodes.pop();
239-
let greedy = true;
240-
if (this.iterator.current == Char.Question) {
241-
greedy = false;
242-
this.eatToken();
243-
}
244228
nodes.push(
245-
new RangeRepetitionNode(expression, range.from, range.to, greedy)
229+
new RangeRepetitionNode(
230+
expression,
231+
range.from,
232+
range.to,
233+
this.isGreedy()
234+
)
246235
);
247236
} else {
248237
// this is not the start of a repetition, it's just a char!
@@ -251,12 +240,7 @@ export class Parser {
251240
} else if (isQuantifier(token)) {
252241
const expression = nodes.pop();
253242
const quantifier = this.eatToken();
254-
let greedy = true;
255-
if (this.iterator.current == Char.Question) {
256-
greedy = false;
257-
this.eatToken();
258-
}
259-
nodes.push(new RepetitionNode(expression, quantifier, greedy));
243+
nodes.push(new RepetitionNode(expression, quantifier, this.isGreedy()));
260244
// @ts-ignore
261245
} else if (token == Char.LeftSquareBracket) {
262246
nodes.push(this.parseCharacterSet());

ts/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ globalAny.log = console.log;
55

66
import { RegExp } from "../assembly/regexp";
77

8-
const regexObj = new RegExp("a?");
9-
const match = regexObj.exec("a");
8+
const regexObj = new RegExp("ba{0}b");
9+
const match = regexObj.exec("bb");
1010

1111
console.log(match);

0 commit comments

Comments
 (0)