Skip to content

Commit

Permalink
Command line for --returnTypes changed to --returnTypes. Docs added. …
Browse files Browse the repository at this point in the history
…Small updates to generated_template.d.ts - mostly docs, but I think GrammarSource is better now, as is StartRules. Switched to opts file for building parser. Updated deps.
  • Loading branch information
hildjj committed Aug 6, 2024
1 parent 4157552 commit 349eb80
Show file tree
Hide file tree
Showing 10 changed files with 381 additions and 207 deletions.
75 changes: 66 additions & 9 deletions bin/generated_template.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,25 @@ export interface Location {
readonly offset: number;
}

export interface Stringable {
/**
* Anything that can successfully be converted to a string with `String()`
* so that it can be used in error messages.
*
* The GrammarLocation class in Peggy is a good example.
*/
export interface GrammarSourceObject extends Stringable {
readonly toString: () => string;
}

export interface GrammarSourceObject extends Stringable {
readonly source?: undefined | string | Stringable;
/**
* If specified, allows the grammar source to be embedded in a larger file
* at some offset.
*/
readonly offset?: undefined | ((loc: Location) => Location);
}

/**
* Most often, you just use a string with the file name.
*/
export type GrammarSource = string | GrammarSourceObject;

/** The `start` and `end` position's of an object within the source. */
Expand All @@ -32,41 +42,70 @@ export interface LocationRange {
readonly end: Location;
}

/**
* Expected a literal string, like `"foo"i`.
*/
export interface LiteralExpectation {
readonly type: "literal";
readonly text: string;
readonly ignoreCase: boolean;
}

/**
* Range of characters, like `a-z`
*/
export type ClassRange = [
start: string,
end: string,
]

export interface ClassParts extends Array<string | ClassRange> {
}

/**
* Expected a class, such as `[^acd-gz]i`
*/
export interface ClassExpectation {
readonly type: "class";
readonly parts: ClassParts;
readonly inverted: boolean;
readonly ignoreCase: boolean;
}

/**
* Expected any character, with `.`
*/
export interface AnyExpectation {
readonly type: "any";
}

/**
* Expected the end of input.
*/
export interface EndExpectation {
readonly type: "end";
}

/**
* Expected some other input. These are specified with a rule's
* "human-readable name", or with the `expected(message, location)`
* function.
*/
export interface OtherExpectation {
readonly type: "other";
readonly description: string;
}

export type Expectation =
| AnyExpectation
| ClassExpectation
| EndExpectation
| LiteralExpectation
| OtherExpectation;

/**
* Pass an array of these into `SyntaxError.prototype.format()`
*/
export interface SourceText {
/**
* Identifier of an input that was used as a grammarSource in parse().
Expand Down Expand Up @@ -96,16 +135,33 @@ export declare class SyntaxError extends Error {
found: string | null,
location: LocationRange,
);

/**
* With good sources, generates a feature-rich error message pointing to the
* error in the input.
* @param sources List of {source, text} objects that map to the input.
*/
format(sources: SourceText[]): string;
}

/**
* Trace execution of the parser.
*/
export interface ParserTracer {
trace: (event: ParserTracerEvent) => void;
}

export type ParserTracerEvent
= { readonly type: "rule.enter"; readonly rule: string; readonly location: LocationRange }
| { readonly type: "rule.fail"; readonly rule: string; readonly location: LocationRange }
= {
readonly type: "rule.enter";
readonly rule: string;
readonly location: LocationRange
}
| {
readonly type: "rule.fail";
readonly rule: string;
readonly location: LocationRange
}
| {
readonly type: "rule.match";
readonly rule: string;
Expand All @@ -114,8 +170,8 @@ export type ParserTracerEvent
readonly result: unknown;
};

export type StartRules = $$$StartRules$$$;
export interface ParseOptions<T extends StartRules = $$$DefaultStartRule$$$> {
export type StartRuleNames = $$$StartRules$$$;
export interface ParseOptions<T extends StartRuleNames = $$$DefaultStartRule$$$> {
/**
* String or object that will be attached to the each `LocationRange` object
* created by the parser. For example, this can be path to the parsed file
Expand All @@ -137,7 +193,8 @@ export interface ParseOptions<T extends StartRules = $$$DefaultStartRule$$$> {
[key: string]: unknown;
}

export declare const parse: typeof ParseFunction;
export declare const StartRules: StartRuleNames[];
export declare const SyntaxError: typeof _PeggySyntaxError;
export declare const parse: typeof ParseFunction;

// Overload of ParseFunction for each allowedStartRule
2 changes: 1 addition & 1 deletion bin/peggy-cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ class PeggyCLI extends Command {
"Generate a source map. If name is not specified, the source map will be named \"<input_file>.map\" if input is a file and \"source.map\" if input is a standard input. If the special filename `inline` is given, the sourcemap will be embedded in the output file as a data URI. If the filename is prefixed with `hidden:`, no mapping URL will be included so that the mapping can be specified with an HTTP SourceMap: header. This option conflicts with the `-t/--test` and `-T/--test-file` options unless `-o/--output` is also specified"
)
.option(
"--returnTypes <typeInfo>",
"--return-types <typeInfo>",
"Types returned for rules, as JSON object of the form {\"ruleName\": \"type\"}",
moreJSON
)
Expand Down
41 changes: 40 additions & 1 deletion docs/documentation.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ <h2 id="table-of-contents">Table of Contents</h2>
<li><a href="#error-reporting">Error Reporting</a></li>
</ul>
</li>
<li>
<a href="#typescript-types">Generating TypeScript Types</a>
</li>
</ul>
</li>
<li><a href="#using-the-parser">Using the Parser</a></li>
Expand Down Expand Up @@ -184,6 +187,12 @@ <h3 id="generating-a-parser-command-line">Command Line</h3>
<dd>Dependencies, in JSON object format with variable:module pairs. (Can be
specified multiple times).</dd>

<dt><code>--dts</code></dt>
<dd>Generate a .d.ts file next to the output .js file containing TypeScript
types for the generated parser. See <a href="#typescript-types">Generating
TypeScript Types</a> for more information.
</dd>

<dt><code>-e</code>, <code>--export-var &lt;variable&gt;</code></dt>
<dd>Name of a global variable into which the parser object is assigned to when
no module loader is detected.</dd>
Expand Down Expand Up @@ -223,6 +232,15 @@ <h3 id="generating-a-parser-command-line">Command Line</h3>
specified
</dd>

<dt><code>--return-types &lt;JSON object&gt;</code></dt>
<dd>If <code>--dts</code> is specified, the <code>typeInfo</code> provided
will be used to specify the return type of the given rules.
<code>typeInfo</code> should be specified as a JSON object whose keys are
rule names and whose values are strings containing the return type for that
rule. See <a href="#typescript-types">Generating TypeScript Types</a> for
more information.
</dd>

<dt><code>-S</code>, <code>--start-rule &lt;rule&gt;</code></dt>
<dd>When testing, use this rule as the start rule. Automatically added to
the allowedStartRules.</dd>
Expand Down Expand Up @@ -339,7 +357,7 @@ <h4 id="importing">Importing</h4>

<pre><code class="language-javascript">import peggy from "peggy";</code></pre>

<p>With some configurations of Typescript or other tools, you might need:</p>
<p>With some configurations of TypeScript or other tools, you might need:</p>

<pre><code class="language-javascript">import * as peggy from "peggy";</code></pre>

Expand Down Expand Up @@ -514,6 +532,27 @@ <h4 id="error-reporting">Error Reporting</h4>
<li><code>generate</code></li>
</ul>

<h3 id="typescript-types">Generating TypeScript Types</h3>
<p>If you are consuming the generated parser from TypeScript, it is useful for
there to be a .d.ts file next to the generated .js file that describes the
types used in the parser. To enable this, use a configuration file such as:</p>

<pre><code class="language-js">// MJS
export default {
input: "foo.peggy",
output: "foo.js",
dts: true,
returnTypes: {
foo: "string",
},
};</code></pre>

<p>If a rule name is in the allowedStartRules, but not in returnTypes,
<code>any</code> will be used as the return type for that rule.</p>
<p>Note that <code>--return-types &lt;JSON object&gt;</code> can be specified
on the command line; the use of a config file just makes quoting easier to get
correct.</p>

<h2 id="using-the-parser">Using the Parser</h2>

<p>To use the generated parser, import it using your selected module approach
Expand Down
2 changes: 1 addition & 1 deletion docs/js/test-bundle.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ module.exports = [
{
...require("@peggyjs/eslint-config/flat/modern"),
// All of these can use modern JS and node constructs
files: ["bin/*.js", "tools/**", "web-test/**"],
files: ["bin/*.js", "tools/**", "web-test/**", "src/*.mjs"],
},
{
files: ["lib/peg.d.ts"],
Expand Down
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
},
"scripts": {
"clean": "rimraf -g build browser bin/*.map && mkdir browser",
"parser": "node bin/peggy.js -o lib/parser.js --format commonjs --allowed-start-rules Grammar,ImportsAndSource src/parser.pegjs ",
"parser": "node bin/peggy.js -c src/opts.mjs",
"examples": "node bin/peggy.js -c docs/js/options.js docs/js/examples.peggy",
"set_version": "node ./tools/set_version",
"lint": "eslint .",
Expand Down Expand Up @@ -53,15 +53,15 @@
"start": "cd docs && npm start"
},
"devDependencies": {
"@peggyjs/eslint-config": "^4.0.3",
"@peggyjs/eslint-config": "^4.0.4",
"@rollup/plugin-commonjs": "^26.0.1",
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-multi-entry": "^6.0.1",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-typescript": "^11.1.6",
"@types/chai": "^4.3.11",
"@types/jest": "^29.5.12",
"@types/node": "^22.0.2",
"@types/node": "^22.1.0",
"chai": "^4.3.11",
"chai-like": "^1.1.1",
"copyfiles": "^2.4.1",
Expand All @@ -72,14 +72,14 @@
"glob": "^11.0.0",
"jest": "^29.7.0",
"rimraf": "^6.0.1",
"rollup": "^4.19.1",
"rollup": "^4.20.0",
"rollup-plugin-ignore": "1.0.10",
"source-map": "^0.8.0-beta.0",
"terser": "^5.31.3",
"ts-jest": "^29.2.3",
"ts-jest": "^29.2.4",
"tslib": "^2.6.3",
"typescript": "^5.5.4",
"typescript-eslint": "8.0.0"
"typescript-eslint": "8.0.1"
},
"dependencies": {
"@peggyjs/from-mem": "1.3.4",
Expand Down
Loading

0 comments on commit 349eb80

Please sign in to comment.