@cornjs/parser 0.11.0 → 0.11.1
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.
- package/README.md +21 -19
- package/dist/evaluator.d.ts +17 -0
- package/dist/evaluator.test.d.ts +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/lexer.d.ts +77 -0
- package/dist/parser.d.ts +85 -0
- package/dist/utils.d.ts +52 -0
- package/package.json +8 -14
package/README.md
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
|
-
# Corn.JS
|
|
2
|
-
|
|
3
|
-
Native Typescript implementation of the Corn parser.
|
|
4
|
-
|
|
5
|
-
This is compliant with the (currently unfinished) v0.11 spec.
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
1
|
+
# Corn.JS
|
|
2
|
+
|
|
3
|
+
Native Typescript implementation of the Corn parser.
|
|
4
|
+
|
|
5
|
+
This is compliant with the (currently unfinished) v0.11 spec.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
Add the `@cornjs/parser` package.
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { parse } from '@cornjs/parser';
|
|
15
|
+
|
|
16
|
+
const corn = "{ let $foo = 42 } in { value = $foo }";
|
|
17
|
+
const res = parse(corn);
|
|
18
|
+
|
|
19
|
+
if(res.ok) console.log(res.value); // { value: 42 }
|
|
20
|
+
```
|
|
21
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { RuleConfig } from "./parser";
|
|
2
|
+
import { Result } from "./utils";
|
|
3
|
+
export type Value = boolean | number | string | null | Value[] | {
|
|
4
|
+
[k: string]: Value;
|
|
5
|
+
};
|
|
6
|
+
export declare class Evaluator {
|
|
7
|
+
private inputs;
|
|
8
|
+
evaluate(rule: RuleConfig): Result<Record<string, Value>, string>;
|
|
9
|
+
private evaluateAssignBlock;
|
|
10
|
+
private evaluateObject;
|
|
11
|
+
private addAtPath;
|
|
12
|
+
private evaluateArray;
|
|
13
|
+
private evaluateString;
|
|
14
|
+
private trimMultilineString;
|
|
15
|
+
private evaluateValue;
|
|
16
|
+
private evaluateInput;
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { LexerError } from "./lexer";
|
|
2
|
+
import { Value } from "./evaluator";
|
|
3
|
+
import { Result } from "./utils";
|
|
4
|
+
export type { LexerError } from "./lexer";
|
|
5
|
+
export type { Value } from "./evaluator";
|
|
6
|
+
export type { Result } from "./utils";
|
|
7
|
+
/**
|
|
8
|
+
* Parses the provided corn string
|
|
9
|
+
* into an object.
|
|
10
|
+
*
|
|
11
|
+
* @typeParam T output object type
|
|
12
|
+
* @param corn input string
|
|
13
|
+
* @returns result containing output object on success,
|
|
14
|
+
* or error variant on any failure.
|
|
15
|
+
*/
|
|
16
|
+
export declare function parse<T extends Record<string, Value> = Record<string, Value>>(corn: string): Result<T, string | LexerError>;
|
package/dist/lexer.d.ts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { Result } from "./utils";
|
|
2
|
+
type LiteralChar = "{" | "}" | "[" | "]" | "=" | '"' | ".";
|
|
3
|
+
type LiteralString = ".." | "let" | "in" | "true" | "false" | "null";
|
|
4
|
+
export type Token = {
|
|
5
|
+
type: LiteralChar;
|
|
6
|
+
} | {
|
|
7
|
+
type: LiteralString;
|
|
8
|
+
} | {
|
|
9
|
+
type: "pathSegment";
|
|
10
|
+
value: string;
|
|
11
|
+
} | {
|
|
12
|
+
type: "integer";
|
|
13
|
+
value: number;
|
|
14
|
+
} | {
|
|
15
|
+
type: "float";
|
|
16
|
+
value: number;
|
|
17
|
+
} | {
|
|
18
|
+
type: "input";
|
|
19
|
+
value: string;
|
|
20
|
+
} | {
|
|
21
|
+
type: "charSequence";
|
|
22
|
+
value: string;
|
|
23
|
+
} | {
|
|
24
|
+
type: "charEscape";
|
|
25
|
+
value: string;
|
|
26
|
+
} | {
|
|
27
|
+
type: "unicodeEscape";
|
|
28
|
+
value: number;
|
|
29
|
+
} | {
|
|
30
|
+
type: "null";
|
|
31
|
+
};
|
|
32
|
+
export type LexerError = {
|
|
33
|
+
message: string;
|
|
34
|
+
span: Span;
|
|
35
|
+
};
|
|
36
|
+
export type TokenWithSpan = {
|
|
37
|
+
token: Token;
|
|
38
|
+
span: Span;
|
|
39
|
+
};
|
|
40
|
+
export type Span = {
|
|
41
|
+
startRow: number;
|
|
42
|
+
endRow: number;
|
|
43
|
+
startCol: number;
|
|
44
|
+
endCol: number;
|
|
45
|
+
};
|
|
46
|
+
export declare class Lexer {
|
|
47
|
+
private row;
|
|
48
|
+
private col;
|
|
49
|
+
private readonly MATCHERS;
|
|
50
|
+
tokenizeInput(inputString: string): Result<TokenWithSpan[], LexerError>;
|
|
51
|
+
private matchPathSegment;
|
|
52
|
+
private matchQuotedPathSegment;
|
|
53
|
+
private matchInteger;
|
|
54
|
+
private matchFloat;
|
|
55
|
+
private matchInterpolatedInput;
|
|
56
|
+
private matchCharEscape;
|
|
57
|
+
private matchUnicodeEscape;
|
|
58
|
+
private matchCharSequence;
|
|
59
|
+
private matchInput;
|
|
60
|
+
/**
|
|
61
|
+
* Returns a matcher function for a literal token.
|
|
62
|
+
|
|
63
|
+
* @param str Literal token value.
|
|
64
|
+
* @private
|
|
65
|
+
*/
|
|
66
|
+
private matchLiteral;
|
|
67
|
+
/**
|
|
68
|
+
* Applies a relative span to the current row/col
|
|
69
|
+
* to get an absolute span.
|
|
70
|
+
*
|
|
71
|
+
* @param relativeSpan
|
|
72
|
+
* @private
|
|
73
|
+
*/
|
|
74
|
+
private getAbsoluteSpan;
|
|
75
|
+
private setSpan;
|
|
76
|
+
}
|
|
77
|
+
export {};
|
package/dist/parser.d.ts
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { Token } from "./lexer";
|
|
2
|
+
import { Result } from "./utils";
|
|
3
|
+
export type RuleConfig = {
|
|
4
|
+
type: "config";
|
|
5
|
+
assignBlock?: RuleAssignBlock;
|
|
6
|
+
object: RuleObject;
|
|
7
|
+
};
|
|
8
|
+
export type RuleAssignBlock = {
|
|
9
|
+
type: "assignBlock";
|
|
10
|
+
assignments: RuleAssignment[];
|
|
11
|
+
};
|
|
12
|
+
export type RuleAssignment = {
|
|
13
|
+
type: "assignment";
|
|
14
|
+
key: string;
|
|
15
|
+
value: RuleValue;
|
|
16
|
+
};
|
|
17
|
+
export type RuleInput = {
|
|
18
|
+
type: "input";
|
|
19
|
+
value: string;
|
|
20
|
+
};
|
|
21
|
+
export type RuleBoolean = {
|
|
22
|
+
type: "boolean";
|
|
23
|
+
value: boolean;
|
|
24
|
+
};
|
|
25
|
+
export type RuleInteger = {
|
|
26
|
+
type: "integer";
|
|
27
|
+
value: number;
|
|
28
|
+
};
|
|
29
|
+
export type RuleFloat = {
|
|
30
|
+
type: "float";
|
|
31
|
+
value: number;
|
|
32
|
+
};
|
|
33
|
+
export type RuleString = {
|
|
34
|
+
type: "string";
|
|
35
|
+
value: RuleStringPart[];
|
|
36
|
+
};
|
|
37
|
+
export type RuleNull = {
|
|
38
|
+
type: "null";
|
|
39
|
+
};
|
|
40
|
+
export type RuleArray = {
|
|
41
|
+
type: "array";
|
|
42
|
+
values: RuleArrayItem[];
|
|
43
|
+
};
|
|
44
|
+
export type RuleObject = {
|
|
45
|
+
type: "object";
|
|
46
|
+
pairs: RuleObjectItem[];
|
|
47
|
+
};
|
|
48
|
+
export type RulePair = {
|
|
49
|
+
type: "pair";
|
|
50
|
+
path: RulePath;
|
|
51
|
+
value: RuleValue;
|
|
52
|
+
};
|
|
53
|
+
export type RulePath = {
|
|
54
|
+
type: "path";
|
|
55
|
+
value: string[];
|
|
56
|
+
};
|
|
57
|
+
export type RuleSpread = {
|
|
58
|
+
type: "spread";
|
|
59
|
+
value: string;
|
|
60
|
+
};
|
|
61
|
+
export type RuleCharSequence = {
|
|
62
|
+
type: "charSequence";
|
|
63
|
+
value: string;
|
|
64
|
+
};
|
|
65
|
+
export type RuleCharEscape = {
|
|
66
|
+
type: "charEscape";
|
|
67
|
+
value: string;
|
|
68
|
+
};
|
|
69
|
+
export type RuleUnicodeEscape = {
|
|
70
|
+
type: "unicodeEscape";
|
|
71
|
+
value: number;
|
|
72
|
+
};
|
|
73
|
+
export type RuleValue = RuleInput | RuleBoolean | RuleInteger | RuleFloat | RuleString | RuleArray | RuleObject | RuleNull;
|
|
74
|
+
export type RuleObjectItem = RulePair | RuleSpread;
|
|
75
|
+
export type RuleArrayItem = RuleValue | RuleSpread;
|
|
76
|
+
export type RuleStringPart = RuleCharSequence | RuleCharEscape | RuleUnicodeEscape | RuleInput;
|
|
77
|
+
/**
|
|
78
|
+
* Attempts to parse the provided token array
|
|
79
|
+
* into an AST of rules.
|
|
80
|
+
*
|
|
81
|
+
* @param tokens The token array.
|
|
82
|
+
* @returns A result containing the AST if successfully parsed,
|
|
83
|
+
* or an error message if not.
|
|
84
|
+
*/
|
|
85
|
+
export declare function parseTokens(tokens: Token[]): Result<RuleConfig, string>;
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents the outcome of a fallible operation,
|
|
3
|
+
* where the outcome can be either success value `T` or error `E`.
|
|
4
|
+
*/
|
|
5
|
+
export type Result<T, E> = {
|
|
6
|
+
ok: true;
|
|
7
|
+
value: T;
|
|
8
|
+
} | {
|
|
9
|
+
ok: false;
|
|
10
|
+
error: E;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Creates an ok (success) variant of `Result`.
|
|
14
|
+
* @param value
|
|
15
|
+
*/
|
|
16
|
+
export declare function ok<T, E>(value: T): Result<T, E>;
|
|
17
|
+
/**
|
|
18
|
+
* Creates an error variant of `Result`.
|
|
19
|
+
* @param error
|
|
20
|
+
*/
|
|
21
|
+
export declare function err<T, E>(error: E): Result<T, E>;
|
|
22
|
+
/**
|
|
23
|
+
* Throws an "unreachable" error if it ever runs.
|
|
24
|
+
*
|
|
25
|
+
* This is used as an exhaustive typeguard check on switch blocks,
|
|
26
|
+
* causing the type checker to error if a non-never type is passed in.
|
|
27
|
+
* @param _
|
|
28
|
+
*/
|
|
29
|
+
export declare function assertNever(_: never): never;
|
|
30
|
+
/**
|
|
31
|
+
* Determines if the given character is a numeric digit (0-9).
|
|
32
|
+
*
|
|
33
|
+
* @param {string} char - A single character to evaluate.
|
|
34
|
+
* @return {boolean} True if the character is a digit, otherwise false.
|
|
35
|
+
*/
|
|
36
|
+
export declare function isDigit(char: string): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Determines if the given character is a hex digit (0-F), case-insensitive.
|
|
39
|
+
*
|
|
40
|
+
* @param {string} char - A single character to evaluate.
|
|
41
|
+
* @return {boolean} True if the character is a digit, otherwise false.
|
|
42
|
+
*/
|
|
43
|
+
export declare function isHexDigit(char: string): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Determines if a given character is a letter (uppercase or lowercase) `[a-zA-Z]`.
|
|
46
|
+
*
|
|
47
|
+
* @param {string} char - The character to be checked.
|
|
48
|
+
* @return {boolean} Returns true if the character is a letter, otherwise false.
|
|
49
|
+
*/
|
|
50
|
+
export declare function isLetter(char: string): boolean;
|
|
51
|
+
export declare function isAlphanumeric(char: string): boolean;
|
|
52
|
+
export declare function isObject(val: unknown): val is Record<string | number | symbol, unknown>;
|
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"files": [
|
|
9
9
|
"dist"
|
|
10
10
|
],
|
|
11
|
-
"version": "0.11.
|
|
11
|
+
"version": "0.11.1",
|
|
12
12
|
"description": " Native Typescript Corn parser",
|
|
13
13
|
"homepage": "https://cornlang.dev",
|
|
14
14
|
"license": "MIT",
|
|
@@ -19,14 +19,13 @@
|
|
|
19
19
|
"bugs": {
|
|
20
20
|
"url": "https://github.com/jakestanger/corn/issues"
|
|
21
21
|
},
|
|
22
|
-
"keywords": [
|
|
23
|
-
"corn",
|
|
24
|
-
"config",
|
|
25
|
-
"parser",
|
|
26
|
-
"language",
|
|
27
|
-
"typescript"
|
|
28
|
-
],
|
|
22
|
+
"keywords": ["corn", "config", "parser", "language", "typescript"],
|
|
29
23
|
"main": "dist/index.js",
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "tsc",
|
|
26
|
+
"dev": "ts-node src",
|
|
27
|
+
"test": "jest"
|
|
28
|
+
},
|
|
30
29
|
"dependencies": {
|
|
31
30
|
"dedent": "^1.6.0"
|
|
32
31
|
},
|
|
@@ -48,10 +47,5 @@
|
|
|
48
47
|
},
|
|
49
48
|
"volta": {
|
|
50
49
|
"node": "22.17.1"
|
|
51
|
-
},
|
|
52
|
-
"scripts": {
|
|
53
|
-
"build": "tsc",
|
|
54
|
-
"dev": "ts-node src",
|
|
55
|
-
"test": "jest"
|
|
56
50
|
}
|
|
57
|
-
}
|
|
51
|
+
}
|