APG Lite Parser
apg-lite is a lightweight JavaScript parser for ABNF (Augmented Backus-Naur Form) grammars, supporting a simplified subset of SABNF operators. It functions strictly as a parser, requiring grammar objects to be pre-generated using `apg-js` (version 4.3.0 or higher) with its `--lite` option. Currently at version 1.0.5, it parses only JavaScript strings, a key distinction from `apg-js` which handles arbitrary arrays of positive integers. The library retains only User-Defined Terminals (UDT), positive look-ahead (AND), and negative look-ahead (NOT) operators from the SABNF superset. It offers simplified AST manipulation, parse tree tracing for debugging, and statistics collection for profiling, all encapsulated within a single ECMAScript Module (ESM) compatible JavaScript file. The package is actively maintained, with a release cadence driven by bug fixes and minor enhancements, as demonstrated by recent updates to its robust, dependency-free URI parser.
Common errors
-
ReferenceError: require is not defined
cause Attempting to use CommonJS `require()` in an ECMAScript Module (ESM) context or a browser where `apg-lite` is loaded via standard script tags.fixFor Node.js, ensure your project or file is configured for ESM (e.g., `"type": "module"` in `package.json` or using `.mjs` file extensions) and use `import` statements. For browsers, use `<script src="..."></script>` for `web-parser.js`. -
SyntaxError: Cannot use import statement outside a module
cause Using an `import` statement in a Node.js file that is treated as CommonJS (e.g., `.js` file without `"type": "module"` in `package.json`).fixEither change your Node.js project to use ESM by adding `"type": "module"` to `package.json`, or rename the file to have a `.mjs` extension. Alternatively, if bundling for a browser, ensure your bundler supports ESM. -
TypeError: Parser is not a constructor
cause Incorrectly importing or accessing the `Parser` class/function from `apg-lite`, or attempting to use a CommonJS `require()` result as a constructor when it's an ESM export.fixVerify the correct ESM import path (e.g., `import { Parser } from 'apg-lite/lib/parser'`) and ensure your environment supports ESM. If `Parser` is a factory function, use `Parser()` instead of `new Parser()`.
Warnings
- breaking apg-lite is a parser *only*. It does not generate grammars. Grammar objects must be pre-generated using `apg-js` (v4.3.0+) with the `--lite` option. Directly feeding ABNF definitions to `apg-lite` will not work.
- breaking apg-lite only parses JavaScript strings. It does not support parsing arbitrary arrays of positive integers, a feature available in the full `apg-js` library.
- breaking apg-lite supports only three SABNF superset operators: User-Defined Terminals (UDT), positive look-ahead (AND), and negative look-ahead (NOT). Grammars utilizing other SABNF operators (e.g., semantic validation, case-sensitive/insensitive string literals) will not be correctly processed or will fail.
- gotcha Version 1.0.5 fixed a critical bug in the URI grammar definition where previous versions incorrectly allowed empty strings for IPv4 octets. Relying on pre-1.0.5 URI parsing behavior may lead to incorrectly validated URIs.
Install
-
npm install apg-lite -
yarn add apg-lite -
pnpm add apg-lite
Imports
- Parser
const { Parser } = require('apg-lite/lib/parser')import { Parser } from 'apg-lite/lib/parser' - UriParser
const { UriParser } = require('apg-lite/uri-app/UriParser')import { UriParser } from 'apg-lite/uri-app/UriParser' - webParserScript
import { Parser } from 'apg-lite/lib/web-parser'<script src="./node_modules/apg-lite/lib/web-parser.js"></script>
Quickstart
import { UriParser } from 'apg-lite/uri-app/UriParser';
const uriStrings = [
'http://user:pass@host:80/path?query#fragment',
'mailto:john.doe@example.com',
'ftp://ftp.example.com/dir/file.txt',
'//example.org/schema-relative/path',
'data:text/plain;base64,SGVsbG8sIFdvcmxkIQ==',
'' // Empty string for demonstration
];
console.log('Parsing various URI strings:');
uriStrings.forEach(uriStr => {
try {
const parser = new UriParser(uriStr);
const result = parser.parse();
if (result.success) {
console.log(`\nURI: '${uriStr}'`);
console.log(' Parse successful. Result:', JSON.stringify(result.ast, null, 2));
} else {
console.error(`\nURI: '${uriStr}'`);
console.error(' Parse failed. Error:', result.error);
}
} catch (e) {
console.error(`\nError parsing URI '${uriStr}':`, e.message);
}
});