@bablr/cli 0.8.0 → 0.10.0
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 +2 -62
- package/bin/index.js +32 -15
- package/lib/syntax.js +26 -22
- package/package.json +11 -11
package/README.md
CHANGED
|
@@ -2,26 +2,9 @@
|
|
|
2
2
|
|
|
3
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
4
|
|
|
5
|
-
|
|
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 top BABLR language
|
|
14
|
-
-p, --production [type] The name of the top production type
|
|
15
|
-
-f, --format Pretty-format CSTML output (default: true)
|
|
16
|
-
-F, --no-format
|
|
17
|
-
-v, --verbose Prints debugging information to stderr
|
|
18
|
-
-c, --color [WHEN] When to use ANSI escape colors
|
|
19
|
-
WHEN: "auto" | "always" | "never" (default: "auto")
|
|
20
|
-
-e, --embedded Requires quoted input but enables gap parsing
|
|
21
|
-
-h, --help display help for command
|
|
22
|
-
```
|
|
5
|
+
For complete information see the [bablr-cli reference documentation](https://docs.bablr.org/reference/bablr-cli)
|
|
23
6
|
|
|
24
|
-
##
|
|
7
|
+
## Usage
|
|
25
8
|
|
|
26
9
|
```bash
|
|
27
10
|
bablr -l @bablr/language-en-json -p Expression -f << 'EOF'
|
|
@@ -32,46 +15,3 @@ bablr -l @bablr/language-en-json -p Expression -f << 'EOF'
|
|
|
32
15
|
]
|
|
33
16
|
EOF
|
|
34
17
|
```
|
|
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-en-json'>
|
|
40
|
-
<>
|
|
41
|
-
.:
|
|
42
|
-
<Array>
|
|
43
|
-
openToken: <*Punctuator '[' balanced=']' />
|
|
44
|
-
<#*Space:Space '\n ' />
|
|
45
|
-
separators[]: []
|
|
46
|
-
elements[]: []
|
|
47
|
-
elements[]:
|
|
48
|
-
<Number span='Number'>
|
|
49
|
-
wholePart:
|
|
50
|
-
<Integer>
|
|
51
|
-
signToken: null
|
|
52
|
-
value: <*UnsignedInteger '1' />
|
|
53
|
-
</>
|
|
54
|
-
fractionalSeparatorToken: null
|
|
55
|
-
fractionalPart: null
|
|
56
|
-
exponentSeparatorToken: null
|
|
57
|
-
exponentPart: null
|
|
58
|
-
</>
|
|
59
|
-
separators[]: <*Punctuator ',' />
|
|
60
|
-
<#*Space:Space '\n ' />
|
|
61
|
-
elements[]:
|
|
62
|
-
<Boolean>
|
|
63
|
-
sigilToken: <*Keyword 'true' />
|
|
64
|
-
</>
|
|
65
|
-
separators[]: <*Punctuator ',' />
|
|
66
|
-
<#*Space:Space '\n ' />
|
|
67
|
-
elements[]:
|
|
68
|
-
<String>
|
|
69
|
-
openToken: <*Punctuator '"' balanced='"' balancedSpan='String' />
|
|
70
|
-
content: <*StringContent '3' />
|
|
71
|
-
closeToken: <*Punctuator '"' balancer />
|
|
72
|
-
<#*Space:Space '\n' />
|
|
73
|
-
</>
|
|
74
|
-
closeToken: <*Punctuator ']' balancer />
|
|
75
|
-
</>
|
|
76
|
-
</>
|
|
77
|
-
```
|
package/bin/index.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
/* global process */
|
|
4
4
|
|
|
5
5
|
import { program } from 'commander';
|
|
6
|
-
import { streamParse
|
|
6
|
+
import { streamParse } from 'bablr';
|
|
7
7
|
import { embeddedSourceFrom, readFromStream, stripTrailingNewline } from '@bablr/helpers/source';
|
|
8
8
|
import { debugEnhancers } from '@bablr/helpers/enhancers';
|
|
9
9
|
import colorSupport from 'color-support';
|
|
@@ -11,6 +11,7 @@ import { evaluateIO } from '@bablr/io-vm-node';
|
|
|
11
11
|
import { generateCSTML } from '../lib/syntax.js';
|
|
12
12
|
import {
|
|
13
13
|
buildBasicNodeMatcher,
|
|
14
|
+
buildNodeFlags,
|
|
14
15
|
buildOpenNodeMatcher,
|
|
15
16
|
buildPropertyMatcher,
|
|
16
17
|
} from '@bablr/helpers/builders';
|
|
@@ -23,7 +24,10 @@ program
|
|
|
23
24
|
.option('-l, --language [URL]', 'The URL of the top BABLR language')
|
|
24
25
|
.option('-p, --production [type]', 'The name of the top production type')
|
|
25
26
|
.option('-f, --format', 'Pretty-format CSTML output', true)
|
|
26
|
-
.option('-g, --gaps', '
|
|
27
|
+
.option('-g, --gaps', 'Sets hasGap flag on root matcher')
|
|
28
|
+
.option('-r, --fragment', 'Sets fragment flag on root matcher')
|
|
29
|
+
.option('-t --token', 'Sets token flag on root matcher')
|
|
30
|
+
.option('-o --cover', 'Sets cover flag on root matcher')
|
|
27
31
|
.option('-F, --no-format')
|
|
28
32
|
.option('-v, --verbose', 'Prints debugging information to stderr')
|
|
29
33
|
.option(
|
|
@@ -49,14 +53,25 @@ const options = {
|
|
|
49
53
|
|
|
50
54
|
const language = await import(options.language);
|
|
51
55
|
|
|
52
|
-
const matcher =
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
const matcher = options.production
|
|
57
|
+
? buildEmbeddedMatcher(
|
|
58
|
+
buildPropertyMatcher(
|
|
59
|
+
null,
|
|
60
|
+
null,
|
|
61
|
+
buildBasicNodeMatcher(
|
|
62
|
+
buildOpenNodeMatcher(
|
|
63
|
+
buildNodeFlags({
|
|
64
|
+
hasGap: options.gaps,
|
|
65
|
+
fragment: options.fragment,
|
|
66
|
+
token: options.token,
|
|
67
|
+
cover: options.cover,
|
|
68
|
+
}),
|
|
69
|
+
options.production,
|
|
70
|
+
),
|
|
71
|
+
),
|
|
72
|
+
),
|
|
73
|
+
)
|
|
74
|
+
: language.defaultMatcher;
|
|
60
75
|
|
|
61
76
|
const logStderr = (...args) => {
|
|
62
77
|
process.stderr.write(args.join(' ') + '\n');
|
|
@@ -64,23 +79,25 @@ const logStderr = (...args) => {
|
|
|
64
79
|
|
|
65
80
|
const enhancers = options.verbose ? { ...debugEnhancers, agast: null } : {};
|
|
66
81
|
|
|
67
|
-
const ctx = Context.from(language, enhancers.bablrProduction);
|
|
68
|
-
|
|
69
82
|
const rawStream = process.stdin.setEncoding('utf-8');
|
|
70
83
|
|
|
71
84
|
const output = evaluateIO(() =>
|
|
72
85
|
generateCSTML(
|
|
73
86
|
streamParse(
|
|
74
|
-
|
|
87
|
+
language,
|
|
75
88
|
matcher,
|
|
76
89
|
options.embedded
|
|
77
90
|
? embeddedSourceFrom(readFromStream(rawStream))
|
|
78
91
|
: stripTrailingNewline(readFromStream(rawStream)),
|
|
79
92
|
o({}),
|
|
80
|
-
{
|
|
93
|
+
{
|
|
94
|
+
enhancers,
|
|
95
|
+
emitEffects: true,
|
|
96
|
+
holdShiftedNodes: !options.gaps,
|
|
97
|
+
holdUndefinedAttributes: !options.gaps,
|
|
98
|
+
},
|
|
81
99
|
),
|
|
82
100
|
{
|
|
83
|
-
ctx,
|
|
84
101
|
color: options.color,
|
|
85
102
|
format: options.format,
|
|
86
103
|
emitEffects: true,
|
package/lib/syntax.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import emptyStack from '@iter-tools/imm-stack';
|
|
4
4
|
import * as cstml from '@bablr/language-en-cstml';
|
|
5
5
|
import * as verboseOutput from '@bablr/language-en-bablr-cli-verbose-output';
|
|
6
|
-
import { streamParse
|
|
6
|
+
import { streamParse } from 'bablr/enhanceable';
|
|
7
7
|
import { Coroutine } from '@bablr/coroutine';
|
|
8
8
|
import { StreamIterable, getStreamIterator } from '@bablr/agast-helpers/stream';
|
|
9
9
|
import {
|
|
@@ -20,9 +20,13 @@ import {
|
|
|
20
20
|
import { OpenNodeTag, CloseNodeTag, ReferenceTag, LiteralTag } from '@bablr/agast-helpers/symbols';
|
|
21
21
|
import {
|
|
22
22
|
buildBasicNodeMatcher,
|
|
23
|
+
buildNodeFlags,
|
|
23
24
|
buildOpenNodeMatcher,
|
|
24
25
|
buildPropertyMatcher,
|
|
25
26
|
} from '@bablr/helpers/builders';
|
|
27
|
+
import { getFlagsWithGap, nodeFlags } from '@bablr/agast-helpers/builders';
|
|
28
|
+
|
|
29
|
+
let gapNodeFlags = getFlagsWithGap(nodeFlags);
|
|
26
30
|
|
|
27
31
|
function* __higlightStrategy(tags) {
|
|
28
32
|
const co = new Coroutine(getStreamIterator(tags));
|
|
@@ -50,7 +54,7 @@ function* __higlightStrategy(tags) {
|
|
|
50
54
|
|
|
51
55
|
if (
|
|
52
56
|
tagType === Symbol.for('LiteralTag') ||
|
|
53
|
-
(tagType === Symbol.for('String') && currentRef.name === '
|
|
57
|
+
(tagType === Symbol.for('String') && currentRef.name === 'literalValue')
|
|
54
58
|
) {
|
|
55
59
|
if (tagType === Symbol.for('LiteralTag') || currentType === Symbol.for('OpenNodeTag')) {
|
|
56
60
|
yield buildAnsiPushEffect('bold green');
|
|
@@ -59,13 +63,16 @@ function* __higlightStrategy(tags) {
|
|
|
59
63
|
} else {
|
|
60
64
|
yield buildAnsiPushEffect();
|
|
61
65
|
}
|
|
62
|
-
} else if (
|
|
63
|
-
tagType === Symbol.for('Pattern') &&
|
|
64
|
-
tag.value.language !== 'https://bablr.org/languages/core/en/spamex'
|
|
65
|
-
) {
|
|
66
|
+
} else if (tagType === Symbol.for('Pattern')) {
|
|
66
67
|
yield buildAnsiPushEffect('bold orange');
|
|
67
68
|
} else if (tagType === Symbol.for('EscapeSequence')) {
|
|
68
69
|
yield buildAnsiPushEffect('bold cyan');
|
|
70
|
+
} else if (tagType === Symbol.for('Punctuator')) {
|
|
71
|
+
if (currentType === Symbol.for('ReferenceTag')) {
|
|
72
|
+
yield buildAnsiPushEffect('bold gray');
|
|
73
|
+
} else {
|
|
74
|
+
yield buildAnsiPushEffect();
|
|
75
|
+
}
|
|
69
76
|
} else if (tagType === Symbol.for('Identifier')) {
|
|
70
77
|
if (currentType === Symbol.for('ReferenceTag')) {
|
|
71
78
|
yield buildAnsiPushEffect('bold gray');
|
|
@@ -96,20 +103,19 @@ function* __higlightStrategy(tags) {
|
|
|
96
103
|
currentRef = tag.value;
|
|
97
104
|
}
|
|
98
105
|
|
|
99
|
-
if (tag.type === CloseNodeTag) {
|
|
100
|
-
types = types.pop();
|
|
101
|
-
yield buildAnsiPopEffect();
|
|
102
|
-
}
|
|
103
|
-
|
|
104
106
|
if (tag.type === LiteralTag) {
|
|
105
107
|
yield buildWriteEffect(tag.value);
|
|
106
|
-
} else if (tag.type === OpenNodeTag && tag.value.
|
|
107
|
-
yield buildWriteEffect(tag.value.
|
|
108
|
-
yield buildAnsiPopEffect();
|
|
108
|
+
} else if (tag.type === OpenNodeTag && tag.value.literalValue) {
|
|
109
|
+
yield buildWriteEffect(tag.value.literalValue);
|
|
109
110
|
}
|
|
110
111
|
|
|
111
112
|
yield tag;
|
|
112
113
|
|
|
114
|
+
if (tag.type === CloseNodeTag || (tag.type === OpenNodeTag && tag.value.selfClosing)) {
|
|
115
|
+
types = types.pop();
|
|
116
|
+
yield buildAnsiPopEffect();
|
|
117
|
+
}
|
|
118
|
+
|
|
113
119
|
co.advance();
|
|
114
120
|
}
|
|
115
121
|
}
|
|
@@ -119,30 +125,28 @@ export const higlightStrategy = (tags) => {
|
|
|
119
125
|
};
|
|
120
126
|
|
|
121
127
|
export const generateCSTML = (tags, options = {}) => {
|
|
122
|
-
const strategyOptions = { ctx: options.ctx };
|
|
123
128
|
const outputInstructions = options.format
|
|
124
|
-
? writePrettyCSTMLStrategy(tags
|
|
125
|
-
: writeCSTMLStrategy(tags
|
|
129
|
+
? writePrettyCSTMLStrategy(tags)
|
|
130
|
+
: writeCSTMLStrategy(tags);
|
|
126
131
|
|
|
127
132
|
if (options.color) {
|
|
128
133
|
const input = generateAllOutput(outputInstructions);
|
|
129
134
|
const language = options.emitEffects ? verboseOutput : cstml;
|
|
130
135
|
const type = options.emitEffects ? 'Output' : 'Document';
|
|
131
136
|
|
|
132
|
-
const context = Context.from(language);
|
|
133
|
-
|
|
134
137
|
const tags = streamParse(
|
|
135
|
-
|
|
138
|
+
language,
|
|
136
139
|
buildEmbeddedMatcher(
|
|
137
140
|
buildPropertyMatcher(
|
|
138
141
|
null,
|
|
139
|
-
|
|
142
|
+
null,
|
|
143
|
+
buildBasicNodeMatcher(buildOpenNodeMatcher(buildNodeFlags(gapNodeFlags), type)),
|
|
140
144
|
),
|
|
141
145
|
),
|
|
142
146
|
input,
|
|
143
147
|
);
|
|
144
148
|
|
|
145
|
-
return higlightStrategy(tags
|
|
149
|
+
return higlightStrategy(tags);
|
|
146
150
|
} else {
|
|
147
151
|
return outputInstructions;
|
|
148
152
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bablr/cli",
|
|
3
3
|
"description": "CLI for running BABLR parsers",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.10.0",
|
|
5
5
|
"author": "Conrad Buck<conartist6@gmail.com>",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"files": [
|
|
@@ -17,21 +17,21 @@
|
|
|
17
17
|
},
|
|
18
18
|
"sideEffects": false,
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@bablr/agast-helpers": "0.
|
|
21
|
-
"@bablr/agast-vm-helpers": "0.
|
|
22
|
-
"@bablr/io-vm-node": "0.
|
|
23
|
-
"@bablr/boot": "0.
|
|
20
|
+
"@bablr/agast-helpers": "0.9.0",
|
|
21
|
+
"@bablr/agast-vm-helpers": "0.9.0",
|
|
22
|
+
"@bablr/io-vm-node": "0.8.0",
|
|
23
|
+
"@bablr/boot": "0.10.0",
|
|
24
24
|
"@bablr/coroutine": "0.1.0",
|
|
25
|
-
"@bablr/helpers": "0.
|
|
26
|
-
"@bablr/language-en-cstml": "0.
|
|
27
|
-
"@bablr/language-en-bablr-cli-verbose-output": "0.
|
|
28
|
-
"@iter-tools/imm-stack": "1.
|
|
29
|
-
"bablr": "0.
|
|
25
|
+
"@bablr/helpers": "0.24.0",
|
|
26
|
+
"@bablr/language-en-cstml": "0.11.0",
|
|
27
|
+
"@bablr/language-en-bablr-cli-verbose-output": "0.9.0",
|
|
28
|
+
"@iter-tools/imm-stack": "1.2.0",
|
|
29
|
+
"bablr": "0.10.0",
|
|
30
30
|
"color-support": "1.1.3",
|
|
31
31
|
"commander": "^12.0.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@bablr/eslint-config-base": "github:bablr-lang/eslint-config-base#
|
|
34
|
+
"@bablr/eslint-config-base": "github:bablr-lang/eslint-config-base#c97bfa4b3663f8378e9b3e42bb5a41e685406cf9",
|
|
35
35
|
"enhanced-resolve": "^5.12.0",
|
|
36
36
|
"eslint": "^8.32.0",
|
|
37
37
|
"eslint-import-resolver-enhanced-resolve": "^1.0.5",
|