Skip to content

Commit 3cbcf57

Browse files
committed
fix: throw when lookaheads contain anchors
1 parent 16cf82b commit 3cbcf57

File tree

4 files changed

+30
-11
lines changed

4 files changed

+30
-11
lines changed
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11

22
failed instances:
3-
- parseError : 17
4-
- cacheOverflow : 94
5-
- veryLargeSyntaTree : 29
6-
- stackOverflow : 11
3+
- parseError : 45
4+
- cacheOverflow : 89
5+
- veryLargeSyntaTree : 24
6+
- stackOverflow : 12
77
- regexSyntaxError : 0
88

99
size multipliers:
10-
- mean : 324.6198162588445
11-
- median : 1.5333333333333334
10+
- mean : 323.9035686487585
11+
- median : 1.2692307692307692
1212
- max : 178441.7894736842

benchmark/toStdRegex_output_length.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import fs from 'fs'
22
import * as RE from '../src/regex'
3+
import * as AST from '../src/ast'
34
import { UnsupportedSyntaxError, ParseError } from '../src/index'
45
import { parseRegExp } from '../src/regex-parser'
56
import { toStdRegex } from '../src/dfa.js'
@@ -16,7 +17,7 @@ const mults: number[] = []
1617
function run(inputRegExp: RegExp, index: number) {
1718
console.log('#' + index, inputRegExp)
1819

19-
const inputRegex = RE.fromRegExpAST(parseRegExp(inputRegExp))
20+
const inputRegex = AST.toExtRegex(parseRegExp(inputRegExp))
2021
const outputRegex = toStdRegex(inputRegex)
2122
const outputRegExp = RE.toRegExp(outputRegex)
2223

src/ast.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as CharSet from './char-set'
22
import * as RE from './regex'
3+
import { UnsupportedSyntaxError } from './regex-parser'
34
import { assert, checkedAllCases, isOneOf } from './utils'
45

56
/**
@@ -243,16 +244,22 @@ function pullUpStartAnchor(ast: RegExpAST): RegExpAST {
243244
}
244245
}
245246
case "positive-lookahead": {
247+
const inner = pullUpStartAnchor(ast.inner)
246248
const right = pullUpStartAnchor(ast.right)
247-
if (right.type === 'start-anchor') {
249+
if (inner.type === 'start-anchor') {
250+
throw new UnsupportedSyntaxError('start anchors (^) inside lookaheads are not supported')
251+
} else if (right.type === 'start-anchor') {
248252
return startAnchor(undefined, positiveLookahead(ast.inner, right.right))
249253
} else {
250254
return positiveLookahead(ast.inner, right)
251255
}
252256
}
253257
case "negative-lookahead": {
258+
const inner = pullUpStartAnchor(ast.inner)
254259
const right = pullUpStartAnchor(ast.right)
255-
if (right.type === 'start-anchor') {
260+
if (inner.type === 'start-anchor') {
261+
throw new UnsupportedSyntaxError('start anchors (^) inside lookaheads are not supported')
262+
} else if (right.type === 'start-anchor') {
256263
return startAnchor(undefined, negativeLookahead(ast.inner, right.right))
257264
} else {
258265
return negativeLookahead(ast.inner, right)
@@ -386,16 +393,22 @@ function pullUpEndAnchor(ast: RegExpAST): RegExpAST {
386393
}
387394
}
388395
case "positive-lookahead": {
396+
const inner = pullUpEndAnchor(ast.inner)
389397
const right = pullUpEndAnchor(ast.right)
390-
if (right.type === 'end-anchor') {
398+
if (inner.type === 'end-anchor') {
399+
throw new UnsupportedSyntaxError('end anchors ($) inside lookaheads are not supported')
400+
} else if (right.type === 'end-anchor') {
391401
return endAnchor(positiveLookahead(ast.inner, right.left), undefined)
392402
} else {
393403
return positiveLookahead(ast.inner, right)
394404
}
395405
}
396406
case "negative-lookahead": {
407+
const inner = pullUpEndAnchor(ast.inner)
397408
const right = pullUpEndAnchor(ast.right)
398-
if (right.type === 'end-anchor') {
409+
if (inner.type === 'end-anchor') {
410+
throw new UnsupportedSyntaxError('end anchors ($) inside lookaheads are not supported')
411+
} else if (right.type === 'end-anchor') {
399412
return endAnchor(negativeLookahead(ast.inner, right.right), undefined)
400413
} else {
401414
return negativeLookahead(ast.inner, right)

test/ast.spec.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ describe('toExtRegex', () => {
7777
assert.equal(actual.hash, expected.hash)
7878
})
7979
}
80+
81+
it('fixme', {todo:true}, () => {
82+
const re = /^(?!a)(?!.*a$)(?!.*a{2})a+$/
83+
AST.toExtRegex(parseRegExp(re))
84+
})
8085
})
8186

8287
describe('lookahead elimination', () => {

0 commit comments

Comments
 (0)