grammar-composer 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,191 @@
1
+ import * as G from '../GrammarComposer.js';
2
+ import * as R from 'regexp-composer';
3
+ export class RegExpGrammar {
4
+ //////////////////////////////////////////////////////////////////////////////////////////////
5
+ // High level productions
6
+ //////////////////////////////////////////////////////////////////////////////////////////////
7
+ disjunction = () => [
8
+ this.sequence,
9
+ G.possibly([
10
+ this.disjunctionSeparator,
11
+ this.disjunction,
12
+ ])
13
+ ];
14
+ sequence = () => G.oneOrMore(this.element);
15
+ element = () => G.anyOf(this.anchor, this.lookaround, this.possiblyQuantifiedExpression);
16
+ //////////////////////////////////////////////////////////////////////////////////////////////
17
+ // Quantifed expressions
18
+ //////////////////////////////////////////////////////////////////////////////////////////////
19
+ possiblyQuantifiedExpression = () => [
20
+ G.anyOf(this.group, this.backReference, this.singleCharExpression),
21
+ G.possibly(G.anyOf(this.starQuantifier, this.plusQuantifier, this.exactCountQuantifier, this.countRangeQuantifier)),
22
+ G.possibly(this.nongreedyQuantifier), // Nongreedy quantifier
23
+ ];
24
+ exactCountQuantifier = () => G.pattern([
25
+ '{',
26
+ R.captureAs('count', R.oneOrMore(digit)),
27
+ '}',
28
+ ]);
29
+ countRangeQuantifier = () => G.pattern([
30
+ '{',
31
+ R.captureAs('start', R.oneOrMore(digit)),
32
+ ',',
33
+ R.possibly(R.captureAs('end', R.oneOrMore(digit))),
34
+ '}',
35
+ ]);
36
+ //////////////////////////////////////////////////////////////////////////////////////////////
37
+ // Group expressions
38
+ //////////////////////////////////////////////////////////////////////////////////////////////
39
+ group = () => G.anyOf(this.uncapturedGroup, this.namedCaptureGroup, this.unnamedCaptureGroup);
40
+ uncapturedGroup = () => [
41
+ '(:',
42
+ this.disjunction,
43
+ ')',
44
+ ];
45
+ namedCaptureGroup = () => [
46
+ '(?<',
47
+ G.pattern(R.captureAs('name', R.oneOrMore(letter))),
48
+ '>',
49
+ this.disjunction,
50
+ ')',
51
+ ];
52
+ unnamedCaptureGroup = () => [
53
+ '(',
54
+ this.disjunction,
55
+ ')',
56
+ ];
57
+ //////////////////////////////////////////////////////////////////////////////////////////////
58
+ // Backreferences
59
+ //////////////////////////////////////////////////////////////////////////////////////////////
60
+ unnamedBackreference = () => G.pattern([
61
+ '\\',
62
+ R.captureAs('index', digit),
63
+ ]);
64
+ namedBackreference = () => G.pattern([
65
+ '\\k<',
66
+ R.captureAs('name', digit),
67
+ '>',
68
+ ]);
69
+ backReference = G.anyOf(this.unnamedBackreference, this.namedBackreference);
70
+ //////////////////////////////////////////////////////////////////////////////////////////////
71
+ // Lookahead and lookbehind expressions
72
+ //////////////////////////////////////////////////////////////////////////////////////////////
73
+ positiveLookahead = () => [
74
+ '(?=',
75
+ this.disjunction,
76
+ ')',
77
+ ];
78
+ negativeLookahead = () => [
79
+ '(?!',
80
+ this.disjunction,
81
+ ')',
82
+ ];
83
+ positiveLookbehind = () => [
84
+ '(?<=',
85
+ this.disjunction,
86
+ ')',
87
+ ];
88
+ negativeLookbehind = () => [
89
+ '(?<!',
90
+ this.disjunction,
91
+ ')',
92
+ ];
93
+ lookaround = G.anyOf(this.positiveLookahead, this.negativeLookahead, this.positiveLookbehind, this.negativeLookbehind);
94
+ //////////////////////////////////////////////////////////////////////////////////////////////
95
+ // Single character expressions
96
+ //////////////////////////////////////////////////////////////////////////////////////////////
97
+ singleCharExpression = () => G.anyOf(this.anyCharWildcard, this.charClass, this.unicodeProperty, this.notUnicodeProperty, this.charcodeOrEscapedChar, this.unreservedCharLiteral);
98
+ unreservedCharLiteral = () => G.pattern(R.notAnyOfChars('[', '.', '*', '+', '?', '^', '$', '{', '}', '(', ')', '|', ']', '\\'));
99
+ escapedCharLiteral = () => G.pattern([
100
+ '\\',
101
+ R.anyChar
102
+ ]);
103
+ hexCharcode = () => G.pattern([
104
+ '\\x',
105
+ hexDigit,
106
+ hexDigit
107
+ ]);
108
+ controlCharcode = () => G.pattern([
109
+ '\\c',
110
+ R.charRange('A', 'Z'),
111
+ ]);
112
+ codepoint = () => G.pattern([
113
+ '\\u',
114
+ '{',
115
+ R.captureAs('value', R.oneOrMore(hexDigit)),
116
+ '}',
117
+ ]);
118
+ codepointRange = () => G.pattern([
119
+ '\\u',
120
+ '{',
121
+ R.captureAs('start', R.oneOrMore(hexDigit)),
122
+ '-',
123
+ R.captureAs('end', R.oneOrMore(hexDigit)),
124
+ '}',
125
+ ]);
126
+ unicodeProperty = () => G.pattern([
127
+ '\\p',
128
+ this.unicodePropertyBodyPattern,
129
+ ]);
130
+ notUnicodeProperty = () => G.pattern([
131
+ '\\P',
132
+ this.unicodePropertyBodyPattern,
133
+ ]);
134
+ unicodePropertyBodyPattern = [
135
+ '{',
136
+ R.captureAs('property', R.oneOrMore(letterOrDigit)),
137
+ R.possibly([
138
+ '=',
139
+ R.captureAs('value', R.oneOrMore(letterOrDigit)),
140
+ ]),
141
+ '}',
142
+ ];
143
+ charClassChar = () => G.pattern(R.notAnyOfChars(']'));
144
+ charClass = () => [
145
+ '[',
146
+ G.possibly(this.charClassNegator),
147
+ G.oneOrMore(G.anyOf(this.charRange, this.codepointRange, this.charClass, this.unicodeProperty, this.notUnicodeProperty, this.charcodeOrEscapedChar, this.charClassChar)),
148
+ ']',
149
+ ];
150
+ charcodeOrEscapedChar = G.anyOf(this.codepoint, this.hexCharcode, this.controlCharcode, this.escapedCharLiteral);
151
+ charRangeElement = G.anyOf(this.charcodeOrEscapedChar, G.pattern(R.anyChar));
152
+ charRange = () => [
153
+ this.charRangeElement,
154
+ '-',
155
+ this.charRangeElement,
156
+ ];
157
+ //////////////////////////////////////////////////////////////////////////////////////////////
158
+ // Special symbols
159
+ //////////////////////////////////////////////////////////////////////////////////////////////
160
+ starQuantifier = () => '*';
161
+ plusQuantifier = () => '+';
162
+ nongreedyQuantifier = () => '?';
163
+ charClassNegator = () => '^';
164
+ inputStartAnchor = () => '^';
165
+ inputEndAnchor = () => '$';
166
+ anyCharWildcard = () => '.';
167
+ disjunctionSeparator = () => '|';
168
+ anchor = G.anyOf(this.inputStartAnchor, this.inputEndAnchor);
169
+ escapedCharacterClass = () => G.pattern(R.anyOf(R.captureAs('whitespace', escapedCharString.whitespace), R.captureAs('nonWhitespace', escapedCharString.nonWhitespace), R.captureAs('digit', escapedCharString.digit), R.captureAs('nonDigit', escapedCharString.nonDigit), R.captureAs('wordBoundary', escapedCharString.wordBoundary), R.captureAs('nonWordBoundary', escapedCharString.nonWordBoundary), R.captureAs('formFeed', escapedCharString.formFeed), R.captureAs('carriageReturn', escapedCharString.carriageReturn), R.captureAs('lineFeed', escapedCharString.lineFeed), R.captureAs('tab', escapedCharString.tab), R.captureAs('verticalTab', escapedCharString.verticalTab), R.captureAs('backwardSlash', escapedCharString.backwardSlash)));
170
+ }
171
+ const digit = R.charRange('0', '9');
172
+ const letter = R.anyOf(R.charRange('a', 'z'), R.charRange('A', 'Z'));
173
+ const letterOrDigit = R.anyOf(letter, digit);
174
+ const hexDigit = R.anyOf(digit, R.charRange('a', 'f'), R.charRange('A', 'F'));
175
+ const escapedCharString = {
176
+ whitespace: '\\s',
177
+ nonWhitespace: '\\S',
178
+ digit: '\\d',
179
+ nonDigit: '\\D',
180
+ word: '\\d',
181
+ nonWord: '\\D',
182
+ wordBoundary: '\\b',
183
+ nonWordBoundary: '\\B',
184
+ formFeed: '\\f',
185
+ carriageReturn: '\\r',
186
+ lineFeed: '\\n',
187
+ tab: '\\t',
188
+ verticalTab: '\\v',
189
+ backwardSlash: '\\\\'
190
+ };
191
+ //# sourceMappingURL=RegExpGrammar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RegExpGrammar.js","sourceRoot":"","sources":["../../src/test-grammars/RegExpGrammar.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grammar-composer",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Defines and generates parsers from composable grammar definitions. Includes advanced features like lexer-free parsing, selective packrat memoization and static analysis.",
5
5
  "author": "Rotem Dan",
6
6
  "license": "MIT",
@@ -32,7 +32,7 @@
32
32
  "test": "node dist/Test.js"
33
33
  },
34
34
  "dependencies": {
35
- "regexp-composer": "^0.2.0"
35
+ "regexp-composer": "^0.2.2"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@types/node": "^22.10.1"
@@ -38,7 +38,11 @@ export function buildGrammar<T extends { [key: string]: any }>(obj: T | (new ()
38
38
  const uniqueIdSource = () => uniqueIdCounter++
39
39
 
40
40
  for (const [func, nonterminal] of nonterminalLookup) {
41
- const preparedContent = prepareGrammarElement(nonterminal.content, nameLookup as Map<any, string>, nonterminalLookup, optionalNonterminalLookup, uniqueIdSource)
41
+ const preparedContent = prepareGrammarElement(
42
+ nonterminal.content,
43
+ nonterminalLookup,
44
+ optionalNonterminalLookup,
45
+ uniqueIdSource)
42
46
 
43
47
  nonterminal.content = preparedContent
44
48
 
@@ -46,7 +50,7 @@ export function buildGrammar<T extends { [key: string]: any }>(obj: T | (new ()
46
50
  optionalNonterminal.content = preparedContent
47
51
  }
48
52
 
49
- let startNonterminal = nonterminalLookup.get(obj[startProductionName] as Function)
53
+ const startNonterminal = nonterminalLookup.get(obj[startProductionName] as Function)
50
54
 
51
55
  if (!startNonterminal) {
52
56
  throw new Error(`Couldn't find a start production named '${startProductionName as string}'.`)
@@ -61,16 +65,15 @@ export function buildGrammar<T extends { [key: string]: any }>(obj: T | (new ()
61
65
  nonterminals[nameLookup.get(key)!] = nonterminal
62
66
  }
63
67
 
64
- return new Grammar(
68
+ return new Grammar<T>(
65
69
  nonterminals[startProductionName],
66
70
  nonterminals,
67
71
  uniqueIdCounter
68
- ) as Grammar<T>
72
+ )
69
73
  }
70
74
 
71
75
  function prepareGrammarElement(
72
76
  rootElement: GrammarElement,
73
- nameLookup: Map<any, string>,
74
77
  nonterminalLookup: Map<Function, Nonterminal>,
75
78
  optionalNonterminalLookup: Map<Function, Nonterminal>,
76
79
  getUniqueId: () => number
@@ -89,7 +92,6 @@ function prepareGrammarElement(
89
92
  case 'PatternTerminal': {
90
93
  return {
91
94
  ...element,
92
- name: nameLookup.get(element) ?? '',
93
95
  uniqueId: getUniqueId()
94
96
  }
95
97
  }
@@ -399,7 +401,6 @@ export function pattern(pattern: Pattern): PatternTerminal {
399
401
 
400
402
  return {
401
403
  type: 'PatternTerminal',
402
- name: '[Pattern]',
403
404
  pattern,
404
405
  regExp,
405
406
  optional,
@@ -518,8 +519,7 @@ export interface StringTerminal extends GrammarElementBase {
518
519
 
519
520
  export interface PatternTerminal extends GrammarElementBase {
520
521
  type: 'PatternTerminal'
521
- name: string
522
- pattern: Pattern | Pattern[]
522
+ pattern: Pattern
523
523
  regExp: RegExp
524
524
  }
525
525
 
package/src/Test.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  import { Timer } from "./utilities/Timer.js"
2
- import { jsonSample2 } from "./test-data/TestData.js"
2
+ import { jsonSample1, jsonSample2 } from "./test-data/TestData.js"
3
3
  import { anyOf, buildGrammar } from "./GrammarComposer.js"
4
4
  import { JsonGrammar } from "./test-grammars/JsonGrammar.js"
5
5
  import { XmlGrammar } from "./test-grammars/XmlGrammar.js"
6
+ import { RegExpGrammar } from "./test-grammars/RegExpGrammar.js"
6
7
 
7
8
  const log = console.log
8
9
 
@@ -24,26 +25,29 @@ function testBasic() {
24
25
  console.log(JSON.stringify(result, undefined, 4))
25
26
  }
26
27
 
27
-
28
28
  function testJsonParser() {
29
- const jsonString = jsonSample2
29
+ const jsonString = jsonSample1
30
30
 
31
31
  const grammar = buildGrammar(JsonGrammar, 'expression')
32
32
 
33
- function run() {
34
- const timer = new Timer()
35
- const result1 = grammar.parse(jsonString)
36
- timer.logAndRestart('Parse')
33
+ const iterations = 1000
34
+
35
+ let result1: any
36
+ let result2: any
37
37
 
38
- const result2 = JSON.parse(jsonString)
39
- timer.logAndRestart('JSON.Parse')
38
+ const timer = new Timer()
40
39
 
41
- log(JSON.stringify(result2, undefined, 4))
40
+ for (let i = 0; i < iterations; i++) {
41
+ result1 = grammar.parse(jsonString)
42
42
  }
43
+ timer.logAndRestart('grammar.Parse')
43
44
 
44
- for (let i = 0; i < 1; i++) {
45
- run()
45
+ for (let i = 0; i < iterations; i++) {
46
+ result2 = JSON.parse(jsonString)
46
47
  }
48
+ timer.logAndRestart('JSON.Parse')
49
+
50
+ log(JSON.stringify(result1, undefined, 4))
47
51
  }
48
52
 
49
53
  function testXmlParser() {
@@ -77,6 +81,23 @@ function testXmlParser() {
77
81
  log(JSON.stringify(parseTree, undefined, 4))
78
82
  }
79
83
 
84
+ async function testRegExpParser() {
85
+ //const regExpString = /^([+]?[1]?(1 )?[-.+]?\(?\d{1}[- .+]*\d{1}[- .+]*\d{1}\)?[- .+]*\d{1}[- .+]*\d{1}[- .+]*\d{1}[- .+]*\d{1}[- .+]*\d{1}[- .+]*\d{1}[- .+]*\d{1})$/.source
86
+ const regExpString = /^asdf{$/.source
87
+
88
+ const grammar = buildGrammar(RegExpGrammar, 'disjunction')
89
+
90
+ const parseTree = grammar.parse(regExpString)
91
+
92
+ const parseTreeJson = JSON.stringify(parseTree, undefined, 4)
93
+
94
+ log(parseTreeJson)
95
+
96
+ const { writeFile } = await import('fs/promises')
97
+
98
+ await writeFile('out/out.json', parseTreeJson)
99
+ }
100
+
80
101
 
81
102
  async function testParserError1() {
82
103
  const xmlData = `<hello> wo rld <!!! `
@@ -98,4 +119,6 @@ async function testParserError2() {
98
119
  console.log(JSON.stringify(result, undefined, 4))
99
120
  }
100
121
 
101
- testXmlParser()
122
+ //testJsonParser()
123
+
124
+ testRegExpParser()
@@ -2,7 +2,6 @@ import { Grammar, GrammarElement, Terminal } from "./GrammarComposer.js"
2
2
 
3
3
  export function parse(inputString: string, grammar: Grammar<any>) {
4
4
  const inputLength = inputString.length
5
- const maxElementId = grammar.maxElementId
6
5
 
7
6
  let bestFailedMatches: Terminal[] = []
8
7
  let bestFailedMatchesOffset = -1
@@ -134,13 +133,7 @@ export function parse(inputString: string, grammar: Grammar<any>) {
134
133
  })
135
134
  }
136
135
 
137
- nodes = [{
138
- name: grammarElement.name,
139
- startOffset: matchStartOffset,
140
- endOffset: matchEndOffset,
141
- sourceText: inputString.substring(matchStartOffset, matchEndOffset),
142
- children
143
- }]
136
+ nodes = children
144
137
  }
145
138
 
146
139
  const parseResult: ParseResult = {
@@ -268,8 +261,10 @@ export function parse(inputString: string, grammar: Grammar<any>) {
268
261
  const possibleMatches = bestFailedMatches.map(match => {
269
262
  if (match.type === 'StringTerminal') {
270
263
  return `'${match.content}'`
264
+ } else if (match.type === 'PatternTerminal') {
265
+ return `/${match.regExp.source}/`
271
266
  } else {
272
- return match.name
267
+ throw new Error(`Invalid match type: '${(match as any).type}'`)
273
268
  }
274
269
  })
275
270
 
@@ -1,7 +1,7 @@
1
1
  export const jsonSample1 = JSON.stringify([
2
2
  {
3
3
  "yo": 23,
4
- "man": "hey"
4
+ "man": "h\"ey"
5
5
  }
6
6
  ], undefined, 4)
7
7
 
@@ -11,58 +11,18 @@ export class JsonGrammar {
11
11
  this.arrayExpression
12
12
  )
13
13
 
14
- objectExpression = () => [
15
- this.openingCurlyBrace,
16
-
17
- G.possibly([
18
- this.objectPropertyExpression,
19
- G.zeroOrMore([this.comma, this.objectPropertyExpression])
20
- ]),
21
-
22
- this.closingCurlyBrace,
23
- ]
24
-
25
- objectPropertyExpression = () => [
26
- this.stringLiteral,
27
- this.colons,
28
- this.expression,
29
- ]
30
-
31
- arrayExpression = () => [
32
- this.openingSquareBracket,
33
-
34
- G.possibly([
35
- this.expression,
36
- G.zeroOrMore([this.comma, this.expression])
37
- ]),
38
-
39
- this.closingSquareBracket
40
- ]
41
-
42
- openingCurlyBrace = createPatternWithClearedWhitespace('{')
43
- closingCurlyBrace = createPatternWithClearedWhitespace('}')
44
-
45
- openingSquareBracket = createPatternWithClearedWhitespace('[')
46
- closingSquareBracket = createPatternWithClearedWhitespace(']')
47
-
48
- comma = createPatternWithClearedWhitespace(',')
49
- colons = createPatternWithClearedWhitespace(':')
50
-
51
14
  stringLiteral = G.pattern([
52
15
  zeroOrMoreWhitespace,
53
16
 
54
17
  '"',
55
18
 
56
- R.matches(
57
- R.captureAs('value',
58
- R.zeroOrMoreNonGreedy(R.anyChar)
59
- ),
60
- {
61
- ifNotPrecededBy: '\\'
62
- }
19
+ R.captureAs('value',
20
+ R.zeroOrMoreNonGreedy(R.anyChar)
63
21
  ),
64
22
 
65
- '"',
23
+ R.matches('"', {
24
+ ifNotPrecededBy: '\\'
25
+ }),
66
26
 
67
27
  zeroOrMoreWhitespace,
68
28
  ])
@@ -103,13 +63,50 @@ export class JsonGrammar {
103
63
 
104
64
  zeroOrMoreWhitespace,
105
65
  ])
66
+
67
+ objectExpression = () => [
68
+ this.openingCurlyBrace,
69
+
70
+ G.possibly([
71
+ this.objectPropertyExpression,
72
+ G.zeroOrMore([this.comma, this.objectPropertyExpression])
73
+ ]),
74
+
75
+ this.closingCurlyBrace,
76
+ ]
77
+
78
+ objectPropertyExpression = () => [
79
+ this.stringLiteral,
80
+ this.colons,
81
+ this.expression,
82
+ ]
83
+
84
+ arrayExpression = () => [
85
+ this.openingSquareBracket,
86
+
87
+ G.possibly([
88
+ this.expression,
89
+ G.zeroOrMore([this.comma, this.expression])
90
+ ]),
91
+
92
+ this.closingSquareBracket
93
+ ]
94
+
95
+ openingCurlyBrace = createPatternWithClearedWhitespace('{')
96
+ closingCurlyBrace = createPatternWithClearedWhitespace('}')
97
+
98
+ openingSquareBracket = createPatternWithClearedWhitespace('[')
99
+ closingSquareBracket = createPatternWithClearedWhitespace(']')
100
+
101
+ comma = createPatternWithClearedWhitespace(',')
102
+ colons = createPatternWithClearedWhitespace(':')
106
103
  }
107
104
 
108
- function createPatternWithClearedWhitespace(str: string) {
105
+ function createPatternWithClearedWhitespace(subpattern: R.Pattern) {
109
106
  return G.pattern([
110
107
  zeroOrMoreWhitespace,
111
108
 
112
- str,
109
+ subpattern,
113
110
 
114
111
  zeroOrMoreWhitespace
115
112
  ])