-
Notifications
You must be signed in to change notification settings - Fork 1
/
parser.ts
81 lines (81 loc) · 2.42 KB
/
parser.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import { c, r, Parser } from '../'
import type { RuleDefinitionEntry } from '../types'
import * as SCRIPT from './parser_ext'
const HASHTAG = /#/
const EXCLAMATION = SCRIPT.EXCLAMATION
const AMPERSAND = SCRIPT.AMPERSAND
const PLUS = /\+/
const ASTERISK = /\*/
const QUESTION = /\?/
const SLASH = /\//
const TILDE = /~/
const EQUAL = /=/
const COLON = SCRIPT.COLON
const R_PAREN = /\)/
const L_PAREN = /\(/
const LOWER_R = /r/
const DYNAMIC_RULE = /SCRIPT(\.[a-zA-Z0-9_]+)+/
const EXCEPT_LINE_BREAK = /[^\n]*/
const NOT_SLASH = /[^/]/
const LITERAL = /'([^']|(''))*'/
const NAME = /[a-zA-Z0-9_]+/
const REGEXP = c([LOWER_R, LITERAL], { skip: SCRIPT.settings.skip })
const ASSIGNMENT = c([COLON, EQUAL], { combinator: '/' })
const SYMBOL = c([REGEXP, DYNAMIC_RULE, LITERAL, NAME], { combinator: '/' })
const COMMENT = c([HASHTAG, EXCEPT_LINE_BREAK], { skip: SCRIPT.settings.skip })
const QUANTIFIER = c([c([QUESTION, ASTERISK, PLUS], { combinator: '/' })], { quantifier: '?' })
const ASSERTION = c([AMPERSAND, EXCLAMATION], { combinator: '/' })
const group = r(
c(
[
r(c([NAME, c([L_PAREN], { assertion: '?=' })], { skip: SCRIPT.settings.skip }))
.quantify('?')
.as('name'),
L_PAREN,
(): RuleDefinitionEntry => expression,
R_PAREN
],
{ skip: SCRIPT.settings.skip }
)
).as('group')
const sub_expr = c(
[
r(TILDE).quantify('?').as('noncapture'),
r(ASSERTION).quantify('?').as('assertion'),
c([group, r(SYMBOL).as('symbol')], { combinator: '/' }),
r(QUANTIFIER).as('quantifier')
],
{ skip: SCRIPT.settings.skip }
)
const sequence = c(
[c([r(NOT_SLASH).as('combinator'), sub_expr, c([ASSIGNMENT], { assertion: '?!' })], { skip: SCRIPT.settings.skip })],
{ quantifier: '+' }
)
const choice = c([c([r(SLASH).as('combinator'), sub_expr], { skip: SCRIPT.settings.skip })], { quantifier: '+' })
const expression = r(
c(
[
r(sub_expr).as('first'),
r(c([sequence, choice], { combinator: '/' }))
.quantify('?')
.as('rest')
],
{ skip: SCRIPT.settings.skip }
)
).as('expression')
const grammar = r(
c(
[
c(
[
c([r(NAME).as('name'), r(ASSIGNMENT).as('assignment'), expression], { skip: SCRIPT.settings.skip }),
r(COMMENT).capture(false).as('comment')
],
{ combinator: '/' }
)
],
{ quantifier: '+' }
)
).as('grammar')
const parser = new Parser(grammar, { ...SCRIPT.settings })
export default parser