@bablr/cli 0.1.1 → 0.1.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 ADDED
@@ -0,0 +1,97 @@
1
+ # @bablr/cli
2
+
3
+ This is the CLI runner for BABLR. If you have a BABLR grammar for a computer language, this tool allows you to use it to do streaming parsing. Parse results are presented in CSTML.
4
+
5
+ ## Usage
6
+
7
+ This package has no built-in language support, but rather expects you to supply a valid import specifier referring to a BABLR language. This likely means that you will likely need to start by installing both the parser and the language you wish to use.
8
+
9
+ ```
10
+ Usage: bablr [options]
11
+
12
+ Options:
13
+ -l, --language [URL] The URL of the BABLR language to parse with
14
+ -p, --production [type] The top-level type for the parse
15
+ -f, --format Pretty-format CSTML output
16
+ -F, --no-format Produce machine-readable CSTML output
17
+ -v, --verbose Prints debugging information to stderr
18
+ -c, --color Force colored output (default: true)
19
+ -C, --no-color Do not color output
20
+ -e, --embedded Requires quoted input but enables gap parsing
21
+ -h, --help display help for command
22
+ ```
23
+
24
+ ## Example
25
+
26
+ ```bash
27
+ bablr -l @bablr/language-json -p Expression -f << 'EOF'
28
+ [
29
+ 1,
30
+ true,
31
+ "3"
32
+ ]
33
+ EOF
34
+ ```
35
+
36
+ Running the above command produces the following output. Note that this is a stream parse so lines of output will appear one by one as fast as the input can be read and parsed.
37
+
38
+ ```cstml
39
+ <!0:cstml bablr-language='https://github.com/bablr-lang/language-json'>
40
+ <>
41
+ <Array>
42
+ openToken:
43
+ <*Punctuator '[' balanced=']' />
44
+ <#*Space:Space>
45
+ '\n '
46
+ </>
47
+ elements[]:
48
+ <Number span='Number'>
49
+ wholePart:
50
+ <Integer>
51
+ digits[]:
52
+ <*Digit>
53
+ '1'
54
+ </>
55
+ </>
56
+ fractionalPart:
57
+ null
58
+ exponentPart:
59
+ null
60
+ </>
61
+ separators[]:
62
+ <*Punctuator ',' />
63
+ <#*Space:Space>
64
+ '\n '
65
+ </>
66
+ elements[]:
67
+ <Boolean>
68
+ sigilToken:
69
+ <*Keyword 'true' />
70
+ </>
71
+ separators[]:
72
+ <*Punctuator ',' />
73
+ <#*Space:Space>
74
+ '\n '
75
+ </>
76
+ elements[]:
77
+ <String>
78
+ openToken:
79
+ <*Punctuator '"' balanced='"' balancedSpan='String' />
80
+ content:
81
+ <*StringContent>
82
+ '3'
83
+ </>
84
+ closeToken:
85
+ <*Punctuator '"' balancer />
86
+ <#*Space:Space>
87
+ '\n'
88
+ </>
89
+ </>
90
+ closeToken:
91
+ <*Punctuator ']' balancer />
92
+ <#*Space:Space>
93
+ '\n'
94
+ </>
95
+ </>
96
+ </>
97
+ ```
package/bin/index.js CHANGED
@@ -4,22 +4,28 @@
4
4
 
5
5
  import { program } from 'commander';
6
6
  import { streamParse } from 'bablr';
7
- import { sourceFromReadStream } from '@bablr/helpers/source';
7
+ import { embeddedSourceFromReadStream, sourceFromReadStream } from '@bablr/helpers/source';
8
8
  import { buildDebugEnhancers } from '@bablr/helpers/enhancers';
9
- import { printTerminal } from '@bablr/agast-helpers/stream';
9
+ import colorSupport from 'color-support';
10
+ import { pipeline } from 'node:stream/promises';
11
+ import { generateCSTML, generateColorfulCSTML } from '../lib/syntax.js';
10
12
 
11
13
  program
12
14
  .option('-l, --language [URL]', 'The URL of the BABLR language to parse with')
13
15
  .option('-p, --production [type]', 'The top-level type for the parse')
14
- .option('-f, --formatted', 'Whether to pretty-format the CSTML output')
15
- .option('-v, --verbose', 'Whether to print debug logging to stderr during parsing')
16
+ .option('-f, --format', 'Pretty-format CSTML output')
17
+ .option('-F, --no-format', 'Produce machine-readable CSTML output')
18
+ .option('-v, --verbose', 'Prints debugging information to stderr')
19
+ .option('-c, --color', 'Force colored output', true)
20
+ .option('-C, --no-color', 'Do not color output')
21
+ .option('-e, --embedded', 'Requires quoted input but enables gap parsing')
16
22
  .parse(process.argv);
17
23
 
18
24
  const options = program.opts();
19
25
 
20
- const language = await import(options.language);
26
+ const enableAnsi = colorSupport.hasBasic && options.color;
21
27
 
22
- let indentAmt = 0;
28
+ const language = await import(options.language);
23
29
 
24
30
  const logStderr = (...args) => {
25
31
  process.stderr.write(args.join(' ') + '\n');
@@ -27,30 +33,19 @@ const logStderr = (...args) => {
27
33
 
28
34
  const enhancers = options.verbose ? { ...buildDebugEnhancers(logStderr), agastStrategy: null } : {};
29
35
 
30
- for await (const token of streamParse(
31
- language,
32
- options.production,
33
- sourceFromReadStream(process.stdin.setEncoding('utf-8')),
34
- {},
35
- enhancers,
36
- )) {
37
- if (token.type === 'OpenNodeTag') {
38
- indentAmt++;
39
- }
40
-
41
- const offset =
42
- token.type === 'Null' ? 2 : ['Literal', 'Gap', 'Reference'].includes(token.type) ? 1 : 0;
43
-
44
- const out = options.formatted
45
- ? `${' '.repeat(indentAmt + offset)}${printTerminal(token)}`
46
- : printTerminal(token);
47
-
48
- if (
49
- token.type === 'CloseNodeTag' ||
50
- (token.type === 'OpenNodeTag' && token.value.flags.intrinsic)
51
- ) {
52
- indentAmt--;
53
- }
54
-
55
- process.stdout.write(out + '\n');
56
- }
36
+ const rawStream = process.stdin.setEncoding('utf-8');
37
+
38
+ const generateCSTML_ = enableAnsi ? generateColorfulCSTML : generateCSTML;
39
+
40
+ pipeline(
41
+ generateCSTML_(
42
+ streamParse(
43
+ language,
44
+ options.production,
45
+ options.embedded ? embeddedSourceFromReadStream(rawStream) : sourceFromReadStream(rawStream),
46
+ {},
47
+ enhancers,
48
+ ),
49
+ ),
50
+ process.stdout,
51
+ );
package/lib/syntax.js ADDED
@@ -0,0 +1,83 @@
1
+ /* global process Promise */
2
+
3
+ import { i } from '@bablr/boot';
4
+ import * as cstml from '@bablr/language-cstml';
5
+ import { streamParse } from 'bablr/enhanceable';
6
+ import { Coroutine } from '@bablr/coroutine';
7
+ import {
8
+ StreamIterable,
9
+ getStreamIterator,
10
+ generatePrettyCSTML as generatePrettyCSTMLStream,
11
+ } from '@bablr/agast-helpers/stream';
12
+ import { evaluate } from '@bablr/ansi-vm';
13
+ import { buildString } from '@bablr/agast-vm-helpers';
14
+
15
+ function* __higlightStrategy(tokens) {
16
+ const co = new Coroutine(
17
+ getStreamIterator(streamParse(cstml, 'Document', generatePrettyCSTMLStream(tokens))),
18
+ );
19
+
20
+ let currentType;
21
+ let currentRef;
22
+
23
+ co.advance();
24
+
25
+ for (;;) {
26
+ if (co.current instanceof Promise) {
27
+ co.current = yield co.current;
28
+ }
29
+
30
+ if (co.done) break;
31
+
32
+ const token = co.value;
33
+
34
+ if (token.type === 'OpenNodeTag') {
35
+ if (
36
+ currentType === 'Literal' ||
37
+ (token.value.type === 'String' && currentRef.name === 'intrinsicValue')
38
+ ) {
39
+ yield i`push(bold green)`;
40
+ } else if (token.value.type === 'String') {
41
+ yield i`push(bold white)`;
42
+ } else if (token.value.type === 'Identifier') {
43
+ if (currentType === 'Punctuator' && currentRef.name === 'type') {
44
+ yield i`push(whiteBright bold)`;
45
+ } else if (currentType === 'Reference') {
46
+ yield i`push(gray)`;
47
+ } else {
48
+ yield i`push()`;
49
+ }
50
+ } else {
51
+ yield i`push()`;
52
+ }
53
+ currentType = token.value.type;
54
+ }
55
+
56
+ if (token.type === 'Reference') {
57
+ currentRef = token.value;
58
+ }
59
+
60
+ if (token.type === 'CloseNodeTag') {
61
+ yield i`pop()`;
62
+ }
63
+
64
+ if (token.type === 'Literal') {
65
+ yield i`write(${buildString(token.value)})`;
66
+ } else if (token.type === 'OpenNodeTag' && token.value.flags.intrinsic) {
67
+ yield i`write(${buildString(token.value.intrinsicValue)})`;
68
+ yield i`pop()`;
69
+ }
70
+
71
+ co.advance();
72
+ }
73
+
74
+ yield i`write('\n')`;
75
+ }
76
+
77
+ export const higlightStrategy = (tokens) => {
78
+ return () => new StreamIterable(__higlightStrategy(tokens));
79
+ };
80
+
81
+ export const generateColorfulCSTML = (tokens) => evaluate(higlightStrategy(tokens));
82
+
83
+ export const generateCSTML = (tokens) => generatePrettyCSTMLStream(tokens);
package/package.json CHANGED
@@ -1,23 +1,31 @@
1
1
  {
2
2
  "name": "@bablr/cli",
3
3
  "description": "CLI for running BABLR parsers",
4
- "version": "0.1.1",
4
+ "version": "0.1.3",
5
5
  "author": "Conrad Buck<conartist6@gmail.com>",
6
6
  "type": "module",
7
7
  "files": [
8
- "bin"
8
+ "bin",
9
+ "lib"
9
10
  ],
10
11
  "bin": {
11
12
  "bablr": "./bin/index.js"
12
13
  },
13
14
  "exports": {
14
- ".": "./bin/index.js"
15
+ ".": "./bin/index.js",
16
+ "./syntax": "./lib/syntax.js"
15
17
  },
16
18
  "sideEffects": false,
17
19
  "dependencies": {
18
- "@bablr/agast-helpers": "0.1.0",
19
- "@bablr/helpers": "0.15.0",
20
- "bablr": "0.1.1",
20
+ "@bablr/agast-helpers": "0.1.1",
21
+ "@bablr/agast-vm-helpers": "0.1.1",
22
+ "@bablr/ansi-vm": "0.1.0",
23
+ "@bablr/boot": "0.2.1",
24
+ "@bablr/coroutine": "0.1.0",
25
+ "@bablr/helpers": "0.15.1",
26
+ "@bablr/language-cstml": "0.2.1",
27
+ "bablr": "0.1.2",
28
+ "color-support": "1.1.3",
21
29
  "commander": "12.0.0"
22
30
  },
23
31
  "devDependencies": {