0
# Parser Generation
1
2
Code generation system that creates standalone parser modules in various formats (CommonJS, AMD, plain JavaScript) from processed grammars. The generated parsers are self-contained and can run independently of Jison.
3
4
## Capabilities
5
6
### Source Code Generation
7
8
Generate complete parser source code that can be saved to files and used independently.
9
10
```javascript { .api }
11
/**
12
* Generate parser source code
13
* @param options - Generation options including module format and name
14
* @returns Generated parser source code as string
15
*/
16
generate(options);
17
```
18
19
Options object properties:
20
- **moduleName**: Name for the generated parser (default: "parser")
21
- **moduleType**: Format type - "commonjs", "amd", or "js" (default: "commonjs")
22
- **debug**: Include debug information in generated code
23
24
**Usage Examples:**
25
26
```javascript
27
const jison = require("jison");
28
29
const grammar = {
30
"lex": {
31
"rules": [["\\s+", ""], ["[a-zA-Z]+", "return 'WORD';"]]
32
},
33
"bnf": {
34
"list": [["list WORD", "$$ = $1 + ' ' + $2;"], ["WORD", "$$ = $1;"]]
35
}
36
};
37
38
const generator = new jison.Generator(grammar);
39
40
// Generate CommonJS module
41
const commonjsCode = generator.generate({
42
moduleName: "WordParser",
43
moduleType: "commonjs"
44
});
45
46
// Save to file
47
require('fs').writeFileSync('word-parser.js', commonjsCode);
48
49
// Use generated parser
50
const parser = require('./word-parser');
51
const result = parser.parse("hello world");
52
```
53
54
### CommonJS Module Generation
55
56
Generate parser as a CommonJS module with exports for Node.js environments.
57
58
```javascript { .api }
59
/**
60
* Generate CommonJS module source
61
* @param options - Module generation options
62
* @returns CommonJS module source code with exports
63
*/
64
generateCommonJSModule(options);
65
```
66
67
Generated CommonJS modules export:
68
- `parser` - The parser instance
69
- `Parser` - The parser constructor
70
- `parse` - Convenience function that calls parser.parse
71
- `main` - Main function for CLI usage
72
73
**Usage Examples:**
74
75
```javascript
76
const generator = new jison.Generator(grammar);
77
const moduleCode = generator.generateCommonJSModule({
78
moduleName: "MyParser"
79
});
80
81
// Generated code can be used as:
82
// const { parse, Parser } = require('./my-parser');
83
// const result = parse(input);
84
```
85
86
### AMD Module Generation
87
88
Generate parser as an AMD (Asynchronous Module Definition) module for browser environments with RequireJS.
89
90
```javascript { .api }
91
/**
92
* Generate AMD module source
93
* @param options - AMD module generation options
94
* @returns AMD module source code
95
*/
96
generateAMDModule(options);
97
```
98
99
**Usage Examples:**
100
101
```javascript
102
const generator = new jison.Generator(grammar);
103
const amdCode = generator.generateAMDModule({
104
moduleName: "BrowserParser"
105
});
106
107
// Generated AMD module can be used as:
108
// define(['./browser-parser'], function(parser) {
109
// return parser.parse(input);
110
// });
111
```
112
113
### Plain JavaScript Generation
114
115
Generate parser as plain JavaScript that works in any environment.
116
117
```javascript { .api }
118
/**
119
* Generate plain JavaScript module
120
* @param options - JavaScript generation options
121
* @returns Plain JavaScript parser code
122
*/
123
generateModule(options);
124
```
125
126
**Usage Examples:**
127
128
```javascript
129
const generator = new jison.Generator(grammar);
130
const jsCode = generator.generate({
131
moduleType: "js",
132
moduleName: "GlobalParser"
133
});
134
135
// Generated code creates a global variable that can be used as:
136
// var result = GlobalParser.parse(input);
137
```
138
139
## Parser Runtime Interface
140
141
Generated parsers implement a consistent runtime interface regardless of the generation format.
142
143
### Generated Parser Object
144
145
```javascript { .api }
146
/**
147
* Generated parser instance structure
148
*/
149
interface GeneratedParser {
150
/** Parse input string and return result or throw error */
151
parse(input: string): any;
152
153
/** Shared state object accessible in semantic actions */
154
yy: object;
155
156
/** Associated lexer instance (if lexer was generated) */
157
lexer?: Lexer;
158
159
/** Symbol name to number mapping */
160
symbols_: Record<string, number>;
161
162
/** Terminal number to name mapping */
163
terminals_: Record<number, string>;
164
165
/** Internal production rules representation */
166
productions_: Array<[number, number]>;
167
168
/** LR parsing table */
169
table: Array<Record<number, number | number[]>>;
170
171
/** Default actions by state */
172
defaultActions: Record<number, number[]>;
173
174
/** Handle parse errors */
175
parseError(str: string, hash: ErrorHash): void;
176
177
/** Semantic action execution function */
178
performAction(yytext: string, yyleng: number, yylineno: number,
179
yy: object, yystate: number, $$: any[], _$: any[]): any;
180
}
181
182
/**
183
* Token location information
184
*/
185
interface LocationInfo {
186
first_line: number; // Starting line number
187
last_line: number; // Ending line number
188
first_column: number; // Starting column number
189
last_column: number; // Ending column number
190
range?: [number, number]; // Character range in input
191
}
192
193
/**
194
* Parse error information
195
*/
196
interface ErrorHash {
197
text: string; // Matched text
198
token: string; // Terminal token
199
line: number; // Line number
200
loc: LocationInfo; // Location details
201
expected: string[]; // Expected tokens
202
recoverable: boolean; // Whether error is recoverable
203
}
204
```
205
206
### Runtime Usage
207
208
Generated parsers can be used immediately after generation:
209
210
```javascript
211
// Create parser instance
212
const parser = generator.createParser();
213
214
// Parse input
215
try {
216
const result = parser.parse("2 + 3 * 4");
217
console.log("Parse result:", result);
218
} catch (error) {
219
console.error("Parse failed:", error.message);
220
if (error.hash) {
221
console.error("At line:", error.hash.line);
222
console.error("Expected:", error.hash.expected.join(", "));
223
}
224
}
225
226
// Access parser internals
227
console.log("Symbols:", Object.keys(parser.symbols_));
228
console.log("Productions:", parser.productions_.length);
229
```
230
231
## Code Generation Options
232
233
### Module Naming
234
235
Control the name of the generated parser module and its components.
236
237
```javascript
238
const options = {
239
moduleName: "Calculator", // Creates Calculator variable/export
240
moduleType: "commonjs"
241
};
242
243
const code = generator.generate(options);
244
// Generated code exports Calculator parser
245
```
246
247
### Debug Mode
248
249
Include additional debugging information in generated parsers.
250
251
```javascript
252
const options = {
253
debug: true,
254
moduleType: "commonjs"
255
};
256
257
const debugCode = generator.generate(options);
258
// Generated parser includes:
259
// - Detailed error messages
260
// - State transition logging
261
// - Conflict resolution information
262
```
263
264
### Custom Module Template
265
266
Advanced users can customize the module generation template:
267
268
```javascript
269
// Override module generation methods
270
const customGenerator = Object.create(jison.Generator.prototype);
271
customGenerator.generateModule = function(options) {
272
// Custom module generation logic
273
return customModuleTemplate;
274
};
275
```
276
277
## File Output Patterns
278
279
### Single File Output
280
281
Generate complete self-contained parser in a single file:
282
283
```javascript
284
const fs = require('fs');
285
const parser = new jison.Generator(grammar);
286
const code = parser.generate({ moduleType: 'commonjs' });
287
288
fs.writeFileSync('generated-parser.js', code);
289
290
// Use the generated parser
291
const generatedParser = require('./generated-parser');
292
const result = generatedParser.parse(input);
293
```
294
295
### Multiple File Output
296
297
For complex parsers, consider splitting into multiple files:
298
299
```javascript
300
// Generate parser
301
const parserCode = generator.generate({ moduleType: 'commonjs' });
302
303
// Generate lexer separately if needed
304
const lexerCode = generator.lexer.generateModule();
305
306
fs.writeFileSync('parser.js', parserCode);
307
fs.writeFileSync('lexer.js', lexerCode);
308
```
309
310
## Performance Considerations
311
312
### Table Compression
313
314
Jison automatically compresses parsing tables for optimal size:
315
316
- Removes duplicate entries
317
- Uses variable assignment for repeated patterns
318
- Minimizes generated code size
319
- Optimizes for V8 engine performance
320
321
### Memory Usage
322
323
Generated parsers are optimized for memory efficiency:
324
325
- Compact table representation
326
- Shared action functions
327
- Minimal runtime overhead
328
- Efficient symbol mapping
329
330
**Monitoring generated parser size:**
331
332
```javascript
333
const code = generator.generate(options);
334
console.log(`Generated parser size: ${code.length} characters`);
335
console.log(`Estimated gzipped size: ~${Math.round(code.length * 0.3)} bytes`);
336
```
337
338
## Error Handling in Generated Parsers
339
340
Generated parsers include comprehensive error handling:
341
342
### Parse Error Recovery
343
344
```javascript
345
// Generated parsers can handle syntax errors
346
try {
347
const result = parser.parse("2 + + 3"); // Invalid syntax
348
} catch (error) {
349
console.log("Parse error:", error.message);
350
// "Parse error on line 1: Unexpected '+' at position 4"
351
}
352
```
353
354
### Custom Error Handling
355
356
Override error handling in generated parsers:
357
358
```javascript
359
const parser = generator.createParser();
360
361
parser.yy.parseError = function(str, hash) {
362
console.log("Custom error handler:", str);
363
throw new Error(`Parse failed: ${str}`);
364
};
365
```