yini-parser 1.0.0-beta.1 → 1.0.2-beta

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.
@@ -20,6 +20,7 @@ import { String_concatContext } from "./YiniParser.js";
20
20
  import { Boolean_literalContext } from "./YiniParser.js";
21
21
  import { Empty_objectContext } from "./YiniParser.js";
22
22
  import { Empty_listContext } from "./YiniParser.js";
23
+ import { Bad_memberContext } from "./YiniParser.js";
23
24
  /**
24
25
  * This interface defines a complete generic visitor for a parse tree produced
25
26
  * by `YiniParser`.
@@ -154,4 +155,10 @@ export default class YiniParserVisitor<Result> extends ParseTreeVisitor<Result>
154
155
  * @return the visitor result
155
156
  */
156
157
  visitEmpty_list?: (ctx: Empty_listContext) => Result;
158
+ /**
159
+ * Visit a parse tree produced by `YiniParser.bad_member`.
160
+ * @param ctx the parse tree
161
+ * @return the visitor result
162
+ */
163
+ visitBad_member?: (ctx: Bad_memberContext) => Result;
157
164
  }
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- // Generated from grammar/v1.0.0-rc.1/YiniParser.g4 by ANTLR 4.13.2
2
+ // Generated from grammar/v1.0.0-rc.2x/YiniParser.g4 by ANTLR 4.13.2
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  const antlr4_1 = require("antlr4");
5
5
  /**
package/dist/index.js CHANGED
@@ -1,25 +1,25 @@
1
1
  "use strict";
2
- // import { isDebug&&console.log } from './utils/general'
3
- var __importDefault = (this && this.__importDefault) || function (mod) {
4
- return (mod && mod.__esModule) ? mod : { "default": mod };
5
- };
6
- var _a, _b, _c;
7
- Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.parseFile = exports.parse = void 0;
9
2
  /*
10
- https://pauloe-me.medium.com/typescript-npm-package-publishing-a-beginners-guide-40b95908e69c
3
+ https://github.com/YINI-lang/yini-parser-typescript/blob/main/docs/Project-Setup.md
11
4
 
12
5
  Run the code with the following command:
13
- npx ts-node index
14
- or
15
6
  npm start
7
+ or
8
+ npm run start:dev
9
+ or
10
+ npm run start:dev:debug
16
11
 
17
12
  /END
18
13
  */
14
+ var __importDefault = (this && this.__importDefault) || function (mod) {
15
+ return (mod && mod.__esModule) ? mod : { "default": mod };
16
+ };
17
+ var _a, _b, _c;
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.parseFile = exports.parse = void 0;
19
20
  const env_1 = require("./config/env");
20
21
  const print_1 = require("./utils/print");
21
22
  const YINI_1 = __importDefault(require("./YINI"));
22
- // export { default } from './YINI'
23
23
  exports.parse = YINI_1.default.parse;
24
24
  exports.parseFile = YINI_1.default.parseFile;
25
25
  exports.default = YINI_1.default;
@@ -52,100 +52,8 @@ if ((0, env_1.isProdEnv)()) {
52
52
  // Do nothing, and exit.
53
53
  }
54
54
  else {
55
- const invalidInput1 = `
56
- ^ Settings
57
- fruit = "Pear"
58
- number = 5
59
- value q= "something"
60
- `;
61
- const invalidInput2 = `
62
- ^ Config
63
- varAge = 30
64
- varName = abcd
65
- varNull = NULL
66
- `;
67
- const input1 = `
68
- ^ SectionName
69
- varBool = true
70
- varBool2 = off
71
- varInt = 30
72
- varFloat = 12.34
73
- varStr = "Alice"
74
- listItems = ["a", "b", "c"]
75
- varE1 = 1e4
76
- varE2 = 1.23e4
77
- varE3 = 6.5E23
78
- /END
79
- `;
80
- const input2 = `
81
- ^ Config
82
- varAge = 30
83
- varName = "Alice"
84
- varNull = NULL
85
- listItems = ["a", "b", "c"]
86
- ^^Extra
87
- isExtra = true
88
- /END
89
- `;
90
- // const input = `
91
- // # Config`;
92
- // debugPrint('input2:')
93
- // if (isDebug()) {
94
- // console.debug(input2)
95
- // }
96
- // YINI.parse(input2)
97
- // debugPrint('invalidInput1:')
98
- // if (isDebug()) {
99
- // console.debug(invalidInput1)
100
- // }
101
- // YINI.parse(invalidInput1)
102
55
  if (env_1.localAppEnv === 'local' && env_1.localNodeEnv !== 'test') {
103
- /*
104
- YINI.parse(`
105
- --^ Section0
106
- --value = 0
107
- ^ Section1
108
- value = 1
109
-
110
- ^^ Section11
111
- value = 11
112
-
113
- ^^^ Section111
114
- value = 111
115
- //^^^^ Section2104
116
- value = 24
117
-
118
- ^ Section2
119
- value = 2
120
- `)
121
- }
122
- */
123
- // YINI.parse(`number = 42`)
124
- /*
125
- Expected JS output:
126
- {
127
- Section1: { value: 1, Section2: { value: 11 }},
128
- Section2: { value: 2 }
129
- }
130
-
131
- */
132
- /*
133
- YINI.parse(
134
- `
135
- // Using numeric shorthand section markers.
136
-
137
- @yini
138
-
139
- // This whole line is a comment.
140
- ^SectionName# This part is a comment.
141
- // This whole line is a comment.
142
- --x=1
143
- `,
144
- false,
145
- 2,
146
- )
147
- */
148
- // YINI.parse(`^1 SectionName`, false, 2)
56
+ // parseUntilError(`^1 SectionName`, false, 2)
149
57
  // const validYini = `
150
58
  // < user
151
59
  // username = 'tester two'
@@ -169,18 +77,32 @@ Expected JS output:
169
77
  // notifications = ON
170
78
  // `
171
79
  // // Act.
172
- // const result = YINI.parse(validYini)
80
+ // const result = parseUntilError(validYini)
173
81
  // debugPrint(result)
174
82
  // const validYini = `^ App
175
83
  // id = 32403 # The correct app id.
176
84
  // title = "My Program"
177
85
  // `
178
86
  const yini = `
179
- ^ Database
180
- pool = { max: 10, min: 2 }
181
- `;
182
- YINI_1.default.parse(yini);
183
- // YINI.parse(`
87
+ ^ DozNumbers
88
+ ^^ WithXE
89
+ doz1 = 0z00
90
+ doz2 = 0z01 // One with leading zeros
91
+ doz3 = 0z100 // Decimal 144 (X/A is digit for 10 in base-12)
92
+ doz4 = 0z7EE // Decimal 1151
93
+ doz5 = 0zX00 // Decimal 1440 (E/B is digit for 11 in base-12)
94
+
95
+ ^^ WithAB
96
+ doz6 = 0z7BB // Decimal 1151
97
+ doz7 = 0zA00 // Decimal 1440 (E/B is digit for 11 in base-12)
98
+ `;
99
+ console.log((0, print_1.toPrettyJSON)(YINI_1.default.parse(yini, false)));
100
+ // console.log(
101
+ // toPrettyJSON(YINI.parseFile('comprehensive-example.yini', true)),
102
+ // )
103
+ // const fileName = './tests/fixtures/valid/common/common-config-2.yini'
104
+ // YINI.parseFile(fileName, false)
105
+ // parseUntilError(`
184
106
  // ^ Section1
185
107
  // ^^ Section2
186
108
  // ^^^ Section3
@@ -12,13 +12,13 @@ const YINIVisitor_1 = __importDefault(require("./core/YINIVisitor"));
12
12
  const YiniLexer_1 = __importDefault(require("./grammar/YiniLexer"));
13
13
  const YiniParser_1 = __importDefault(require("./grammar/YiniParser"));
14
14
  const print_1 = require("./utils/print");
15
- class MyErrorListener {
15
+ class MyParserErrorListener {
16
16
  constructor(errorHandler) {
17
17
  this.errors = [];
18
18
  this.errorHandler = errorHandler;
19
19
  }
20
20
  syntaxError(recognizer, offendingSymbol, line, charPositionInLine, msg, e) {
21
- (0, print_1.debugPrint)('ANTLR grammar cached an error');
21
+ (0, print_1.debugPrint)('ANTLR parser cached an error');
22
22
  this.errors.push(`Line ${line}:${charPositionInLine} ${msg}`);
23
23
  const msgWhat = `Syntax error, at line: ${line}`;
24
24
  const msgWhy = `At about column ${1 + charPositionInLine} ${msg}`;
@@ -29,6 +29,20 @@ class MyErrorListener {
29
29
  reportAttemptingFullContext(...args) { }
30
30
  reportContextSensitivity(...args) { }
31
31
  }
32
+ class MyLexerErrorListener {
33
+ constructor(errorHandler) {
34
+ this.errors = [];
35
+ this.errorHandler = errorHandler;
36
+ }
37
+ syntaxError(recognizer, offendingSymbol, line, charPositionInLine, msg, e) {
38
+ // Handle the error as you want:
39
+ (0, print_1.debugPrint)('ANTLR parser cached an error');
40
+ this.errors.push(`Line ${line}:${charPositionInLine} ${msg}`);
41
+ const msgWhat = `Syntax error, at line: ${line}`;
42
+ const msgWhy = `At about column ${1 + charPositionInLine} ${msg}`;
43
+ this.errorHandler.pushOrBail(null, 'Syntax-Error', msgWhat, msgWhy);
44
+ }
45
+ }
32
46
  const parseMain = (yiniContent, options = {
33
47
  isStrict: false,
34
48
  bailSensitivityLevel: 0,
@@ -58,17 +72,23 @@ const parseMain = (yiniContent, options = {
58
72
  const tokenStream = new antlr4_1.CommonTokenStream(lexer);
59
73
  const parser = new YiniParser_1.default(tokenStream);
60
74
  const errorHandler = new ErrorDataHandler_1.ErrorDataHandler(persistThreshold);
61
- const errorListener = new MyErrorListener(errorHandler);
62
- parser.removeErrorListeners(); // Removes the default console error output.
63
- parser.addErrorListener(errorListener);
75
+ // Remove the default ConsoleErrorListener
76
+ lexer.removeErrorListeners(); // Removes the default lexer console error output.
77
+ const lexerErrorListener = new MyLexerErrorListener(errorHandler);
78
+ lexer.addErrorListener(lexerErrorListener);
79
+ // const errorListener = new MyParserErrorListener(errorHandler)
80
+ parser.removeErrorListeners(); // Removes the default parser console error output.
81
+ const parserErrorListener = new MyParserErrorListener(errorHandler);
82
+ parser.addErrorListener(parserErrorListener);
64
83
  (0, print_1.debugPrint)();
65
84
  (0, print_1.debugPrint)('--- Starting parsing... ---');
66
85
  const parseTree = parser.yini(); // The function yini() is the start rule.
67
- if (errorListener.errors.length > 0) {
86
+ if (parserErrorListener.errors.length > 0 ||
87
+ lexerErrorListener.errors.length > 0) {
68
88
  (0, print_1.debugPrint)('*** ERROR detected ***');
69
89
  if ((0, env_1.isDebug)()) {
70
90
  // Handle or display syntax errors
71
- console.error('Syntax errors detected:', errorListener.errors);
91
+ console.error('Syntax errors detected:', parserErrorListener.errors, lexerErrorListener.errors);
72
92
  //process.exit(1)
73
93
  }
74
94
  }
@@ -3,37 +3,57 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const print_1 = require("../utils/print");
4
4
  const parseNumberLiteral = (txt) => {
5
5
  (0, print_1.debugPrint)('-> Entered parseNumberLiteral(..), txt: ' + txt);
6
- if (/^0[xX]|#/.test(txt)) {
6
+ if (/^[+-]?(?:\d+\.\d*|\d*\.?\d+)e[+-]?\d+$/i.test(txt)) {
7
+ // Exp. numbers
8
+ (0, print_1.debugPrint)('* Identified as an exp number');
9
+ return {
10
+ type: 'Number-Float',
11
+ // value: parseInt(txt.replace('#', '0x'), 16),
12
+ value: parseFloat(txt),
13
+ };
14
+ }
15
+ // --- Hexadecimal ---------
16
+ if (/^[+-]?(0[xX]|#)/.test(txt)) {
7
17
  // Prefix: 0x, 0X, #
8
18
  (0, print_1.debugPrint)('* Identified as a hex number');
19
+ (0, print_1.debugPrint)('parsed out HEX: ' + txt.replace(/0[xX]|#/, ''));
9
20
  return {
10
21
  type: 'Number-Integer',
11
22
  // value: parseInt(txt.replace('#', '0x'), 16),
12
- value: parseInt(txt.replace(/^0[xX]|#/, ''), 16),
23
+ value: parseInt(txt.replace(/0[xX]|#/, ''), 16),
13
24
  };
14
25
  }
15
- if (/^0[bB]|%/.test(txt)) {
26
+ // --- Binary ---------
27
+ if (/^[+-]?(0[bB]|%)/.test(txt)) {
16
28
  // Prefix: 0b, 0B, %
17
29
  (0, print_1.debugPrint)('* Identified as a bin number');
30
+ (0, print_1.debugPrint)('parsed out BIN: ' + txt.replace(/0[bB]|%/, ''));
18
31
  return {
19
32
  type: 'Number-Integer',
20
- value: parseInt(txt.replace(/^0[bB]|%/, ''), 2),
33
+ value: parseInt(txt.replace(/0[bB]|%/, ''), 2),
21
34
  };
22
35
  }
23
- if (/^0[oO]/.test(txt)) {
36
+ // --- Octal ---------
37
+ if (/^[+-]?0[oO]/.test(txt)) {
24
38
  // Prefix: 0o, 0O
25
- (0, print_1.debugPrint)('* Identified as a ord number');
39
+ (0, print_1.debugPrint)('* Identified as a oct number');
40
+ (0, print_1.debugPrint)('parsed out OCT: ' + txt.replace(/0[oO]/, ''));
26
41
  return {
27
42
  type: 'Number-Integer',
28
- value: parseInt(txt.replace(/^0[oO]/, ''), 8),
43
+ value: parseInt(txt.replace(/0[oO]/, ''), 8),
29
44
  };
30
45
  }
31
- if (/^0[zZ]/.test(txt)) {
32
- // Prefix: 0z, 0Z
46
+ // --- Duodecimal ---------
47
+ if (/^[+-]?0[zZ]/.test(txt)) {
48
+ // Prefix: 0z, 0Z, x = A = 10, e = B = 11.
33
49
  (0, print_1.debugPrint)('* Identified as a duodecimal number');
50
+ (0, print_1.debugPrint)('parsed out DOZ: ' + txt.replace(/0[zZ]/, ''));
51
+ txt = txt.replace(/[xX]/g, 'A');
52
+ txt = txt.replace(/[eE]/g, 'B');
53
+ (0, print_1.debugPrint)('Converter to AB form: ' + txt.replace(/0[zZ]/, ''));
34
54
  return {
35
55
  type: 'Number-Integer',
36
- value: parseInt(txt.replace(/^0[zZ]/, ''), 12),
56
+ value: parseInt(txt.replace(/0[zZ]/, ''), 12),
37
57
  };
38
58
  }
39
59
  // In a regex literal the dot must be escaped (\.) to match a literal '.'
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "yini-parser",
3
- "version": "1.0.0-beta.1",
4
- "description": "Simple and flexible config parser for Node.js. YINI: an enhanced, readable alternative to JSON, INI, and YAML—built for modern JavaScript and TypeScript projects.",
3
+ "version": "1.0.2-beta",
4
+ "description": "Node.js parser for YINI a clean, structured INI alternative with types, simple section nesting, comments, and strict mode.",
5
5
  "keywords": [
6
6
  "yini",
7
7
  "yini-parser",
@@ -19,7 +19,7 @@
19
19
  "nodejs",
20
20
  "javascript"
21
21
  ],
22
- "homepage": "https://m4se.com/yini-lang.org/",
22
+ "homepage": "https://github.com/YINI-lang/yini-parser-typescript",
23
23
  "license": "Apache-2.0",
24
24
  "files": [
25
25
  "dist/",
@@ -54,9 +54,13 @@
54
54
  "test:smoke": "cross-env NODE_ENV=test APP_ENV=local jest tests/smoke --bail --verbose --runInBand",
55
55
  "test:unit": "cross-env NODE_ENV=test APP_ENV=local jest tests/unit --bail --verbose --runInBand",
56
56
  "test:integr": "cross-env NODE_ENV=test APP_ENV=local jest tests/integration --bail --verbose --runInBand",
57
+ "test:issues": "cross-env NODE_ENV=test APP_ENV=local jest tests/fixed-issues --bail --verbose --runInBand",
58
+ "test:gold": "cross-env NODE_ENV=test APP_ENV=local jest tests/golden --bail --verbose --runInBand",
57
59
  "test:smoke:debug": "cross-env npm run test:smoke -- --isDebug=1",
58
60
  "test:unit:debug": "cross-env npm run test:unit -- --isDebug=1",
59
61
  "test:integr:debug": "cross-env npm run test:integr -- --isDebug=1",
62
+ "test:issues:debug": "cross-env npm run test:issues -- --isDebug=1",
63
+ "test:gold:debug": "cross-env npm run test:gold -- --isDebug=1",
60
64
  "test:esm": "node ./tests/fixtures/test-src-files/esm-smoke.js",
61
65
  "ci:test": "cross-env NODE_ENV=test APP_ENV=ci jest --verbose --runInBand",
62
66
  "ci:test:smoke": "cross-env NODE_ENV=test APP_ENV=ci jest tests/smoke --verbose --runInBand",