grammar-composer 0.6.2 → 0.7.0

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.
Files changed (49) hide show
  1. package/README.md +27 -19
  2. package/dist/parser/Builder.d.ts +3 -3
  3. package/dist/parser/Builder.d.ts.map +1 -1
  4. package/dist/parser/Builder.js +37 -37
  5. package/dist/parser/Builder.js.map +1 -1
  6. package/dist/parser/Grammar.d.ts +24 -24
  7. package/dist/parser/Grammar.d.ts.map +1 -1
  8. package/dist/parser/Grammar.js +11 -11
  9. package/dist/parser/Grammar.js.map +1 -1
  10. package/dist/parser/ParseError.js +6 -6
  11. package/dist/parser/ParseError.js.map +1 -1
  12. package/dist/parser/Parser.d.ts.map +1 -1
  13. package/dist/parser/Parser.js +36 -36
  14. package/dist/parser/Parser.js.map +1 -1
  15. package/dist/parser/StaticAnalysis.d.ts +3 -3
  16. package/dist/parser/StaticAnalysis.d.ts.map +1 -1
  17. package/dist/parser/StaticAnalysis.js +6 -6
  18. package/dist/parser/StaticAnalysis.js.map +1 -1
  19. package/dist/parser/{TerminalToText.d.ts → TerminalFormatter.d.ts} +2 -2
  20. package/dist/parser/TerminalFormatter.d.ts.map +1 -0
  21. package/dist/parser/{TerminalToText.js → TerminalFormatter.js} +2 -2
  22. package/dist/parser/TerminalFormatter.js.map +1 -0
  23. package/dist/tests/Test.js +6 -6
  24. package/dist/tests/Test.js.map +1 -1
  25. package/dist/tests/test-grammars/JsonGrammar.d.ts +3 -3
  26. package/dist/tests/test-grammars/JsonGrammar.d.ts.map +1 -1
  27. package/dist/tests/test-grammars/JsonGrammar.js +2 -2
  28. package/dist/tests/test-grammars/JsonGrammar.js.map +1 -1
  29. package/dist/tests/test-grammars/RegExpGrammar.d.ts +11 -11
  30. package/dist/tests/test-grammars/RegExpGrammar.d.ts.map +1 -1
  31. package/dist/tests/test-grammars/RegExpGrammar.js +2 -2
  32. package/dist/tests/test-grammars/RegExpGrammar.js.map +1 -1
  33. package/dist/tests/test-grammars/XmlGrammar.d.ts +1 -1
  34. package/dist/tests/test-grammars/XmlGrammar.d.ts.map +1 -1
  35. package/dist/tests/test-grammars/XmlGrammar.js +2 -2
  36. package/dist/tests/test-grammars/XmlGrammar.js.map +1 -1
  37. package/package.json +2 -2
  38. package/src/parser/Builder.ts +42 -42
  39. package/src/parser/Grammar.ts +36 -36
  40. package/src/parser/ParseError.ts +6 -6
  41. package/src/parser/Parser.ts +38 -38
  42. package/src/parser/StaticAnalysis.ts +20 -18
  43. package/src/parser/{TerminalToText.ts → TerminalFormatter.ts} +1 -1
  44. package/src/tests/Test.ts +6 -6
  45. package/src/tests/test-grammars/JsonGrammar.ts +2 -2
  46. package/src/tests/test-grammars/RegExpGrammar.ts +2 -2
  47. package/src/tests/test-grammars/XmlGrammar.ts +2 -2
  48. package/dist/parser/TerminalToText.d.ts.map +0 -1
  49. package/dist/parser/TerminalToText.js.map +0 -1
@@ -75,9 +75,9 @@ const quotedString = R.anyOf([
75
75
  "'"
76
76
  ]);
77
77
  //////////////////////////////////////////////////////////////////////////////////////////////
78
- // Wrapped nonterminal names
78
+ // Unfolded nonterminal list
79
79
  //////////////////////////////////////////////////////////////////////////////////////////////
80
- export const xmlGrammarUnwrappedNonterminalNames = [
80
+ export const xmlGrammarUnfoldedNonterminalNames = [
81
81
  'openingTagStart',
82
82
  'tagEnd',
83
83
  'declarationTagOpening',
@@ -1 +1 @@
1
- {"version":3,"file":"XmlGrammar.js","sourceRoot":"","sources":["../../../src/tests/test-grammars/XmlGrammar.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,0BAA0B,CAAA;AAC7C,OAAO,KAAK,CAAC,MAAM,iBAAiB,CAAA;AAEpC,MAAM,OAAO,UAAU;IACtB,QAAQ,GAAG,GAAG,EAAE,CAAC;QAChB,CAAC,CAAC,UAAU,CACX,CAAC,CAAC,KAAK,CACN,IAAI,CAAC,YAAY,EACjB,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,cAAc,CACnB,CACD;KACD,CAAA;IAED,YAAY,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QAC9B,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;KACjC,CAAC,CAAA;IAEF,UAAU,GAAG,GAAG,EAAE,CAAC;QAClB,IAAI,CAAC,eAAe;QAEpB,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC;QAE5B,IAAI,CAAC,MAAM;KACX,CAAA;IAED,eAAe,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QACjC,GAAG;QAEH,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC;QAEf,CAAC,CAAC,SAAS,CAAC,SAAS,EACpB,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,UAAU,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CACxE;QAED,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC;KAC1B,CAAC,CAAA;IAEF,MAAM,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QACxB,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC;QAE1B,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAE7B,GAAG;KACH,CAAC,CAAA;IAEF,SAAS,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QAC3B,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC;QAE1B,CAAC,CAAC,SAAS,CAAC,eAAe,EAC1B,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,UAAU,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CACxE;QAED,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC;QAE1B,CAAC,CAAC,QAAQ,CAAC;YACV,GAAG;YAEH,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC;YAE1B,YAAY;YAEZ,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC;SAC1B,CAAC;KACF,CAAC,CAAA;IAEF,UAAU,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QAC5B,IAAI;QAEJ,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC;QAE1B,CAAC,CAAC,SAAS,CAAC,SAAS,EACpB,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,UAAU,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CACpD;QAED,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC;QAE1B,GAAG;KACH,CAAC,CAAA;IAEF,cAAc,GAAG,GAAG,EAAE,CAAC;QACtB,IAAI,CAAC,qBAAqB;QAE1B,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,uBAAuB,CAAC;QAE1C,IAAI,CAAC,MAAM;KACX,CAAA;IAED,qBAAqB,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QACvC,IAAI;QAEJ,CAAC,CAAC,SAAS,CAAC,SAAS,EACpB,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,UAAU,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAC9D;QAED,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC;KAC1B,CAAC,CAAA;IAEF,uBAAuB,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QACzC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC;QAE1B,CAAC,CAAC,KAAK,CACN,CAAC,CAAC,SAAS,CAAC,eAAe,EAC1B,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,UAAU,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CACxE,EAED,YAAY,CACZ;QAED,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC;KAC1B,CAAC,CAAA;IAEF,OAAO,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QACzB,MAAM;QAEN,CAAC,CAAC,SAAS,CAAC,aAAa,EACxB,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,OAAO,CAAC,CAChC;QAED,KAAK;KACL,CAAC,CAAA;CACF;AAED,8FAA8F;AAC9F,6BAA6B;AAC7B,8FAA8F;AAC9F,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAC3B;IACC,GAAG;IACH,CAAC,CAAC,SAAS,CAAC,2BAA2B,EACtC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAClC;IACD,GAAG;CACH,EACD;IACC,GAAG;IACH,CAAC,CAAC,SAAS,CAAC,2BAA2B,EACtC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAClC;IACD,GAAG;CACH,CACD,CAAA;AAED,8FAA8F;AAC9F,4BAA4B;AAC5B,8FAA8F;AAC9F,MAAM,CAAC,MAAM,mCAAmC,GAA0C;IACzF,iBAAiB;IACjB,QAAQ;IACR,uBAAuB;CACvB,CAAA"}
1
+ {"version":3,"file":"XmlGrammar.js","sourceRoot":"","sources":["../../../src/tests/test-grammars/XmlGrammar.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.6.2",
3
+ "version": "0.7.0",
4
4
  "description": "Creates 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",
@@ -36,7 +36,7 @@
36
36
  "regexp-composer": "~0.6.1"
37
37
  },
38
38
  "devDependencies": {
39
- "@types/node": "~26.4.0",
39
+ "@types/node": "~26.4.1",
40
40
  "vitest": "~4.1.11"
41
41
  }
42
42
  }
@@ -1,7 +1,7 @@
1
1
  import { isArray, isFunction, isString } from '../utilities/Utilities.js'
2
2
 
3
3
  import { detectAndAnnotateOptionalNodes, detectAndErrorOnLeftRecursion } from './StaticAnalysis.js'
4
- import { Grammar, Nonterminal, GrammarElement, StringTerminal, Sequence, NonterminalReference, Production } from './Grammar.js'
4
+ import { Grammar, Nonterminal, GrammarNode, StringTerminal, Sequence, NonterminalReference, GrammarExpression } from './Grammar.js'
5
5
 
6
6
  /////////////////////////////////////////////////////////////////////////////////////////////////
7
7
  // Grammar builder method
@@ -12,7 +12,7 @@ export function buildGrammar<T extends GrammarDefinition>(
12
12
  options?: GrammarBuilderOptions<T>): Grammar<T> {
13
13
 
14
14
  options = {
15
- unwrappedNonterminalNames: [],
15
+ unfoldedNonterminalNames: [],
16
16
  ...options
17
17
  }
18
18
 
@@ -34,10 +34,10 @@ export function buildGrammar<T extends GrammarDefinition>(
34
34
  }
35
35
 
36
36
  const productionContent = objectProperty.call(definitionObject)
37
- const normalizedProduction = productionToGrammarElement(productionContent)
38
- const isUnwrappedNonterminal = options.unwrappedNonterminalNames?.includes(key) === true
37
+ const productionContentNode = grammarExpressionToNode(productionContent)
38
+ const isUnfoldedNonterminal = options.unfoldedNonterminalNames?.includes(key) === true
39
39
 
40
- const newNonterminal = nonterminal(key, normalizedProduction, isUnwrappedNonterminal)
40
+ const newNonterminal = nonterminal(key, productionContentNode, isUnfoldedNonterminal)
41
41
  const newOptionalNonterminal = {
42
42
  ...newNonterminal,
43
43
  optional: true,
@@ -57,7 +57,7 @@ export function buildGrammar<T extends GrammarDefinition>(
57
57
  }
58
58
 
59
59
  for (const [func, nonterminal] of nonterminalLookup) {
60
- const preparedContent = prepareGrammarElement(
60
+ const preparedContent = prepareGrammarNode(
61
61
  nonterminal.content,
62
62
  nonterminalLookup,
63
63
  optionalNonterminalLookup,
@@ -97,73 +97,73 @@ export function buildGrammar<T extends GrammarDefinition>(
97
97
  )
98
98
  }
99
99
 
100
- function prepareGrammarElement(
101
- rootElement: GrammarElement,
100
+ function prepareGrammarNode(
101
+ rootNode: GrammarNode,
102
102
  nonterminalLookup: Map<Function, Nonterminal>,
103
103
  optionalNonterminalLookup: Map<Function, Nonterminal>,
104
104
  getNewCacheId: () => number
105
- ): GrammarElement {
106
- function prepare(element: GrammarElement): GrammarElement {
107
- const setCacheIdIfNeeded = (element: GrammarElement) => {
108
- if (element.cached === true) {
109
- element.cacheId = getNewCacheId()
105
+ ): GrammarNode {
106
+ function prepare(node: GrammarNode): GrammarNode {
107
+ const setCacheIdIfNeeded = (node: GrammarNode) => {
108
+ if (node.cached === true) {
109
+ node.cacheId = getNewCacheId()
110
110
  }
111
111
 
112
- return element
112
+ return node
113
113
  }
114
114
 
115
- switch (element.type) {
115
+ switch (node.type) {
116
116
  case 'StringTerminal':
117
117
  case 'Nonterminal': {
118
118
  return setCacheIdIfNeeded({
119
- ...element
119
+ ...node
120
120
  })
121
121
  }
122
122
 
123
123
  case 'PatternTerminal': {
124
124
  return setCacheIdIfNeeded({
125
- ...element,
125
+ ...node,
126
126
  })
127
127
  }
128
128
 
129
129
  case 'Repetition': {
130
130
  return setCacheIdIfNeeded({
131
- ...element,
132
- content: prepare(element.content),
131
+ ...node,
132
+ content: prepare(node.content),
133
133
  })
134
134
  }
135
135
 
136
136
  case 'Sequence':
137
137
  case 'Choice': {
138
138
  return setCacheIdIfNeeded({
139
- ...element,
140
- members: element.members.map(element => prepare(element)),
139
+ ...node,
140
+ members: node.members.map(member => prepare(member)),
141
141
  })
142
142
  }
143
143
 
144
144
  case 'NonterminalReference': {
145
- const reference = element.reference
145
+ const reference = node.reference
146
146
 
147
147
  let nonterminal: Nonterminal | undefined
148
148
 
149
- if (element.optional) {
149
+ if (node.optional) {
150
150
  nonterminal = optionalNonterminalLookup.get(reference)
151
151
  } else {
152
152
  nonterminal = nonterminalLookup.get(reference)
153
153
  }
154
154
 
155
155
  if (!nonterminal) {
156
- throw new Error(`Couldn't resolve function reference in grammar element: ${JSON.stringify(element)}`)
156
+ throw new Error(`Couldn't resolve function reference in grammar node: ${JSON.stringify(node)}`)
157
157
  }
158
158
 
159
- if (element.cached === true) {
159
+ if (node.cached === true) {
160
160
  return {
161
161
  ...nonterminal,
162
162
 
163
163
  cached: true,
164
164
  cacheId: getNewCacheId(),
165
165
 
166
- grammarNonterminal: nonterminal.grammarNonterminal ?? nonterminal
166
+ canonicalNonterminal: nonterminal.canonicalNonterminal ?? nonterminal
167
167
  }
168
168
  } else {
169
169
  return nonterminal
@@ -172,7 +172,7 @@ function prepareGrammarElement(
172
172
  }
173
173
  }
174
174
 
175
- return prepare(rootElement)
175
+ return prepare(rootNode)
176
176
  }
177
177
 
178
178
  /////////////////////////////////////////////////////////////////////////////////////////////////
@@ -192,7 +192,7 @@ function stringTerminal(content: string): StringTerminal {
192
192
  }
193
193
  }
194
194
 
195
- function nonterminal(name: string, content: GrammarElement, unwrapped: boolean): Nonterminal {
195
+ function nonterminal(name: string, content: GrammarNode, unfolded: boolean): Nonterminal {
196
196
  if (name.length < 1) {
197
197
  throw new Error(`A nonterminal name must include at least 1 character.`)
198
198
  }
@@ -204,11 +204,11 @@ function nonterminal(name: string, content: GrammarElement, unwrapped: boolean):
204
204
 
205
205
  optional: false,
206
206
  cached: false,
207
- unwrapped,
207
+ unfolded,
208
208
  }
209
209
  }
210
210
 
211
- function sequence(members: GrammarElement[]): Sequence {
211
+ function sequence(members: GrammarNode[]): Sequence {
212
212
  return {
213
213
  type: 'Sequence',
214
214
  members,
@@ -218,27 +218,27 @@ function sequence(members: GrammarElement[]): Sequence {
218
218
  }
219
219
  }
220
220
 
221
- function unresolvedReference(reference: Function): NonterminalReference {
221
+ function unresolvedNonterminalReference(nonterminalReferenceFunction: Function): NonterminalReference {
222
222
  return {
223
223
  type: 'NonterminalReference',
224
- reference,
224
+ reference: nonterminalReferenceFunction,
225
225
  optional: false,
226
226
 
227
227
  cached: false,
228
228
  }
229
229
  }
230
230
 
231
- export function productionToGrammarElement(production: Production): GrammarElement {
232
- if (isString(production)) {
233
- return stringTerminal(production)
234
- } else if (isArray(production)) {
235
- const normalizedMembers = production.map(element => productionToGrammarElement(element))
231
+ export function grammarExpressionToNode(grammarExpression: GrammarExpression): GrammarNode {
232
+ if (isString(grammarExpression)) {
233
+ return stringTerminal(grammarExpression)
234
+ } else if (isArray(grammarExpression)) {
235
+ const memberNodes = grammarExpression.map(member => grammarExpressionToNode(member))
236
236
 
237
- return sequence(normalizedMembers)
238
- } else if (isFunction(production)) {
239
- return unresolvedReference(production)
237
+ return sequence(memberNodes)
238
+ } else if (isFunction(grammarExpression)) {
239
+ return unresolvedNonterminalReference(grammarExpression)
240
240
  } else {
241
- return production
241
+ return grammarExpression
242
242
  }
243
243
  }
244
244
 
@@ -246,7 +246,7 @@ export function productionToGrammarElement(production: Production): GrammarEleme
246
246
  // Builder type definitions
247
247
  /////////////////////////////////////////////////////////////////////////////////////////////////
248
248
  export interface GrammarBuilderOptions<T> {
249
- unwrappedNonterminalNames?: GrammarNonterminalNames<T>
249
+ unfoldedNonterminalNames?: GrammarNonterminalNames<T>
250
250
  }
251
251
 
252
252
  export type GrammarNonterminalNames<T> = (keyof T)[]
@@ -3,7 +3,7 @@ import { isArray } from '../utilities/Utilities.js'
3
3
 
4
4
  import { parse } from './Parser.js'
5
5
  import { validatePatternCaptureGroups } from './StaticAnalysis.js'
6
- import { productionToGrammarElement } from './Builder.js'
6
+ import { grammarExpressionToNode } from './Builder.js'
7
7
 
8
8
  /////////////////////////////////////////////////////////////////////////////////////////////////
9
9
  // Grammar class
@@ -28,7 +28,7 @@ export class Grammar<T> {
28
28
  return parse(text, this)
29
29
  }
30
30
 
31
- get rootElement() {
31
+ get rootNode() {
32
32
  return this.productions[this.startProductionName]
33
33
  }
34
34
  }
@@ -36,50 +36,50 @@ export class Grammar<T> {
36
36
  /////////////////////////////////////////////////////////////////////////////////////////////////
37
37
  // Exported grammar builder functions
38
38
  /////////////////////////////////////////////////////////////////////////////////////////////////
39
- export function zeroOrMore(content: Production): Repetition {
39
+ export function zeroOrMore(content: GrammarExpression): Repetition {
40
40
  return {
41
41
  type: 'Repetition',
42
- content: productionToGrammarElement(content),
42
+ content: grammarExpressionToNode(content),
43
43
  optional: true,
44
44
  cached: false,
45
45
  }
46
46
  }
47
47
 
48
- export function oneOrMore(content: Production): Repetition {
48
+ export function oneOrMore(content: GrammarExpression): Repetition {
49
49
  return {
50
50
  type: 'Repetition',
51
- content: productionToGrammarElement(content),
51
+ content: grammarExpressionToNode(content),
52
52
  optional: false,
53
53
  cached: false,
54
54
  }
55
55
  }
56
56
 
57
- export function anyOf(...members: Production[]): Choice {
57
+ export function anyOf(...members: GrammarExpression[]): Choice {
58
58
  if (members.length === 0) {
59
59
  throw new Error(`'anyOf' requires at least one member.`)
60
60
  }
61
61
 
62
- const normalizedMembers = members.map(member => productionToGrammarElement(member))
62
+ const memberNodes = members.map(member => grammarExpressionToNode(member))
63
63
 
64
64
  return {
65
65
  type: 'Choice',
66
- members: normalizedMembers,
66
+ members: memberNodes,
67
67
  optional: false,
68
68
  exhaustive: false,
69
69
  cached: false,
70
70
  }
71
71
  }
72
72
 
73
- export function bestOf(...members: Production[]): Choice {
73
+ export function bestOf(...members: GrammarExpression[]): Choice {
74
74
  if (members.length === 0) {
75
75
  throw new Error(`'bestOf' requires at least one member.`)
76
76
  }
77
77
 
78
- const normalizedMembers = members.map(member => productionToGrammarElement(member))
78
+ const memberNodes = members.map(member => grammarExpressionToNode(member))
79
79
 
80
80
  return {
81
81
  type: 'Choice',
82
- members: normalizedMembers,
82
+ members: memberNodes,
83
83
  optional: false,
84
84
  exhaustive: true,
85
85
 
@@ -87,8 +87,8 @@ export function bestOf(...members: Production[]): Choice {
87
87
  }
88
88
  }
89
89
 
90
- export function possibly<T extends Production>(content: Production): T {
91
- return { ...productionToGrammarElement(content), optional: true } as T
90
+ export function possibly<T extends GrammarExpression>(content: GrammarExpression): T {
91
+ return { ...grammarExpressionToNode(content), optional: true } as T
92
92
  }
93
93
 
94
94
  export function pattern(pattern: Pattern): PatternTerminal {
@@ -113,20 +113,20 @@ export function pattern(pattern: Pattern): PatternTerminal {
113
113
  }
114
114
  }
115
115
 
116
- export function cached<T extends Production>(content: Production): T {
117
- return { ...productionToGrammarElement(content), cached: true } as T
116
+ export function cached<T extends GrammarExpression>(content: GrammarExpression): T {
117
+ return { ...grammarExpressionToNode(content), cached: true } as T
118
118
  }
119
119
 
120
- export function uncached<T extends Production>(content: Production): T {
121
- return { ...productionToGrammarElement(content), cached: false } as T
120
+ export function uncached<T extends GrammarExpression>(content: GrammarExpression): T {
121
+ return { ...grammarExpressionToNode(content), cached: false } as T
122
122
  }
123
123
 
124
124
  /////////////////////////////////////////////////////////////////////////////////////////////////
125
125
  // Type definitions
126
126
  /////////////////////////////////////////////////////////////////////////////////////////////////
127
- export type Production = string | GrammarElement | (() => Production) | Production[]
127
+ export type GrammarExpression = string | GrammarNode | (() => GrammarExpression) | GrammarExpression[]
128
128
 
129
- export type GrammarElement =
129
+ export type GrammarNode =
130
130
  StringTerminal |
131
131
  PatternTerminal |
132
132
  Nonterminal |
@@ -135,60 +135,60 @@ export type GrammarElement =
135
135
  Choice |
136
136
  NonterminalReference
137
137
 
138
- interface GrammarElementBase {
138
+ interface GrammarNodeBase {
139
139
  type: string
140
140
  optional: boolean
141
141
 
142
142
  cached: boolean
143
143
  cacheId?: number
144
144
 
145
- // The name of the grammar property this element was assigned to, if any.
146
- // Used by the parser to refer to the element by name in error messages.
145
+ // The name of the grammar property this node was assigned to, if any.
146
+ // Used by the parser to refer to the node by name in error messages.
147
147
  name?: string
148
148
  }
149
149
 
150
150
  export type Terminal = StringTerminal | PatternTerminal
151
151
 
152
- export interface StringTerminal extends GrammarElementBase {
152
+ export interface StringTerminal extends GrammarNodeBase {
153
153
  type: 'StringTerminal'
154
154
  content: string
155
155
  }
156
156
 
157
- export interface PatternTerminal extends GrammarElementBase {
157
+ export interface PatternTerminal extends GrammarNodeBase {
158
158
  type: 'PatternTerminal'
159
159
  pattern: Pattern
160
160
  regExp: RegExp
161
161
  }
162
162
 
163
- export interface Nonterminal extends GrammarElementBase {
163
+ export interface Nonterminal extends GrammarNodeBase {
164
164
  type: 'Nonterminal'
165
165
  name: string
166
- content: GrammarElement
167
- unwrapped: boolean
166
+ content: GrammarNode
167
+ unfolded: boolean
168
168
 
169
169
  // The canonical nonterminal as defined in the grammar. Clones created for
170
170
  // optional references and cached references keep a reference to the original,
171
171
  // so identity comparisons work across clones.
172
- grammarNonterminal?: Nonterminal
172
+ canonicalNonterminal?: Nonterminal
173
173
  }
174
174
 
175
- export interface Sequence extends GrammarElementBase {
175
+ export interface Sequence extends GrammarNodeBase {
176
176
  type: 'Sequence'
177
- members: GrammarElement[]
177
+ members: GrammarNode[]
178
178
  }
179
179
 
180
- export interface Repetition extends GrammarElementBase {
180
+ export interface Repetition extends GrammarNodeBase {
181
181
  type: 'Repetition'
182
- content: GrammarElement
182
+ content: GrammarNode
183
183
  }
184
184
 
185
- export interface Choice extends GrammarElementBase {
185
+ export interface Choice extends GrammarNodeBase {
186
186
  type: 'Choice'
187
- members: GrammarElement[]
187
+ members: GrammarNode[]
188
188
  exhaustive: boolean
189
189
  }
190
190
 
191
- export interface NonterminalReference extends GrammarElementBase {
191
+ export interface NonterminalReference extends GrammarNodeBase {
192
192
  type: 'NonterminalReference'
193
193
  reference: Function
194
194
  }
@@ -1,6 +1,6 @@
1
1
  import type { Nonterminal, Terminal } from './Grammar.js'
2
2
  import { buildCaretSpacing, expandTabs, getLineAndColumn } from '../utilities/LineAndColumn.js'
3
- import { escapeChar, TerminalToText } from './TerminalToText.js'
3
+ import { escapeChar, TerminalFormatter } from './TerminalFormatter.js'
4
4
 
5
5
  /////////////////////////////////////////////////////////////////////////////////////////////////
6
6
  // Parse error class
@@ -145,10 +145,10 @@ function isRedundantCandidate(candidate: TerminalCandidate, candidates: Terminal
145
145
 
146
146
  // Compares nonterminals by their canonical grammar reference, because the same
147
147
  // production can be represented by multiple cloned instances during a parse.
148
- function stackIndexOf(productionStack: Nonterminal[], production: Nonterminal): number {
149
- const canonical = production.grammarNonterminal ?? production
148
+ function stackIndexOf(productionStack: Nonterminal[], nonterminal: Nonterminal): number {
149
+ const canonicalNonterminal = nonterminal.canonicalNonterminal ?? nonterminal
150
150
 
151
- return productionStack.findIndex(nonterminal => (nonterminal.grammarNonterminal ?? nonterminal) === canonical)
151
+ return productionStack.findIndex(nonterminal => (nonterminal.canonicalNonterminal ?? nonterminal) === canonicalNonterminal)
152
152
  }
153
153
 
154
154
  function areTerminalsEqual(a: any, b: any): boolean {
@@ -193,7 +193,7 @@ function stringifyFailedTerminal(failedMatch: FailedMatch): string {
193
193
  }
194
194
 
195
195
  const stringifiedLengthLimit = 100
196
- const terminalToText = new TerminalToText(stringifiedLengthLimit)
196
+ const terminalToText = new TerminalFormatter(stringifiedLengthLimit)
197
197
 
198
198
  return terminalToText.stringifyTerminal(terminal)
199
199
  }
@@ -236,7 +236,7 @@ function findCommonProductionPrefix(productionStacks: Nonterminal[][]): Nontermi
236
236
  }
237
237
 
238
238
  function areSameNonterminal(a: Nonterminal, b: Nonterminal): boolean {
239
- return (a.grammarNonterminal ?? a) === (b.grammarNonterminal ?? b)
239
+ return (a.canonicalNonterminal ?? a) === (b.canonicalNonterminal ?? b)
240
240
  }
241
241
 
242
242
  /////////////////////////////////////////////////////////////////////////////////////////////////