From 3ad0e1d2279f6f746ed3158276efed5be9922c24 Mon Sep 17 00:00:00 2001 From: Nikita Litvin Date: Mon, 5 Jun 2017 02:11:13 +0500 Subject: [PATCH] Add nearley 2.9 and moo 0.3 (#16937) * Add definitions for nearley 2.9 * Add definitions for moo 0.3 --- types/moo/index.d.ts | 109 +++++++++++++++++++++++++++++++++ types/moo/moo-tests.ts | 32 ++++++++++ types/moo/tsconfig.json | 23 +++++++ types/moo/tslint.json | 1 + types/nearley/index.d.ts | 99 ++++++++++++++++++++++++++++++ types/nearley/nearley-tests.ts | 18 ++++++ types/nearley/tsconfig.json | 23 +++++++ types/nearley/tslint.json | 1 + 8 files changed, 306 insertions(+) create mode 100644 types/moo/index.d.ts create mode 100644 types/moo/moo-tests.ts create mode 100644 types/moo/tsconfig.json create mode 100644 types/moo/tslint.json create mode 100644 types/nearley/index.d.ts create mode 100644 types/nearley/nearley-tests.ts create mode 100644 types/nearley/tsconfig.json create mode 100644 types/nearley/tslint.json diff --git a/types/moo/index.d.ts b/types/moo/index.d.ts new file mode 100644 index 0000000000..8bdc583cc9 --- /dev/null +++ b/types/moo/index.d.ts @@ -0,0 +1,109 @@ +// Type definitions for moo 0.3 +// Project: https://github.com/tjvr/moo#readme +// Definitions by: Nikita Litvin +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +export as namespace moo; + +/** + * Reserved token for indicating a parse fail. + */ +export const error: { error: true }; + +export function compile(rules: Rules): Lexer; + +export function states(states: {[x: string]: Rules}, start?: string): Lexer; + +export interface Rules { + [x: string]: RegExp | string | string[] | { + match: RegExp | string | string[], + /** + * Moo tracks detailed information about the input for you. + * It will track line numbers, as long as you apply the `lineBreaks: true` + * option to any tokens which might contain newlines. Moo will try to warn you if you forget to do this. + */ + lineBreaks?: boolean, + /** + * Moves the lexer to a new state, and pushes the old state onto the stack. + */ + push?: string, + /** + * Returns to a previous state, by removing one or more states from the stack. + */ + pop?: number, + /** + * Moves to a new state, but does not affect the stack. + */ + next?: string, + /** + * You can have a token type that both matches tokens and contains error values. + */ + error?: true + }; +} + +export interface Lexer { + /** + * Returns a string with a pretty error message. + */ + formatError(token: Token, message?: string): string; + /** + * Can be used by parsers like nearley to check whether a given token type can be parsed by this lexer. + */ + has(tokenType: string): boolean; + /** + * When you reach the end of Moo's internal buffer, next() will return undefined. + * You can always reset() it and feed it more data when that happens. + */ + next(): Token | undefined; + /** + * Empty the internal buffer of the lexer, and set the line, column, and offset counts back to their initial value. + */ + reset(chunk: string, state?: LexerState): void; + /** + * Returns current state, which you can later pass it as the second argument + * to reset() to explicitly control the internal state of the lexer. + */ + save(): LexerState; +} + +export interface Token { + /** + * Returns value of the token, or its type if value isn't available. + */ + toString(): string; + /** + * The name of the group, as passed to compile. + */ + type?: string; + /** + * The contents of the capturing group (or the whole match, if the token RegExp doesn't define a capture). + */ + value: string; + /** + * The number of bytes from the start of the buffer where the match starts. + */ + offset: number; + /** + * The total length of the match (value may be shorter if you have capturing groups). + */ + size: number; + /** + * The number of line breaks found in the match. (Always zero if this rule has lineBreaks: false.) + */ + lineBreaks: boolean; + /** + * The line number of the beginning of the match, starting from 1. + */ + line: number; + /** + * The column where the match begins, starting from 1. + */ + col: number; +} + +export interface LexerState { + line: number; + col: number; + state: string; +} diff --git a/types/moo/moo-tests.ts b/types/moo/moo-tests.ts new file mode 100644 index 0000000000..2c1205d26e --- /dev/null +++ b/types/moo/moo-tests.ts @@ -0,0 +1,32 @@ +import * as moo from 'moo'; + +let lexer = moo.compile({ + lparen: '(', + word: /[a-z]+/, + rparen: ')', + keyword: ['while', 'if', 'else', 'moo', 'cows'] +}); + +lexer = moo.states({ + main: { + strstart: {match: '`', push: 'lit'}, + ident: /\w+/, + lbrace: {match: '{', push: 'main'}, + rbrace: {match: '}', pop: 1}, + colon: ':', + space: {match: /\s+/, lineBreaks: true}, + }, + lit: { + interp: {match: '${', push: 'main'}, + escape: /\\./, + strend: {match: '`', pop: 1}, + const: {match: /(?:[^$`]|\$(?!\{))+/, lineBreaks: true}, + }, +}); + +lexer.reset('some line\n'); +let info = lexer.save(); +lexer.next(); +lexer.next(); +lexer.reset('a different line\n', info); +lexer.next(); diff --git a/types/moo/tsconfig.json b/types/moo/tsconfig.json new file mode 100644 index 0000000000..18a86a36a5 --- /dev/null +++ b/types/moo/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6", + "dom" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "moo-tests.ts" + ] +} diff --git a/types/moo/tslint.json b/types/moo/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/moo/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" } diff --git a/types/nearley/index.d.ts b/types/nearley/index.d.ts new file mode 100644 index 0000000000..3ea2a32ab5 --- /dev/null +++ b/types/nearley/index.d.ts @@ -0,0 +1,99 @@ +// Type definitions for nearley 2.9 +// Project: https://github.com/Hardmath123/nearley#readme +// Definitions by: Nikita Litvin +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +export as namespace nearley; + +export class Parser { + constructor(rules: Rule[], start: string, options?: ParserOptions); + constructor(grammar: Grammar, options?: ParserOptions); + /** + * The Parser object can be fed data in parts with .feed(data). + * You can then find an array of parsings with the .results property. + * If results is empty, then there are no parsings. + * If results contains multiple values, then that combination is ambiguous. + * + * @throws If there are no possible parsings, nearley will throw an error + * whose offset property is the index of the offending token. + */ + feed(chunk: string): void; + finish(): any[]; + restore(column: {[x: string]: any, lexerState: LexerState}): void; + save(): LexerState; + + grammar: Grammar; + options: ParserOptions; + lexer: Lexer; + lexerState?: LexerState; + current: number; + /** + * An array of possible parsings. Each element is the thing returned by your grammar. + * + * Note that this is undefined before the first feed() call. + * It isn't typed as `any[] | undefined` to spare you the null checks when it's definitely an array. + */ + results: any[]; + + /** + * Reserved token for indicating a parse fail. + */ + static fail: {}; +} + +export interface ParserOptions { + keepHistory?: boolean; + lexer?: Lexer; +} + +export class Rule { + constructor(name: any, symbols: any, postprocess: any); + toString(withCursorAt: any): any; + static highestId: number; +} + +export class Grammar { + constructor(rules: Rule[], start: string); + rules: Rule[]; + byName: {[x: string]: Rule}; +} + +export namespace Grammar { + function fromCompiled(rules: Rule[], start: string): Grammar; +} + +export interface Lexer { + /** + * Sets the internal buffer to chunk, and restore line/col/state info taken from save(). + */ + reset(chunk: string, state?: LexerState): void; + /** + * Returns e.g. {type, value, line, col, …}. Only the value attribute is required. + */ + next(): Token | undefined; + /** + * Returns an object describing the current line/col etc. This allows us + * to preserve this information between feed() calls, and also to support Parser#rewind(). + * The exact structure is lexer-specific; nearley doesn't care what's in it. + */ + save(): LexerState; + /** + * Returns a string with an error message describing the line/col of the offending token. + * You might like to include a preview of the line in question. + */ + formatError(token: Token): string; + /** + * Returns true if the lexer can emit tokens with that name. + * Used to resolve %-specifiers in compiled nearley grammars. + */ + has(tokenType: string): boolean; +} + +export interface Token { + [x: string]: any; + value: string; +} + +export interface LexerState { + [x: string]: any; +} diff --git a/types/nearley/nearley-tests.ts b/types/nearley/nearley-tests.ts new file mode 100644 index 0000000000..7741df617f --- /dev/null +++ b/types/nearley/nearley-tests.ts @@ -0,0 +1,18 @@ +import { Parser, Grammar, Rule, Lexer } from 'nearley'; + +declare const parserRules: Rule[]; +declare const parserStart: string; +declare const lexer: Lexer; +declare const grammar: Grammar; + +let parser = new Parser(parserRules, parserStart, { lexer, keepHistory: false }); +parser = new Parser(grammar); + +try { + parser.feed("<123>"); + if (parser.results) { + console.log(parser.results[0]); + } +} catch (error) { + console.log(error); +} diff --git a/types/nearley/tsconfig.json b/types/nearley/tsconfig.json new file mode 100644 index 0000000000..9a4feb8763 --- /dev/null +++ b/types/nearley/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6", + "dom" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "nearley-tests.ts" + ] +} diff --git a/types/nearley/tslint.json b/types/nearley/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/nearley/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" }