yini-parser 1.0.0-alpha.1 → 1.0.0-alpha.3
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 -10
- package/dist/YINI.d.ts +21 -0
- package/dist/{src/YINI.js → YINI.js} +7 -7
- package/dist/config/env.d.ts +34 -0
- package/dist/config/env.js +62 -0
- package/dist/core/ErrorDataHandler.d.ts +60 -0
- package/dist/core/YINIVisitor.d.ts +149 -0
- package/dist/core/objectBuilder.d.ts +6 -0
- package/dist/core/types.d.ts +59 -0
- package/dist/grammar/YiniLexer.d.ts +68 -0
- package/dist/grammar/YiniParser.d.ts +284 -0
- package/dist/grammar/YiniParserVisitor.d.ts +143 -0
- package/dist/index.d.ts +1 -0
- package/dist/{src/index.js → index.js} +17 -9
- package/dist/parseEntry.d.ts +2 -0
- package/dist/{src/parseEntry.js → parseEntry.js} +10 -0
- package/dist/parsers/extractHeaderParts.d.ts +31 -0
- package/dist/parsers/extractSignificantYiniLine.d.ts +9 -0
- package/dist/parsers/parseBoolean.d.ts +5 -0
- package/dist/parsers/parseNull.d.ts +2 -0
- package/dist/parsers/parseNumber.d.ts +6 -0
- package/dist/parsers/parseSectionHeader.d.ts +13 -0
- package/dist/parsers/parseString.d.ts +2 -0
- package/dist/utils/pathAndFileName.d.ts +5 -0
- package/dist/utils/string.d.ts +42 -0
- package/dist/utils/system.d.ts +7 -0
- package/dist/{src/utils → utils}/system.js +2 -2
- package/dist/yiniHelpers.d.ts +44 -0
- package/package.json +25 -26
- package/dist/src/config/env.js +0 -15
- package/dist/tests/integration/1-core-parsing/parse-bigger-section-nesting-as-object.test.js +0 -83
- package/dist/tests/integration/1-core-parsing/parse-section-nesting-w-classic-markers.test.js +0 -170
- package/dist/tests/integration/1-core-parsing/parse-section-nesting-w-nsh-markers.test.js +0 -27
- package/dist/tests/integration/1-core-parsing/read some values from level 1 and 2.test.js +0 -77
- package/dist/tests/integration/1-core-parsing/throw on bad section heads.test.js +0 -162
- package/dist/tests/integration/10-special-validation-modes/validation-modes.test.js +0 -38
- package/dist/tests/integration/2-file-structure-and-error/able to parse mixed case filenames.test.js +0 -72
- package/dist/tests/integration/2-file-structure-and-error/throw error on bad file extensions.test.js +0 -36
- package/dist/tests/integration/2-file-structure-and-error/throw error parsing bad content.test.js +0 -80
- package/dist/tests/smoke/A-general-smoke.test.js +0 -259
- package/dist/tests/smoke/B-parse-inline-smoke.test.js +0 -270
- package/dist/tests/smoke/C-traverse-file-smoke.test.js +0 -141
- package/dist/tests/smoke/D-parse-file-smoke.test.js +0 -134
- package/dist/tests/unit/parsers/extractHeaderParts.unit.test.js +0 -490
- package/dist/tests/unit/parsers/parseSectionHeader-classic.unit.test.js +0 -421
- package/dist/tests/unit/parsers/parseSectionHeader-nsh.unit.test.js +0 -436
- package/dist/tests/unit/parsers/parseSectionHeader-throw-on-invalid.unit.test.js +0 -168
- package/dist/tests/unit/utils/utils-pathAndFileName.unit.test.js +0 -80
- package/dist/tests/unit/utils/utils-string.unit.test.js +0 -185
- package/dist/tests/unit/yiniHelpers.unit.test.js +0 -306
- /package/dist/{src/core → core}/ErrorDataHandler.js +0 -0
- /package/dist/{src/core → core}/YINIVisitor.js +0 -0
- /package/dist/{src/core → core}/objectBuilder.js +0 -0
- /package/dist/{src/core → core}/types.js +0 -0
- /package/dist/{src/grammar → grammar}/YiniLexer.js +0 -0
- /package/dist/{src/grammar → grammar}/YiniParser.js +0 -0
- /package/dist/{src/grammar → grammar}/YiniParserVisitor.js +0 -0
- /package/dist/{src/parsers → parsers}/extractHeaderParts.js +0 -0
- /package/dist/{src/parsers → parsers}/extractSignificantYiniLine.js +0 -0
- /package/dist/{src/parsers → parsers}/parseBoolean.js +0 -0
- /package/dist/{src/parsers → parsers}/parseNull.js +0 -0
- /package/dist/{src/parsers → parsers}/parseNumber.js +0 -0
- /package/dist/{src/parsers → parsers}/parseSectionHeader.js +0 -0
- /package/dist/{src/parsers → parsers}/parseString.js +0 -0
- /package/dist/{src/utils → utils}/pathAndFileName.js +0 -0
- /package/dist/{src/utils → utils}/string.js +0 -0
- /package/dist/{src/yiniHelpers.js → yiniHelpers.js} +0 -0
package/README.md
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
# YINI Parser – TypeScript
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/yini-parser) [](https://github.com/YINI-lang/yini-parser-typescript/actions/workflows/run-all-tests.yml)
|
|
4
|
+
|
|
5
|
+
> ⚠️ This package is in **alpha**. The API and features may change. Not all parts of the YINI specification are implemented yet.
|
|
4
6
|
|
|
5
|
-
**YINI Parser
|
|
7
|
+
**YINI Parser in TypeScript** — a runtime library for Node.js.
|
|
8
|
+
A parser / reader for the [YINI configuration file format](https://github.com/YINI-lang/YINI-spec).
|
|
6
9
|
|
|
7
|
-
|
|
8
|
-
|
|
10
|
+
This library implements the official YINI specification using TypeScript + ANTLR4.
|
|
11
|
+
|
|
12
|
+
YINI is a simple, human-friendly configuration format inspired by INI and JSON.
|
|
9
13
|
|
|
10
14
|
---
|
|
11
15
|
|
|
12
16
|
## ✨ Features
|
|
13
|
-
- Simple
|
|
17
|
+
- Simple syntax (supports both strict and lenient modes).
|
|
14
18
|
- Familiar config file style (inspired by INI, YAML, TOML).
|
|
15
19
|
- Easy programmatic usage.
|
|
16
20
|
- Only the `YINI` class is exported; all internal details are private.
|
|
@@ -18,7 +22,7 @@ https://github.com/YINI-lang/YINI-spec
|
|
|
18
22
|
### Limitations
|
|
19
23
|
Not all features of the full YINI specification are implemented yet.
|
|
20
24
|
|
|
21
|
-
See [FEATURE-CHECKLIST.md](
|
|
25
|
+
See [FEATURE-CHECKLIST.md](https://github.com/YINI-lang/yini-parser-typescript/blob/main/FEATURE-CHECKLIST.md) for the current list of implemented YINI features.
|
|
22
26
|
|
|
23
27
|
---
|
|
24
28
|
|
|
@@ -88,7 +92,7 @@ Parses YINI code from a string.
|
|
|
88
92
|
|
|
89
93
|
Returns a JavaScript object representing the parsed configuration (YINI content).
|
|
90
94
|
|
|
91
|
-
### `YINI.parseFile(
|
|
95
|
+
### `YINI.parseFile(filePath: string, strictMode?: boolean, bailSensitivity: 'auto' | 0 | 1 | 2 = "auto", includeMetaData = false): object`
|
|
92
96
|
|
|
93
97
|
Parses YINI code from a file.
|
|
94
98
|
- `filePath`: Path to the `.yini` file.
|
|
@@ -99,7 +103,14 @@ Returns a JavaScript object representing the parsed YINI configuration file.
|
|
|
99
103
|
---
|
|
100
104
|
|
|
101
105
|
## Example Output
|
|
102
|
-
|
|
106
|
+
```js
|
|
107
|
+
{
|
|
108
|
+
Database: {
|
|
109
|
+
host: "localhost",
|
|
110
|
+
port: 5432
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
103
114
|
|
|
104
115
|
---
|
|
105
116
|
|
package/dist/YINI.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { TJSObject } from './core/types';
|
|
2
|
+
/**
|
|
3
|
+
* This class is the public API, which exposes only parse(..) and
|
|
4
|
+
* parseFile(..), rest of the implementation details are hidden.
|
|
5
|
+
* @note Only parse and parseFile are public.
|
|
6
|
+
*/
|
|
7
|
+
export default class YINI {
|
|
8
|
+
static filePath: string;
|
|
9
|
+
/**
|
|
10
|
+
* @param yiniContent YINI code as a string, can be multiple lines.
|
|
11
|
+
* @note The order of properties (members) in each JavaScript object (section) may differ from the order in the input YINI content.
|
|
12
|
+
* @returns The parsed JavaScript object.
|
|
13
|
+
*/
|
|
14
|
+
static parse: (yiniContent: string, strictMode?: boolean, bailSensitivity?: "auto" | 0 | 1 | 2, includeMetaData?: boolean) => TJSObject;
|
|
15
|
+
/**
|
|
16
|
+
* @param yiniFile Path to the YINI file.
|
|
17
|
+
* @note The order of properties (members) in each JavaScript object (section) may differ from the order in the input YINI file.
|
|
18
|
+
* @returns The parsed JavaScript object.
|
|
19
|
+
*/
|
|
20
|
+
static parseFile: (filePath: string, strictMode?: boolean, bailSensitivity?: "auto" | 0 | 1 | 2, includeMetaData?: boolean) => TJSObject;
|
|
21
|
+
}
|
|
@@ -15,7 +15,7 @@ const system_1 = require("./utils/system");
|
|
|
15
15
|
*/
|
|
16
16
|
class YINI {
|
|
17
17
|
}
|
|
18
|
-
YINI.
|
|
18
|
+
YINI.filePath = ''; // Used in error reporting.
|
|
19
19
|
/**
|
|
20
20
|
* @param yiniContent YINI code as a string, can be multiple lines.
|
|
21
21
|
* @note The order of properties (members) in each JavaScript object (section) may differ from the order in the input YINI content.
|
|
@@ -66,25 +66,25 @@ YINI.parse = (yiniContent, strictMode = false, bailSensitivity = 'auto', include
|
|
|
66
66
|
return result;
|
|
67
67
|
};
|
|
68
68
|
/**
|
|
69
|
-
* @param yiniFile
|
|
69
|
+
* @param yiniFile Path to the YINI file.
|
|
70
70
|
* @note The order of properties (members) in each JavaScript object (section) may differ from the order in the input YINI file.
|
|
71
71
|
* @returns The parsed JavaScript object.
|
|
72
72
|
*/
|
|
73
|
-
YINI.parseFile = (
|
|
73
|
+
YINI.parseFile = (filePath, strictMode = false, bailSensitivity = 'auto', includeMetaData = false) => {
|
|
74
74
|
(0, system_1.debugPrint)('Current directory = ' + process.cwd());
|
|
75
|
-
if ((0, pathAndFileName_1.getFileNameExtension)(
|
|
75
|
+
if ((0, pathAndFileName_1.getFileNameExtension)(filePath).toLowerCase() !== '.yini') {
|
|
76
76
|
console.error('Invalid file extension for YINI file:');
|
|
77
|
-
console.error(`"${
|
|
77
|
+
console.error(`"${filePath}"`);
|
|
78
78
|
console.log('File does not have a valid ".yini" extension (case-insensitive).');
|
|
79
79
|
throw new Error('Error: Unexpected file extension for YINI file');
|
|
80
80
|
}
|
|
81
|
-
let content = fs_1.default.readFileSync(
|
|
81
|
+
let content = fs_1.default.readFileSync(filePath, 'utf8');
|
|
82
82
|
let hasNoNewlineAtEOF = false;
|
|
83
83
|
if (!content.endsWith('\n')) {
|
|
84
84
|
content += '\n';
|
|
85
85
|
hasNoNewlineAtEOF = true;
|
|
86
86
|
}
|
|
87
|
-
YINI.
|
|
87
|
+
YINI.filePath = filePath;
|
|
88
88
|
let level = 0;
|
|
89
89
|
// if (bailSensitivity === 'auto' && !strictMode) level = 0
|
|
90
90
|
// if (bailSensitivity === 'auto' && strictMode) level = 1
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NODE_ENV - Defacto Node.js modes (environments)
|
|
3
|
+
*
|
|
4
|
+
* Used in many JS frameworks and tools, for special purposes.
|
|
5
|
+
* Some even only know 'production' and treat everything else as 'development'.
|
|
6
|
+
* Also Jest sets NODE_ENV automatically to 'test'.
|
|
7
|
+
*/
|
|
8
|
+
type TNodeEnv = 'development' | 'production' | 'test';
|
|
9
|
+
/**
|
|
10
|
+
* APP_ENV - More custom envs (more finer-grained control) for this project.
|
|
11
|
+
* @note Since this is a library (as opposed to a Web/App), we don't use "staging".
|
|
12
|
+
*/
|
|
13
|
+
type TAppEnv = 'local' | 'ci' | 'production';
|
|
14
|
+
declare const localNodeEnv: TNodeEnv;
|
|
15
|
+
declare const localAppEnv: TAppEnv;
|
|
16
|
+
/** Are we running in the environment "development"? Will be based on the (global) environment variable process.env.NODE_ENV. */
|
|
17
|
+
export declare const isDevEnv: () => boolean;
|
|
18
|
+
/** Are we running in the environment "production"? Will be based on the (global) environment variable process.env.NODE_ENV. */
|
|
19
|
+
export declare const isProdEnv: () => boolean;
|
|
20
|
+
/** Are we running in the environment "test"? Will be based on the (global) variable process.env.NODE_ENV. */
|
|
21
|
+
export declare const isTestEnv: () => boolean;
|
|
22
|
+
/** Will be based on the local argument when this process was launched.
|
|
23
|
+
* @returns True if the DEV flag is set.
|
|
24
|
+
* @example npm run start -- isDev=1
|
|
25
|
+
* @example node dist/index.js isDev=1
|
|
26
|
+
*/
|
|
27
|
+
export declare const isDev: () => boolean;
|
|
28
|
+
/** Will be based on the local argument when this process was launched.
|
|
29
|
+
* @returns True if the DEBUG flag is set.
|
|
30
|
+
* @example npm run start -- isDebug=1
|
|
31
|
+
* @example node dist/index.js isDebug=1
|
|
32
|
+
*/
|
|
33
|
+
export declare const isDebug: () => boolean;
|
|
34
|
+
export { localNodeEnv, localAppEnv };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.localAppEnv = exports.localNodeEnv = exports.isDebug = exports.isDev = exports.isTestEnv = exports.isProdEnv = exports.isDevEnv = void 0;
|
|
4
|
+
const localNodeEnv = (process.env.NODE_ENV || 'production');
|
|
5
|
+
exports.localNodeEnv = localNodeEnv;
|
|
6
|
+
const localAppEnv = (process.env.APP_ENV || 'production');
|
|
7
|
+
exports.localAppEnv = localAppEnv;
|
|
8
|
+
// export const initEnvs = () => {
|
|
9
|
+
// const localNodeEnv = (process.env.NODE_ENV || 'production') as TNodeEnv
|
|
10
|
+
// const localAppEnv = (process.env?.APP_ENV || 'production') as TAppEnv
|
|
11
|
+
// return { localNodeEnv, localAppEnv }
|
|
12
|
+
// }
|
|
13
|
+
// const { localNodeEnv, localAppEnv } = initEnvs()
|
|
14
|
+
/** Are we running in the environment "development"? Will be based on the (global) environment variable process.env.NODE_ENV. */
|
|
15
|
+
const isDevEnv = () => localNodeEnv === 'development';
|
|
16
|
+
exports.isDevEnv = isDevEnv;
|
|
17
|
+
/** Are we running in the environment "production"? Will be based on the (global) environment variable process.env.NODE_ENV. */
|
|
18
|
+
const isProdEnv = () => localNodeEnv === 'production';
|
|
19
|
+
exports.isProdEnv = isProdEnv;
|
|
20
|
+
/** Are we running in the environment "test"? Will be based on the (global) variable process.env.NODE_ENV. */
|
|
21
|
+
const isTestEnv = () => localNodeEnv === 'test';
|
|
22
|
+
exports.isTestEnv = isTestEnv;
|
|
23
|
+
/** Will be based on the local argument when this process was launched.
|
|
24
|
+
* @returns True if the DEV flag is set.
|
|
25
|
+
* @example npm run start -- isDev=1
|
|
26
|
+
* @example node dist/index.js isDev=1
|
|
27
|
+
*/
|
|
28
|
+
const isDev = () => {
|
|
29
|
+
const len = process.argv.length;
|
|
30
|
+
// NOTE: We will start with index 2, since the first element will be
|
|
31
|
+
// execPath. The second element will be the path to the
|
|
32
|
+
// JavaScript file being executed.
|
|
33
|
+
for (let i = 2; i < len; i++) {
|
|
34
|
+
const val = process.argv[i] || '';
|
|
35
|
+
if (val.toLowerCase() === 'isdev=1' ||
|
|
36
|
+
val.toLowerCase() === 'isdev=true') {
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return false;
|
|
41
|
+
};
|
|
42
|
+
exports.isDev = isDev;
|
|
43
|
+
/** Will be based on the local argument when this process was launched.
|
|
44
|
+
* @returns True if the DEBUG flag is set.
|
|
45
|
+
* @example npm run start -- isDebug=1
|
|
46
|
+
* @example node dist/index.js isDebug=1
|
|
47
|
+
*/
|
|
48
|
+
const isDebug = () => {
|
|
49
|
+
const len = process.argv.length;
|
|
50
|
+
// NOTE: We will start with index 2, since the first element will be
|
|
51
|
+
// execPath. The second element will be the path to the
|
|
52
|
+
// JavaScript file being executed.
|
|
53
|
+
for (let i = 2; i < len; i++) {
|
|
54
|
+
const val = process.argv[i] || '';
|
|
55
|
+
if (val.toLowerCase() === 'isdebug=1' ||
|
|
56
|
+
val.toLowerCase() === 'isdebug=true') {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return false;
|
|
61
|
+
};
|
|
62
|
+
exports.isDebug = isDebug;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { TIssueType, TPersistThreshold } from './types';
|
|
2
|
+
interface IIssuePayload {
|
|
3
|
+
type: TIssueType;
|
|
4
|
+
msgWhat: string;
|
|
5
|
+
start: {
|
|
6
|
+
line: number;
|
|
7
|
+
column: number;
|
|
8
|
+
};
|
|
9
|
+
end?: {
|
|
10
|
+
line?: number;
|
|
11
|
+
column?: number;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* This class handles all error/notice reporting and processes exit/throwing.
|
|
16
|
+
*/
|
|
17
|
+
export declare class ErrorDataHandler {
|
|
18
|
+
private persistThreshold;
|
|
19
|
+
private numFatalErrors;
|
|
20
|
+
private numInternalErrors;
|
|
21
|
+
private numSyntaxErrors;
|
|
22
|
+
private numSyntaxWarnings;
|
|
23
|
+
private numNotices;
|
|
24
|
+
private numInfos;
|
|
25
|
+
/** '1-Abort-on-Errors' is the default.
|
|
26
|
+
|
|
27
|
+
Below is from the YINI spec:
|
|
28
|
+
**Abort Sensitivity Levels** while parsing a YINI document:
|
|
29
|
+
(AKA severity threshold)
|
|
30
|
+
- Level 0 = ignore errors and try parse anyway (may remap falty key/section names)
|
|
31
|
+
- Level 1 = abort on errors only
|
|
32
|
+
- Level 2 = abort even on warnings
|
|
33
|
+
*/
|
|
34
|
+
constructor(threshold?: TPersistThreshold);
|
|
35
|
+
makeIssuePayload: (type: TIssueType, msgWhat: string, lineNum: number, startCol: number, endCol: number) => IIssuePayload;
|
|
36
|
+
/**
|
|
37
|
+
* After pushing processing may continue or exit, depending on the error
|
|
38
|
+
* and/or the bail threshold (that can be optionally set my the user).
|
|
39
|
+
*
|
|
40
|
+
* @note This function MIGHT result in a return, throw, or exit depending
|
|
41
|
+
* on the bail policy (set my the user).
|
|
42
|
+
*
|
|
43
|
+
* @param ctx
|
|
44
|
+
* @param type
|
|
45
|
+
* @param msgWhat Name of the specific error or what failed. E.g. "Key already exists in this section scope".
|
|
46
|
+
* @param msgWhy More details and more specific info about the issue/error.
|
|
47
|
+
* @param msgHint Hint or HUMBLE description on how to fix the issue.
|
|
48
|
+
*/
|
|
49
|
+
pushOrBail: (ctx: any, type: TIssueType, msgWhat: string, msgWhy?: string, msgHint?: string) => void;
|
|
50
|
+
private emitFatalError;
|
|
51
|
+
private emitInternalError;
|
|
52
|
+
private emitSyntaxError;
|
|
53
|
+
private emitSyntaxWarning;
|
|
54
|
+
private emitNotice;
|
|
55
|
+
private emitInfo;
|
|
56
|
+
getNumOfErrors(): number;
|
|
57
|
+
getNumOfWarnings(): number;
|
|
58
|
+
getNumOfInfoAndNotices(): number;
|
|
59
|
+
}
|
|
60
|
+
export {};
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { Boolean_literalContext, ElementContext, ElementsContext, List_in_bracketsContext, ListContext, Member_colon_listContext, MemberContext, Null_literalContext, Number_literalContext, Object_literalContext, ObjectMemberContext, ObjectMemberListContext, Section_membersContext, SectionContext, String_concatContext, String_literalContext, Terminal_lineContext, ValueContext, YiniContext } from '../grammar/YiniParser.js';
|
|
2
|
+
import YiniParserVisitor from '../grammar/YiniParserVisitor';
|
|
3
|
+
import { ErrorDataHandler } from './ErrorDataHandler';
|
|
4
|
+
export type TDataType = undefined | 'String' | 'Number-Integer' | 'Number-Float' | 'Boolean' | 'Null' | 'Object' | 'List';
|
|
5
|
+
/**
|
|
6
|
+
* This interface defines a complete generic visitor for a parse tree produced
|
|
7
|
+
* by `YiniParser`.
|
|
8
|
+
*
|
|
9
|
+
* @param <IResult> The return type of the visit operation. Use `void` for
|
|
10
|
+
* operations with no return type.
|
|
11
|
+
*/
|
|
12
|
+
export default class YINIVisitor<IResult> extends YiniParserVisitor<IResult> {
|
|
13
|
+
private reversedTree;
|
|
14
|
+
private errorHandler;
|
|
15
|
+
private isStrict;
|
|
16
|
+
private lastActiveSectionAtLevels;
|
|
17
|
+
private lastActiveSectionNameAtLevels;
|
|
18
|
+
private numOfLevelOnes;
|
|
19
|
+
private level;
|
|
20
|
+
private prevLevel;
|
|
21
|
+
private prevSectionName;
|
|
22
|
+
private meta_numOfSections;
|
|
23
|
+
private meta_numOfMembers;
|
|
24
|
+
private meta_numOfChains;
|
|
25
|
+
private meta_maxLevelSection;
|
|
26
|
+
constructor(errorHandler: ErrorDataHandler, isStrict: boolean);
|
|
27
|
+
private pushOnTree;
|
|
28
|
+
private getDepthOfLevels;
|
|
29
|
+
private setLastActiveSection;
|
|
30
|
+
/**
|
|
31
|
+
* Visit a parse tree produced by `YiniParser.yini`.
|
|
32
|
+
* @param ctx the parse tree
|
|
33
|
+
* @return the visitor result
|
|
34
|
+
*/
|
|
35
|
+
visitYini: (ctx: YiniContext, isStrict?: boolean) => any;
|
|
36
|
+
/**
|
|
37
|
+
* Will visit here on EVERY section.
|
|
38
|
+
* @param ctx the parse tree
|
|
39
|
+
* @returns { [sectionName]: sectionObj }
|
|
40
|
+
*/
|
|
41
|
+
visitSection: (ctx: SectionContext) => any;
|
|
42
|
+
/**
|
|
43
|
+
* Visit a parse tree produced by `YiniParser.terminal_line`.
|
|
44
|
+
* @param ctx the parse tree
|
|
45
|
+
* @return the visitor result
|
|
46
|
+
*/
|
|
47
|
+
visitTerminal_line?: (ctx: Terminal_lineContext) => IResult;
|
|
48
|
+
/**
|
|
49
|
+
* Visit a parse tree produced by `YiniParser.section_members`.
|
|
50
|
+
* In here will mount object onto members object.
|
|
51
|
+
* @param ctx the parse tree
|
|
52
|
+
* @returns { key: value, ... }
|
|
53
|
+
*/
|
|
54
|
+
visitSection_members: (ctx: Section_membersContext) => any;
|
|
55
|
+
/**
|
|
56
|
+
* Visit every single section or member (any key-value pair such as
|
|
57
|
+
* key=value or key=[...] etc.).
|
|
58
|
+
* @returns {
|
|
59
|
+
type: resultType,
|
|
60
|
+
key: resultKey,
|
|
61
|
+
value: resultValue,
|
|
62
|
+
}: IResult
|
|
63
|
+
*/
|
|
64
|
+
visitMember: (ctx: MemberContext) => IResult;
|
|
65
|
+
/**
|
|
66
|
+
* Visit a parse tree produced by `YiniParser.member_colon_list`.
|
|
67
|
+
* @param ctx the parse tree
|
|
68
|
+
* @return the visitor result
|
|
69
|
+
*/
|
|
70
|
+
visitMember_colon_list: (ctx: Member_colon_listContext) => IResult;
|
|
71
|
+
/**
|
|
72
|
+
* Visit a parse tree produced by `YiniParser.value`.
|
|
73
|
+
* @param ctx the parse tree
|
|
74
|
+
* @return the visitor result
|
|
75
|
+
*/
|
|
76
|
+
visitValue: (ctx: ValueContext) => any;
|
|
77
|
+
/**
|
|
78
|
+
* Visit a parse tree produced by `YiniParser.string_literal`.
|
|
79
|
+
* @param ctx the parse tree
|
|
80
|
+
* @return the visitor result
|
|
81
|
+
*/
|
|
82
|
+
visitString_literal: (ctx: String_literalContext) => IResult;
|
|
83
|
+
/**
|
|
84
|
+
* Visit a parse tree produced by `YiniParser.number_literal`.
|
|
85
|
+
* @param ctx the parse tree
|
|
86
|
+
* @return the visitor result
|
|
87
|
+
*/
|
|
88
|
+
visitNumber_literal: (ctx: Number_literalContext) => IResult;
|
|
89
|
+
/**
|
|
90
|
+
* Visit a parse tree produced by `YiniParser.boolean_literal`.
|
|
91
|
+
* @param ctx the parse tree
|
|
92
|
+
* @return the visitor result
|
|
93
|
+
*/
|
|
94
|
+
visitBoolean_literal: (ctx: Boolean_literalContext) => IResult;
|
|
95
|
+
/**
|
|
96
|
+
* Visit a parse tree produced by `YiniParser.null_literal`.
|
|
97
|
+
* @param ctx the parse tree
|
|
98
|
+
* @return the visitor result
|
|
99
|
+
*/
|
|
100
|
+
visitNull_literal: (ctx: Null_literalContext) => IResult;
|
|
101
|
+
/**
|
|
102
|
+
* Visit a parse tree produced by `YiniParser.object_literal`.
|
|
103
|
+
* @param ctx the parse tree
|
|
104
|
+
* @return the visitor result
|
|
105
|
+
*/
|
|
106
|
+
visitObject_literal: (ctx: Object_literalContext) => IResult;
|
|
107
|
+
/**
|
|
108
|
+
* Visit a parse tree produced by `YiniParser.objectMemberList`.
|
|
109
|
+
* @param ctx the parse tree
|
|
110
|
+
* @return the visitor result
|
|
111
|
+
*/
|
|
112
|
+
visitObjectMemberList: (ctx: ObjectMemberListContext) => IResult;
|
|
113
|
+
/**
|
|
114
|
+
* Visit a parse tree produced by `YiniParser.objectMember`.
|
|
115
|
+
* @param ctx the parse tree
|
|
116
|
+
* @return the visitor result
|
|
117
|
+
*/
|
|
118
|
+
visitObjectMember: (ctx: ObjectMemberContext) => IResult;
|
|
119
|
+
/**
|
|
120
|
+
* Visit a parse tree produced by `YiniParser.list`.
|
|
121
|
+
* @param ctx the parse tree
|
|
122
|
+
* @return the visitor result
|
|
123
|
+
*/
|
|
124
|
+
visitList: (ctx: ListContext) => IResult;
|
|
125
|
+
/**
|
|
126
|
+
* Visit a parse tree produced by `YiniParser.list_in_brackets`.
|
|
127
|
+
* @param ctx the parse tree
|
|
128
|
+
* @return the visitor result
|
|
129
|
+
*/
|
|
130
|
+
visitList_in_brackets: (ctx: List_in_bracketsContext) => IResult;
|
|
131
|
+
/**
|
|
132
|
+
* Visit a parse tree produced by `YiniParser.elements`.
|
|
133
|
+
* @param ctx the parse tree
|
|
134
|
+
* @return the visitor result
|
|
135
|
+
*/
|
|
136
|
+
visitElements?: (ctx: ElementsContext) => IResult;
|
|
137
|
+
/**
|
|
138
|
+
* Visit a parse tree produced by `YiniParser.element`.
|
|
139
|
+
* @param ctx the parse tree
|
|
140
|
+
* @return the visitor result
|
|
141
|
+
*/
|
|
142
|
+
visitElement: (ctx: ElementContext) => IResult;
|
|
143
|
+
/**
|
|
144
|
+
* Visit a parse tree produced by `YiniParser.string_concat`.
|
|
145
|
+
* @param ctx the parse tree
|
|
146
|
+
* @return the visitor result
|
|
147
|
+
*/
|
|
148
|
+
visitString_concat?: (ctx: String_concatContext) => IResult;
|
|
149
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { TJSObject, TSyntaxTreeContainer } from '../core/types';
|
|
2
|
+
import { ErrorDataHandler } from './ErrorDataHandler';
|
|
3
|
+
/**
|
|
4
|
+
* Construct the final result of a JavaScript Object.
|
|
5
|
+
*/
|
|
6
|
+
export declare const constructFinalObject: (syntaxTreeC: TSyntaxTreeContainer, errorHandler: ErrorDataHandler) => TJSObject;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export type TPersistThreshold = '0-Ignore-Errors' | '1-Abort-on-Errors' | '2-Abort-Even-on-Warnings';
|
|
2
|
+
export type TIssueType = 'Fatal-Error' | 'Internal-Error' | 'Syntax-Error' | 'Syntax-Warning' | 'Notice' | 'Info';
|
|
3
|
+
export type TJSObject = any;
|
|
4
|
+
export type TBailSensitivityLevel = 0 | 1 | 2;
|
|
5
|
+
export interface IParseMainOptions {
|
|
6
|
+
isStrict: boolean;
|
|
7
|
+
bailSensitivityLevel: TBailSensitivityLevel;
|
|
8
|
+
isIncludeMeta: boolean;
|
|
9
|
+
isWithDiagnostics: boolean;
|
|
10
|
+
isWithTiming: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface IParseMetaData {
|
|
13
|
+
strictMode: boolean;
|
|
14
|
+
hasTerminal: boolean;
|
|
15
|
+
sections: null | number;
|
|
16
|
+
members: null | number;
|
|
17
|
+
keysParsed: null | number;
|
|
18
|
+
sectionChains: null | number;
|
|
19
|
+
diagnostics?: {
|
|
20
|
+
bailSensitivityLevel: TBailSensitivityLevel;
|
|
21
|
+
errors: null | number;
|
|
22
|
+
warnings: null | number;
|
|
23
|
+
infoAndNotices: null | number;
|
|
24
|
+
envs: {
|
|
25
|
+
NODE_ENV: undefined | string;
|
|
26
|
+
APP_ENV: undefined | string;
|
|
27
|
+
libNodeEnv: undefined | string;
|
|
28
|
+
libAppEnv: undefined | string;
|
|
29
|
+
};
|
|
30
|
+
libFlags: {
|
|
31
|
+
isDev: boolean;
|
|
32
|
+
isDebug: boolean;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
timing?: {
|
|
36
|
+
totalMs: null | number;
|
|
37
|
+
phase1Ms: null | number;
|
|
38
|
+
phase2Ms: null | number;
|
|
39
|
+
phase3Ms: null | number;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export type TSyntaxTreeContainer = {
|
|
43
|
+
_syntaxTree: TSyntaxTree;
|
|
44
|
+
_hasTerminal: boolean;
|
|
45
|
+
_meta_numOfSections: number;
|
|
46
|
+
_meta_numOfMembers: number;
|
|
47
|
+
_meta_numOfChains: number;
|
|
48
|
+
};
|
|
49
|
+
export type TSyntaxTree = IChainContainer[];
|
|
50
|
+
export type TSectionHeaderType = undefined | 'Classic-Header-Marker' | 'Numeric-Header-Marker';
|
|
51
|
+
export interface IChainContainer {
|
|
52
|
+
originLevel: number;
|
|
53
|
+
chain: any;
|
|
54
|
+
}
|
|
55
|
+
export interface ISectionResult {
|
|
56
|
+
level: number;
|
|
57
|
+
name: string;
|
|
58
|
+
members: any;
|
|
59
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { ATN, CharStream, DFA, Lexer } from "antlr4";
|
|
2
|
+
export default class YiniLexer extends Lexer {
|
|
3
|
+
static readonly YINI_MARKER = 1;
|
|
4
|
+
static readonly SECTION_HEAD = 2;
|
|
5
|
+
static readonly TERMINAL_TOKEN = 3;
|
|
6
|
+
static readonly SS = 4;
|
|
7
|
+
static readonly EUR = 5;
|
|
8
|
+
static readonly CARET = 6;
|
|
9
|
+
static readonly TILDE = 7;
|
|
10
|
+
static readonly GT = 8;
|
|
11
|
+
static readonly LT = 9;
|
|
12
|
+
static readonly EQ = 10;
|
|
13
|
+
static readonly HASH = 11;
|
|
14
|
+
static readonly COMMA = 12;
|
|
15
|
+
static readonly COLON = 13;
|
|
16
|
+
static readonly OB = 14;
|
|
17
|
+
static readonly CB = 15;
|
|
18
|
+
static readonly OC = 16;
|
|
19
|
+
static readonly CC = 17;
|
|
20
|
+
static readonly PLUS = 18;
|
|
21
|
+
static readonly DOLLAR = 19;
|
|
22
|
+
static readonly PC = 20;
|
|
23
|
+
static readonly AT = 21;
|
|
24
|
+
static readonly SEMICOLON = 22;
|
|
25
|
+
static readonly BOOLEAN_FALSE = 23;
|
|
26
|
+
static readonly BOOLEAN_TRUE = 24;
|
|
27
|
+
static readonly NULL = 25;
|
|
28
|
+
static readonly EMPTY_OBJECT = 26;
|
|
29
|
+
static readonly EMPTY_LIST = 27;
|
|
30
|
+
static readonly SHEBANG = 28;
|
|
31
|
+
static readonly NUMBER = 29;
|
|
32
|
+
static readonly KEY = 30;
|
|
33
|
+
static readonly IDENT = 31;
|
|
34
|
+
static readonly IDENT_BACKTICKED = 32;
|
|
35
|
+
static readonly STRING = 33;
|
|
36
|
+
static readonly TRIPLE_QUOTED_STRING = 34;
|
|
37
|
+
static readonly SINGLE_OR_DOUBLE = 35;
|
|
38
|
+
static readonly R_AND_C_STRING = 36;
|
|
39
|
+
static readonly HYPER_STRING = 37;
|
|
40
|
+
static readonly ESC_SEQ = 38;
|
|
41
|
+
static readonly ESC_SEQ_BASE = 39;
|
|
42
|
+
static readonly NL = 40;
|
|
43
|
+
static readonly SINGLE_NL = 41;
|
|
44
|
+
static readonly WS = 42;
|
|
45
|
+
static readonly BLOCK_COMMENT = 43;
|
|
46
|
+
static readonly COMMENT = 44;
|
|
47
|
+
static readonly LINE_COMMENT = 45;
|
|
48
|
+
static readonly INLINE_COMMENT = 46;
|
|
49
|
+
static readonly IDENT_INVALID = 47;
|
|
50
|
+
static readonly EOF: number;
|
|
51
|
+
static readonly channelNames: string[];
|
|
52
|
+
static readonly literalNames: (string | null)[];
|
|
53
|
+
static readonly symbolicNames: (string | null)[];
|
|
54
|
+
static readonly modeNames: string[];
|
|
55
|
+
static readonly ruleNames: string[];
|
|
56
|
+
constructor(input: CharStream);
|
|
57
|
+
get grammarFileName(): string;
|
|
58
|
+
get literalNames(): (string | null)[];
|
|
59
|
+
get symbolicNames(): (string | null)[];
|
|
60
|
+
get ruleNames(): string[];
|
|
61
|
+
get serializedATN(): number[];
|
|
62
|
+
get channelNames(): string[];
|
|
63
|
+
get modeNames(): string[];
|
|
64
|
+
static readonly _serializedATN: number[];
|
|
65
|
+
private static __ATN;
|
|
66
|
+
static get _ATN(): ATN;
|
|
67
|
+
static DecisionsToDFA: DFA[];
|
|
68
|
+
}
|