parser-lr 0.6.1 → 0.8.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 +14 -30
- package/bin/parser-lr.js +12759 -13493
- package/bin/parser-lr.js.map +1 -1
- package/dist/lib/grammar/grammar-from-cst.js +4 -1
- package/dist/lib/grammar/grammar-from-cst.js.map +1 -1
- package/dist/lib/grammar/grammar.json +86 -820
- package/dist/lib/grammar/index.d.ts +1 -1
- package/dist/lib/grammar/index.d.ts.map +1 -1
- package/dist/lib/grammar/index.js +1 -1
- package/dist/lib/grammar/index.js.map +1 -1
- package/dist/lib/grammar/meta-grammar-table.d.ts +0 -12
- package/dist/lib/grammar/meta-grammar-table.d.ts.map +1 -1
- package/dist/lib/grammar/meta-grammar-table.js +5 -22
- package/dist/lib/grammar/meta-grammar-table.js.map +1 -1
- package/dist/lib/grammar/table-validator.d.ts.map +1 -1
- package/dist/lib/grammar/table-validator.js +19 -1
- package/dist/lib/grammar/table-validator.js.map +1 -1
- package/dist/lib/grammar-entry.d.ts +42 -0
- package/dist/lib/grammar-entry.d.ts.map +1 -0
- package/dist/lib/grammar-entry.js +45 -0
- package/dist/lib/grammar-entry.js.map +1 -0
- package/dist/lib/index.d.ts +7 -5
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +0 -3
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/parse-context.d.ts +4 -15
- package/dist/lib/parse-context.d.ts.map +1 -1
- package/dist/lib/parse-context.js +4 -23
- package/dist/lib/parse-context.js.map +1 -1
- package/dist/lib/transform/grammar-fixture.js +3 -3
- package/dist/lib/transform/grammar-fixture.js.map +1 -1
- package/docs/The Ferrite Programming Language.md +568 -0
- package/docs/grammar.md +55 -3
- package/docs/parser-lr-browser-lib-split.md +174 -0
- package/grammars/6502.grammar +2 -2
- package/grammars/ferrite.grammar +107 -97
- package/grammars/grammar.grammar +19 -140
- package/grammars/lisp.grammar +3 -2
- package/package.json +7 -2
- package/dist/lib/grammar/grammar-json-path.d.ts +0 -2
- package/dist/lib/grammar/grammar-json-path.d.ts.map +0 -1
- package/dist/lib/grammar/grammar-json-path.esm.d.ts +0 -5
- package/dist/lib/grammar/grammar-json-path.esm.d.ts.map +0 -1
- package/dist/lib/grammar/grammar-json-path.esm.js +0 -9
- package/dist/lib/grammar/grammar-json-path.esm.js.map +0 -1
- package/dist/lib/grammar/grammar-json-path.js +0 -2
- package/dist/lib/grammar/grammar-json-path.js.map +0 -1
- package/dist/lib-cjs/ast/ast-node.js +0 -70
- package/dist/lib-cjs/ast/ast-node.js.map +0 -1
- package/dist/lib-cjs/errors/index.js +0 -9
- package/dist/lib-cjs/errors/index.js.map +0 -1
- package/dist/lib-cjs/errors/parser-lr-error.js +0 -52
- package/dist/lib-cjs/errors/parser-lr-error.js.map +0 -1
- package/dist/lib-cjs/grammar/ast-schema.js +0 -43
- package/dist/lib-cjs/grammar/ast-schema.js.map +0 -1
- package/dist/lib-cjs/grammar/ast-type.js +0 -3
- package/dist/lib-cjs/grammar/ast-type.js.map +0 -1
- package/dist/lib-cjs/grammar/expression.js +0 -3
- package/dist/lib-cjs/grammar/expression.js.map +0 -1
- package/dist/lib-cjs/grammar/grammar-from-cst.js +0 -641
- package/dist/lib-cjs/grammar/grammar-from-cst.js.map +0 -1
- package/dist/lib-cjs/grammar/grammar-json-path.js +0 -13
- package/dist/lib-cjs/grammar/grammar-json-path.js.map +0 -1
- package/dist/lib-cjs/grammar/grammar-literals.js +0 -71
- package/dist/lib-cjs/grammar/grammar-literals.js.map +0 -1
- package/dist/lib-cjs/grammar/grammar.js +0 -64
- package/dist/lib-cjs/grammar/grammar.js.map +0 -1
- package/dist/lib-cjs/grammar/grammar.json +0 -5760
- package/dist/lib-cjs/grammar/index.js +0 -21
- package/dist/lib-cjs/grammar/index.js.map +0 -1
- package/dist/lib-cjs/grammar/meta-grammar-table.js +0 -68
- package/dist/lib-cjs/grammar/meta-grammar-table.js.map +0 -1
- package/dist/lib-cjs/grammar/production.js +0 -3
- package/dist/lib-cjs/grammar/production.js.map +0 -1
- package/dist/lib-cjs/grammar/read-grammar-error.js +0 -22
- package/dist/lib-cjs/grammar/read-grammar-error.js.map +0 -1
- package/dist/lib-cjs/grammar/read-grammar.js +0 -24
- package/dist/lib-cjs/grammar/read-grammar.js.map +0 -1
- package/dist/lib-cjs/grammar/table-validator.js +0 -262
- package/dist/lib-cjs/grammar/table-validator.js.map +0 -1
- package/dist/lib-cjs/grammar/token-rule.js +0 -3
- package/dist/lib-cjs/grammar/token-rule.js.map +0 -1
- package/dist/lib-cjs/grammar/transform-expression.js +0 -3
- package/dist/lib-cjs/grammar/transform-expression.js.map +0 -1
- package/dist/lib-cjs/grammar/transform-rule.js +0 -3
- package/dist/lib-cjs/grammar/transform-rule.js.map +0 -1
- package/dist/lib-cjs/grammar/transform-schema.js +0 -43
- package/dist/lib-cjs/grammar/transform-schema.js.map +0 -1
- package/dist/lib-cjs/index.js +0 -66
- package/dist/lib-cjs/index.js.map +0 -1
- package/dist/lib-cjs/lexer/index.js +0 -32
- package/dist/lib-cjs/lexer/index.js.map +0 -1
- package/dist/lib-cjs/lexer/lexer-compile-error.js +0 -22
- package/dist/lib-cjs/lexer/lexer-compile-error.js.map +0 -1
- package/dist/lib-cjs/lexer/lexer-compile.js +0 -201
- package/dist/lib-cjs/lexer/lexer-compile.js.map +0 -1
- package/dist/lib-cjs/lexer/lexer-error.js +0 -22
- package/dist/lib-cjs/lexer/lexer-error.js.map +0 -1
- package/dist/lib-cjs/lexer/lexer-input-error.js +0 -17
- package/dist/lib-cjs/lexer/lexer-input-error.js.map +0 -1
- package/dist/lib-cjs/lexer/lexer-state-error.js +0 -19
- package/dist/lib-cjs/lexer/lexer-state-error.js.map +0 -1
- package/dist/lib-cjs/lexer/lexer.js +0 -278
- package/dist/lib-cjs/lexer/lexer.js.map +0 -1
- package/dist/lib-cjs/lexer/token.js +0 -44
- package/dist/lib-cjs/lexer/token.js.map +0 -1
- package/dist/lib-cjs/package.json +0 -3
- package/dist/lib-cjs/parse-context-error.js +0 -19
- package/dist/lib-cjs/parse-context-error.js.map +0 -1
- package/dist/lib-cjs/parse-context.js +0 -137
- package/dist/lib-cjs/parse-context.js.map +0 -1
- package/dist/lib-cjs/parse-output-error.js +0 -19
- package/dist/lib-cjs/parse-output-error.js.map +0 -1
- package/dist/lib-cjs/parse-output.js +0 -18
- package/dist/lib-cjs/parse-output.js.map +0 -1
- package/dist/lib-cjs/parse-table/analysis/first-follow.js +0 -294
- package/dist/lib-cjs/parse-table/analysis/first-follow.js.map +0 -1
- package/dist/lib-cjs/parse-table/analysis/index.js +0 -9
- package/dist/lib-cjs/parse-table/analysis/index.js.map +0 -1
- package/dist/lib-cjs/parse-table/bnf/bnf-grammar.js +0 -140
- package/dist/lib-cjs/parse-table/bnf/bnf-grammar.js.map +0 -1
- package/dist/lib-cjs/parse-table/bnf/bnf-production.js +0 -3
- package/dist/lib-cjs/parse-table/bnf/bnf-production.js.map +0 -1
- package/dist/lib-cjs/parse-table/bnf/bnf-symbol.js +0 -39
- package/dist/lib-cjs/parse-table/bnf/bnf-symbol.js.map +0 -1
- package/dist/lib-cjs/parse-table/bnf/desugar-ebnf.js +0 -224
- package/dist/lib-cjs/parse-table/bnf/desugar-ebnf.js.map +0 -1
- package/dist/lib-cjs/parse-table/bnf/index.js +0 -13
- package/dist/lib-cjs/parse-table/bnf/index.js.map +0 -1
- package/dist/lib-cjs/parse-table/build-lr-table.js +0 -171
- package/dist/lib-cjs/parse-table/build-lr-table.js.map +0 -1
- package/dist/lib-cjs/parse-table/index.js +0 -49
- package/dist/lib-cjs/parse-table/index.js.map +0 -1
- package/dist/lib-cjs/parse-table/lr-algorithm-error.js +0 -19
- package/dist/lib-cjs/parse-table/lr-algorithm-error.js.map +0 -1
- package/dist/lib-cjs/parse-table/lr-algorithm.js +0 -31
- package/dist/lib-cjs/parse-table/lr-algorithm.js.map +0 -1
- package/dist/lib-cjs/parse-table/lr0/index.js +0 -14
- package/dist/lib-cjs/parse-table/lr0/index.js.map +0 -1
- package/dist/lib-cjs/parse-table/lr0/lr0-item-set.js +0 -286
- package/dist/lib-cjs/parse-table/lr0/lr0-item-set.js.map +0 -1
- package/dist/lib-cjs/parse-table/lr1/index.js +0 -18
- package/dist/lib-cjs/parse-table/lr1/index.js.map +0 -1
- package/dist/lib-cjs/parse-table/lr1/lr1-item-set.js +0 -432
- package/dist/lib-cjs/parse-table/lr1/lr1-item-set.js.map +0 -1
- package/dist/lib-cjs/parse-table/parse-table-build-error.js +0 -24
- package/dist/lib-cjs/parse-table/parse-table-build-error.js.map +0 -1
- package/dist/lib-cjs/parse-table/parse-table-error.js +0 -19
- package/dist/lib-cjs/parse-table/parse-table-error.js.map +0 -1
- package/dist/lib-cjs/parse-table/parse-table-json.js +0 -12
- package/dist/lib-cjs/parse-table/parse-table-json.js.map +0 -1
- package/dist/lib-cjs/parse-table/parse-table.js +0 -345
- package/dist/lib-cjs/parse-table/parse-table.js.map +0 -1
- package/dist/lib-cjs/parse-table/slr/index.js +0 -13
- package/dist/lib-cjs/parse-table/slr/index.js.map +0 -1
- package/dist/lib-cjs/parse-table/slr/parse-action.js +0 -8
- package/dist/lib-cjs/parse-table/slr/parse-action.js.map +0 -1
- package/dist/lib-cjs/parse-table/slr/slr-table.js +0 -18
- package/dist/lib-cjs/parse-table/slr/slr-table.js.map +0 -1
- package/dist/lib-cjs/parse-table/table/index.js +0 -21
- package/dist/lib-cjs/parse-table/table/index.js.map +0 -1
- package/dist/lib-cjs/parse-table/table/lr-parse-table.js +0 -192
- package/dist/lib-cjs/parse-table/table/lr-parse-table.js.map +0 -1
- package/dist/lib-cjs/parse-table/table/parse-action.js +0 -54
- package/dist/lib-cjs/parse-table/table/parse-action.js.map +0 -1
- package/dist/lib-cjs/parse-table/table/table-builder-base.js +0 -153
- package/dist/lib-cjs/parse-table/table/table-builder-base.js.map +0 -1
- package/dist/lib-cjs/parse-table/token-inventory.js +0 -18
- package/dist/lib-cjs/parse-table/token-inventory.js.map +0 -1
- package/dist/lib-cjs/parser-lr.js +0 -143
- package/dist/lib-cjs/parser-lr.js.map +0 -1
- package/dist/lib-cjs/shift-reduce/index.js +0 -11
- package/dist/lib-cjs/shift-reduce/index.js.map +0 -1
- package/dist/lib-cjs/shift-reduce/shift-reduce-engine.js +0 -224
- package/dist/lib-cjs/shift-reduce/shift-reduce-engine.js.map +0 -1
- package/dist/lib-cjs/transform/binding-map.js +0 -82
- package/dist/lib-cjs/transform/binding-map.js.map +0 -1
- package/dist/lib-cjs/transform/cst-transformer.js +0 -480
- package/dist/lib-cjs/transform/cst-transformer.js.map +0 -1
- package/dist/lib-cjs/transform/grammar-fixture.js +0 -109
- package/dist/lib-cjs/transform/grammar-fixture.js.map +0 -1
- package/dist/lib-cjs/transform/index.js +0 -12
- package/dist/lib-cjs/transform/index.js.map +0 -1
- package/docs/parser-lr-enhancement-proposals.md +0 -337
- package/grammars/fixtures/table-only-import/table-only-smoke.cjs +0 -38
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# parser-lr: browser-safe library / Node CLI split
|
|
2
|
+
|
|
3
|
+
**Audience:** agent working on [parser-lr](https://github.com/adamrmoss/parser-lr)
|
|
4
|
+
**Consumer:** [edu-basic](https://github.com/adamrmoss/edu-basic) (`parser-lr@0.6.1`)
|
|
5
|
+
|
|
6
|
+
## Required architecture
|
|
7
|
+
|
|
8
|
+
| Artifact | Node dependencies | Runs in browser |
|
|
9
|
+
|----------|-------------------|-----------------|
|
|
10
|
+
| **Library** (`parser-lr` package entry, `dist/lib/`) | **None** | **Yes** |
|
|
11
|
+
| **CLI** (`bin/parser-lr.js`) | **All** (`fs`, `path`, `url`, grammar reading, `import.meta`) | No |
|
|
12
|
+
|
|
13
|
+
The CLI is a bundled binary that includes everything it needs. The library is a parse runtime only: load a pre-generated table JSON, lex, parse, return AST.
|
|
14
|
+
|
|
15
|
+
Grammar-file reading and table generation belong in the CLI (and optionally a separate Node-only subpath). They must not be on the main library import graph.
|
|
16
|
+
|
|
17
|
+
## Current failure
|
|
18
|
+
|
|
19
|
+
`ng build` in edu-basic fails:
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
Could not resolve "node:fs"
|
|
23
|
+
Could not resolve "node:path"
|
|
24
|
+
Could not resolve "node:url"
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Import chain from `import { ParseContext } from 'parser-lr'`:
|
|
28
|
+
|
|
29
|
+
```text
|
|
30
|
+
dist/lib/index.js
|
|
31
|
+
→ grammar/index.js
|
|
32
|
+
→ read-grammar.js
|
|
33
|
+
→ meta-grammar-table.js (readFileSync)
|
|
34
|
+
→ grammar-json-path.esm.js (import.meta.url)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Also: `dist/lib/parse-context.js` has a **top-level** `import { readGrammar } from './grammar/read-grammar.js'`, so `ParseContext.fromTableJson` still pulls grammar code even though edu-basic never calls `fromGrammar`.
|
|
38
|
+
|
|
39
|
+
Edu-basic runtime use: `ParseContext.fromTableJson(prebuiltTableJson)` → `lex` / `parseSource`. No `.grammar` files at runtime.
|
|
40
|
+
|
|
41
|
+
## Required changes
|
|
42
|
+
|
|
43
|
+
### 1. Library entry has no Node imports
|
|
44
|
+
|
|
45
|
+
`dist/lib/index.js` (and CJS twin) must not statically import:
|
|
46
|
+
|
|
47
|
+
- `read-grammar.js`
|
|
48
|
+
- `meta-grammar-table.js`
|
|
49
|
+
- `grammar-json-path*.js`
|
|
50
|
+
- any `node:*` module
|
|
51
|
+
|
|
52
|
+
### 2. `ParseContext` must not statically import grammar
|
|
53
|
+
|
|
54
|
+
`fromTableJson` / table branch of `fromSources` must work without loading grammar modules.
|
|
55
|
+
|
|
56
|
+
Options (pick one):
|
|
57
|
+
|
|
58
|
+
- Remove `fromGrammar` from the main library export; grammar construction lives in CLI only.
|
|
59
|
+
- Keep `fromGrammar` but implement it with **lazy** `import()` inside the method so it is not in the static graph.
|
|
60
|
+
|
|
61
|
+
### 3. Grammar APIs off the main entry
|
|
62
|
+
|
|
63
|
+
If Node consumers still need grammar-file APIs, expose them on a **separate** subpath only, e.g. `parser-lr/grammar`:
|
|
64
|
+
|
|
65
|
+
- `readGrammar`
|
|
66
|
+
- `validateGrammarTable`
|
|
67
|
+
- `formatTableValidationIssues`
|
|
68
|
+
- `Grammar`, `AstSchema`, `TransformSchema`
|
|
69
|
+
|
|
70
|
+
Do not re-export these from the main `parser-lr` entry.
|
|
71
|
+
|
|
72
|
+
### 4. CLI bundles all Node code
|
|
73
|
+
|
|
74
|
+
`bin/parser-lr.js` must include grammar reading, meta-grammar bootstrap, and filesystem path resolution. Fix the existing bug where CLI looks for `bin/grammar.json` instead of `dist/lib/grammar/grammar.json` (see symptom below).
|
|
75
|
+
|
|
76
|
+
### 5. Lazy meta-grammar on grammar path
|
|
77
|
+
|
|
78
|
+
Even on the grammar/CLI path, do not load `grammar.json` or evaluate `import.meta` at module evaluation time. Load on first `readGrammar()` / `metaGrammarTable()` call.
|
|
79
|
+
|
|
80
|
+
## Library exports (minimum for edu-basic)
|
|
81
|
+
|
|
82
|
+
Main entry must export at least:
|
|
83
|
+
|
|
84
|
+
- `ParseContext`
|
|
85
|
+
- `AstNode`
|
|
86
|
+
- `Token` (type)
|
|
87
|
+
- `isEofToken`
|
|
88
|
+
|
|
89
|
+
Add other runtime symbols only if existing parser-lr tests require them on the main entry.
|
|
90
|
+
|
|
91
|
+
## Acceptance tests
|
|
92
|
+
|
|
93
|
+
Run all of these against **`npm pack` output**, not only the dev tree.
|
|
94
|
+
|
|
95
|
+
### A. Browser bundle
|
|
96
|
+
|
|
97
|
+
esbuild must succeed:
|
|
98
|
+
|
|
99
|
+
```javascript
|
|
100
|
+
// entry.mjs
|
|
101
|
+
import { ParseContext } from 'parser-lr';
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
esbuild entry.mjs --bundle --platform=browser --outfile=/tmp/out.js
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Exit 0. No `node:fs`, `node:path`, or `node:url` resolution errors.
|
|
109
|
+
|
|
110
|
+
### B. Table-only runtime (ESM)
|
|
111
|
+
|
|
112
|
+
```javascript
|
|
113
|
+
import { ParseContext } from 'parser-lr';
|
|
114
|
+
import { readFileSync } from 'node:fs';
|
|
115
|
+
|
|
116
|
+
const table = JSON.parse(readFileSync('grammars/calc.table.json', 'utf8'));
|
|
117
|
+
const ctx = ParseContext.fromTableJson(JSON.stringify(table));
|
|
118
|
+
const ast = ctx.parseSource('1 + 2');
|
|
119
|
+
if (!ast) throw new Error('parse failed');
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Must not throw `import.meta` errors. Must not require `grammar.json` on disk for this import.
|
|
123
|
+
|
|
124
|
+
### C. Table-only runtime (CJS)
|
|
125
|
+
|
|
126
|
+
```javascript
|
|
127
|
+
const { ParseContext } = require('parser-lr');
|
|
128
|
+
// same table smoke as B
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### D. CLI from tarball
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
npm pack
|
|
135
|
+
tmpdir=$(mktemp -d)
|
|
136
|
+
tar -xzf parser-lr-*.tgz -C "$tmpdir"
|
|
137
|
+
cd "$tmpdir/package"
|
|
138
|
+
node bin/parser-lr.js table validate -g grammars/calc.grammar
|
|
139
|
+
node bin/parser-lr.js table generate -g grammars/calc.grammar -o /tmp/calc.json -a lalr
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Both exit 0.
|
|
143
|
+
|
|
144
|
+
### E. Grammar subpath (if implemented)
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
node -e "import('parser-lr/grammar').then(m => console.log(typeof m.readGrammar))"
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Must not be required for tests A–C.
|
|
151
|
+
|
|
152
|
+
## Known CLI bug (fix while here)
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
npx parser-lr table validate -g grammars/calc.grammar
|
|
156
|
+
# ENOENT: .../node_modules/parser-lr/bin/grammar.json
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
`grammar.json` exists under `dist/lib/grammar/` but CLI resolves relative to `bin/`.
|
|
160
|
+
|
|
161
|
+
## After release
|
|
162
|
+
|
|
163
|
+
edu-basic will:
|
|
164
|
+
|
|
165
|
+
1. Bump `parser-lr` to the new version.
|
|
166
|
+
2. Re-run `npm run build` (Angular) and `npm test`.
|
|
167
|
+
3. No browser polyfills for Node built-ins.
|
|
168
|
+
|
|
169
|
+
Target version: **0.7.0** (export map changes, ESM-only, grammar subpath).
|
|
170
|
+
|
|
171
|
+
## Non-goals
|
|
172
|
+
|
|
173
|
+
- No change to parse semantics, table JSON format, or identity AST shape.
|
|
174
|
+
- No requirement for edu-basic to stub `node:*` in the browser bundle.
|
package/grammars/6502.grammar
CHANGED
|
@@ -112,7 +112,7 @@ grammar
|
|
|
112
112
|
|
|
113
113
|
ast
|
|
114
114
|
program =
|
|
115
|
-
{ line }
|
|
115
|
+
#program { line }
|
|
116
116
|
;
|
|
117
117
|
|
|
118
118
|
line =
|
|
@@ -122,7 +122,7 @@ ast
|
|
|
122
122
|
;
|
|
123
123
|
|
|
124
124
|
directive =
|
|
125
|
-
[dotTok]:dot
|
|
125
|
+
#directive [dotTok]:dot
|
|
126
126
|
[sym]:identifier
|
|
127
127
|
[value]:hex_number
|
|
128
128
|
;
|
package/grammars/ferrite.grammar
CHANGED
|
@@ -1,24 +1,28 @@
|
|
|
1
|
-
// Ferrite — a C-like language with C#-style structs, namespaces, and pointer semantics.
|
|
2
|
-
// No preprocessor; sources compile as single units (namespaces + using
|
|
1
|
+
// Ferrite — a C-like language with C#-style structs, file-scoped namespaces, and pointer semantics.
|
|
2
|
+
// No preprocessor; sources compile as single units (namespaces + using).
|
|
3
|
+
// Naming convention (not enforced by the grammar): PascalCase types, camelCase functions and variables.
|
|
3
4
|
//
|
|
4
5
|
// Example:
|
|
5
6
|
//
|
|
6
|
-
// namespace Ferrite.Math
|
|
7
|
-
// struct Vec2 {
|
|
8
|
-
// float32 x;
|
|
9
|
-
// float32 y;
|
|
10
|
-
// float32 dot(Vec2* other) {
|
|
11
|
-
// return x * other->x + y * other->y;
|
|
12
|
-
// }
|
|
13
|
-
// }
|
|
14
|
-
// }
|
|
7
|
+
// namespace Ferrite.Math;
|
|
15
8
|
//
|
|
16
|
-
// using Ferrite.
|
|
9
|
+
// using Ferrite.Core;
|
|
17
10
|
//
|
|
18
|
-
//
|
|
11
|
+
// public struct Vec2
|
|
12
|
+
// {
|
|
13
|
+
// Float32 x;
|
|
14
|
+
// Float32 y;
|
|
15
|
+
// Float32 dot(Vec2* other)
|
|
16
|
+
// {
|
|
17
|
+
// return x * other->x + y * other->y;
|
|
18
|
+
// }
|
|
19
|
+
// };
|
|
20
|
+
//
|
|
21
|
+
// public Int32 main()
|
|
22
|
+
// {
|
|
19
23
|
// Vec2 a = { 1.0, 2.0 };
|
|
20
24
|
// Vec2* p = &a;
|
|
21
|
-
// return (
|
|
25
|
+
// return (Int32)p->dot(&a);
|
|
22
26
|
// }
|
|
23
27
|
|
|
24
28
|
name "ferrite" ;
|
|
@@ -27,6 +31,8 @@ tokens
|
|
|
27
31
|
kw_struct = /struct/ ;
|
|
28
32
|
kw_namespace = /namespace/ ;
|
|
29
33
|
kw_using = /using/ ;
|
|
34
|
+
kw_public = /public/ ;
|
|
35
|
+
kw_private = /private/ ;
|
|
30
36
|
kw_if = /if/ ;
|
|
31
37
|
kw_else = /else/ ;
|
|
32
38
|
kw_while = /while/ ;
|
|
@@ -38,19 +44,19 @@ tokens
|
|
|
38
44
|
kw_null = /null/ ;
|
|
39
45
|
kw_true = /true/ ;
|
|
40
46
|
kw_false = /false/ ;
|
|
41
|
-
kw_void = /
|
|
42
|
-
kw_bool = /
|
|
43
|
-
kw_int8 = /
|
|
44
|
-
kw_int16 = /
|
|
45
|
-
kw_int32 = /
|
|
46
|
-
kw_int64 = /
|
|
47
|
-
kw_uint8 = /
|
|
48
|
-
kw_uint16 = /
|
|
49
|
-
kw_uint32 = /
|
|
50
|
-
kw_uint64 = /
|
|
51
|
-
kw_float32 = /
|
|
52
|
-
kw_float64 = /
|
|
53
|
-
kw_char = /
|
|
47
|
+
kw_void = /Void/ ;
|
|
48
|
+
kw_bool = /Bool/ ;
|
|
49
|
+
kw_int8 = /Int8/ ;
|
|
50
|
+
kw_int16 = /Int16/ ;
|
|
51
|
+
kw_int32 = /Int32/ ;
|
|
52
|
+
kw_int64 = /Int64/ ;
|
|
53
|
+
kw_uint8 = /UInt8/ ;
|
|
54
|
+
kw_uint16 = /UInt16/ ;
|
|
55
|
+
kw_uint32 = /UInt32/ ;
|
|
56
|
+
kw_uint64 = /UInt64/ ;
|
|
57
|
+
kw_float32 = /Float32/ ;
|
|
58
|
+
kw_float64 = /Float64/ ;
|
|
59
|
+
kw_char = /Char/ ;
|
|
54
60
|
|
|
55
61
|
identifier = /[A-Za-z_][A-Za-z0-9_]*/ ;
|
|
56
62
|
int_literal = /0x[0-9A-F]+|0b[01]+|[0-9]+/i ;
|
|
@@ -112,28 +118,27 @@ start program ;
|
|
|
112
118
|
|
|
113
119
|
grammar
|
|
114
120
|
program =
|
|
121
|
+
[ [ns]:file_namespace ]
|
|
122
|
+
{ [use]:using_directive }
|
|
115
123
|
{ [decl]:top_decl }
|
|
116
124
|
;
|
|
117
125
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
| #using [useKw]:kw_using [qname]:qualified_name [semi]:semicolon
|
|
121
|
-
| #struct struct_decl
|
|
122
|
-
| #function function_decl
|
|
126
|
+
file_namespace =
|
|
127
|
+
[nsKw]:kw_namespace [qname]:qualified_name [semi]:semicolon
|
|
123
128
|
;
|
|
124
129
|
|
|
125
|
-
|
|
126
|
-
[
|
|
127
|
-
{ [member]:namespace_member }
|
|
128
|
-
[close]:rbrace
|
|
130
|
+
using_directive =
|
|
131
|
+
[useKw]:kw_using [qname]:qualified_name [semi]:semicolon
|
|
129
132
|
;
|
|
130
133
|
|
|
131
|
-
|
|
134
|
+
top_decl =
|
|
132
135
|
#struct struct_decl
|
|
133
136
|
| #function function_decl
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
+
;
|
|
138
|
+
|
|
139
|
+
access_modifier =
|
|
140
|
+
#public [keyword]:kw_public
|
|
141
|
+
| #private [keyword]:kw_private
|
|
137
142
|
;
|
|
138
143
|
|
|
139
144
|
qualified_name =
|
|
@@ -145,6 +150,7 @@ grammar
|
|
|
145
150
|
;
|
|
146
151
|
|
|
147
152
|
struct_decl =
|
|
153
|
+
[access]:access_modifier
|
|
148
154
|
[structKw]:kw_struct
|
|
149
155
|
[sym]:identifier
|
|
150
156
|
[body]:struct_body
|
|
@@ -186,12 +192,14 @@ grammar
|
|
|
186
192
|
|
|
187
193
|
function_decl =
|
|
188
194
|
#defined
|
|
195
|
+
[access]:access_modifier
|
|
189
196
|
[type]:type_spec
|
|
190
197
|
[sym]:identifier
|
|
191
198
|
[open]:lpar
|
|
192
199
|
[close]:rpar
|
|
193
200
|
[body]:block
|
|
194
201
|
| #definedParams
|
|
202
|
+
[access]:access_modifier
|
|
195
203
|
[type]:type_spec
|
|
196
204
|
[sym]:identifier
|
|
197
205
|
[open]:lpar
|
|
@@ -199,12 +207,14 @@ grammar
|
|
|
199
207
|
[close]:rpar
|
|
200
208
|
[body]:block
|
|
201
209
|
| #prototype
|
|
210
|
+
[access]:access_modifier
|
|
202
211
|
[type]:type_spec
|
|
203
212
|
[sym]:identifier
|
|
204
213
|
[open]:lpar
|
|
205
214
|
[close]:rpar
|
|
206
215
|
[semi]:semicolon
|
|
207
216
|
| #prototypeParams
|
|
217
|
+
[access]:access_modifier
|
|
208
218
|
[type]:type_spec
|
|
209
219
|
[sym]:identifier
|
|
210
220
|
[open]:lpar
|
|
@@ -273,7 +283,7 @@ grammar
|
|
|
273
283
|
;
|
|
274
284
|
|
|
275
285
|
expr_sep =
|
|
276
|
-
[commaTok]:comma [rest]:expression
|
|
286
|
+
#sep [commaTok]:comma [rest]:expression
|
|
277
287
|
;
|
|
278
288
|
|
|
279
289
|
for_init =
|
|
@@ -425,39 +435,45 @@ grammar
|
|
|
425
435
|
|
|
426
436
|
ast
|
|
427
437
|
program =
|
|
428
|
-
|
|
438
|
+
#program [ [ns]:file_namespace ] [usings]:using_list [decls]:decl_list
|
|
429
439
|
;
|
|
430
440
|
|
|
431
|
-
|
|
432
|
-
#
|
|
433
|
-
| #using [useKw]:kw_using [qname]:qualified_name [semi]:semicolon
|
|
434
|
-
| #struct struct_decl
|
|
435
|
-
| #function function_decl
|
|
441
|
+
using_list =
|
|
442
|
+
#list { using_directive }
|
|
436
443
|
;
|
|
437
444
|
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
445
|
+
decl_list =
|
|
446
|
+
#list { top_decl }
|
|
447
|
+
;
|
|
448
|
+
|
|
449
|
+
file_namespace =
|
|
450
|
+
#file_namespace [nsKw]:kw_namespace [qname]:qualified_name [semi]:semicolon
|
|
451
|
+
;
|
|
452
|
+
|
|
453
|
+
using_directive =
|
|
454
|
+
#using_directive [useKw]:kw_using [qname]:qualified_name [semi]:semicolon
|
|
442
455
|
;
|
|
443
456
|
|
|
444
|
-
|
|
457
|
+
top_decl =
|
|
445
458
|
#struct struct_decl
|
|
446
459
|
| #function function_decl
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
460
|
+
;
|
|
461
|
+
|
|
462
|
+
access_modifier =
|
|
463
|
+
#public [keyword]:kw_public
|
|
464
|
+
| #private [keyword]:kw_private
|
|
450
465
|
;
|
|
451
466
|
|
|
452
467
|
qualified_name =
|
|
453
|
-
[head]:identifier { name_part }
|
|
468
|
+
#qualified_name [head]:identifier { name_part }
|
|
454
469
|
;
|
|
455
470
|
|
|
456
471
|
name_part =
|
|
457
|
-
[dotTok]:dot [part]:identifier
|
|
472
|
+
#part [dotTok]:dot [part]:identifier
|
|
458
473
|
;
|
|
459
474
|
|
|
460
475
|
struct_decl =
|
|
476
|
+
#struct_decl [access]:access_modifier
|
|
461
477
|
[structKw]:kw_struct
|
|
462
478
|
[sym]:identifier
|
|
463
479
|
[body]:struct_body
|
|
@@ -465,7 +481,7 @@ ast
|
|
|
465
481
|
;
|
|
466
482
|
|
|
467
483
|
struct_body =
|
|
468
|
-
[open]:lbrace
|
|
484
|
+
#struct_body [open]:lbrace
|
|
469
485
|
{ [member]:struct_member }
|
|
470
486
|
[close]:rbrace
|
|
471
487
|
;
|
|
@@ -476,7 +492,7 @@ ast
|
|
|
476
492
|
;
|
|
477
493
|
|
|
478
494
|
field_decl =
|
|
479
|
-
[type]:type_spec
|
|
495
|
+
#field_decl [type]:type_spec
|
|
480
496
|
[sym]:identifier
|
|
481
497
|
[semi]:semicolon
|
|
482
498
|
;
|
|
@@ -499,12 +515,14 @@ ast
|
|
|
499
515
|
|
|
500
516
|
function_decl =
|
|
501
517
|
#defined
|
|
518
|
+
[access]:access_modifier
|
|
502
519
|
[type]:type_spec
|
|
503
520
|
[sym]:identifier
|
|
504
521
|
[open]:lpar
|
|
505
522
|
[close]:rpar
|
|
506
523
|
[body]:block
|
|
507
524
|
| #definedParams
|
|
525
|
+
[access]:access_modifier
|
|
508
526
|
[type]:type_spec
|
|
509
527
|
[sym]:identifier
|
|
510
528
|
[open]:lpar
|
|
@@ -512,12 +530,14 @@ ast
|
|
|
512
530
|
[close]:rpar
|
|
513
531
|
[body]:block
|
|
514
532
|
| #prototype
|
|
533
|
+
[access]:access_modifier
|
|
515
534
|
[type]:type_spec
|
|
516
535
|
[sym]:identifier
|
|
517
536
|
[open]:lpar
|
|
518
537
|
[close]:rpar
|
|
519
538
|
[semi]:semicolon
|
|
520
539
|
| #prototypeParams
|
|
540
|
+
[access]:access_modifier
|
|
521
541
|
[type]:type_spec
|
|
522
542
|
[sym]:identifier
|
|
523
543
|
[open]:lpar
|
|
@@ -531,16 +551,17 @@ ast
|
|
|
531
551
|
;
|
|
532
552
|
|
|
533
553
|
param_sep =
|
|
534
|
-
[commaTok]:comma [rest]:param
|
|
554
|
+
#sep [commaTok]:comma [rest]:param
|
|
535
555
|
;
|
|
536
556
|
|
|
537
557
|
param =
|
|
538
|
-
[type]:type_spec
|
|
558
|
+
#param [type]:type_spec
|
|
539
559
|
[sym]:identifier
|
|
540
560
|
;
|
|
541
561
|
|
|
542
562
|
type_spec =
|
|
543
|
-
#
|
|
563
|
+
#pointers { [ptr]:star }
|
|
564
|
+
| #voidType [voidKw]:kw_void { [ptr]:star }
|
|
544
565
|
| #bool [boolKw]:kw_bool { [ptr]:star }
|
|
545
566
|
| #int8 [int8Kw]:kw_int8 { [ptr]:star }
|
|
546
567
|
| #int16 [int16Kw]:kw_int16 { [ptr]:star }
|
|
@@ -559,7 +580,7 @@ ast
|
|
|
559
580
|
;
|
|
560
581
|
|
|
561
582
|
block =
|
|
562
|
-
[open]:lbrace
|
|
583
|
+
#block [open]:lbrace
|
|
563
584
|
{ statement }
|
|
564
585
|
[close]:rbrace
|
|
565
586
|
;
|
|
@@ -586,7 +607,7 @@ ast
|
|
|
586
607
|
;
|
|
587
608
|
|
|
588
609
|
expr_sep =
|
|
589
|
-
[commaTok]:comma [rest]:expression
|
|
610
|
+
#sep [commaTok]:comma [rest]:expression
|
|
590
611
|
;
|
|
591
612
|
|
|
592
613
|
for_init =
|
|
@@ -738,41 +759,39 @@ ast
|
|
|
738
759
|
|
|
739
760
|
transform
|
|
740
761
|
program ->
|
|
741
|
-
#main
|
|
762
|
+
#main program.#program(ns, program$repeat_0, program$repeat_1) ;
|
|
742
763
|
|
|
743
764
|
program$repeat_0 ->
|
|
744
|
-
#main flatten(
|
|
765
|
+
#main flatten(using_list.#list, use, program$repeat_0) ;
|
|
745
766
|
|
|
746
|
-
|
|
747
|
-
#
|
|
748
|
-
| #using top_decl.#using(useKw, qname, semi)
|
|
749
|
-
| #struct pass(struct_decl)
|
|
750
|
-
| #function pass(function_decl) ;
|
|
767
|
+
program$repeat_1 ->
|
|
768
|
+
#main flatten(decl_list.#list, decl, program$repeat_1) ;
|
|
751
769
|
|
|
752
|
-
|
|
753
|
-
#main
|
|
770
|
+
file_namespace ->
|
|
771
|
+
#main file_namespace.#file_namespace(nsKw, qname, semi) ;
|
|
754
772
|
|
|
755
|
-
|
|
756
|
-
#main
|
|
773
|
+
using_directive ->
|
|
774
|
+
#main using_directive.#using_directive(useKw, qname, semi) ;
|
|
757
775
|
|
|
758
|
-
|
|
776
|
+
top_decl ->
|
|
759
777
|
#struct pass(struct_decl)
|
|
760
|
-
| #function pass(function_decl)
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
778
|
+
| #function pass(function_decl) ;
|
|
779
|
+
|
|
780
|
+
access_modifier ->
|
|
781
|
+
#public access_modifier.#public(keyword)
|
|
782
|
+
| #private access_modifier.#private(keyword) ;
|
|
764
783
|
|
|
765
784
|
qualified_name ->
|
|
766
|
-
#main qualified_name.#qualified_name(head, qualified_name$
|
|
785
|
+
#main qualified_name.#qualified_name(head, qualified_name$repeat_0) ;
|
|
767
786
|
|
|
768
|
-
qualified_name$
|
|
769
|
-
#main flatten(qualified_name.#qualified_name, name_part, qualified_name$
|
|
787
|
+
qualified_name$repeat_0 ->
|
|
788
|
+
#main flatten(qualified_name.#qualified_name, name_part, qualified_name$repeat_0) ;
|
|
770
789
|
|
|
771
790
|
name_part ->
|
|
772
791
|
#main name_part.#part(dotTok, part) ;
|
|
773
792
|
|
|
774
793
|
struct_decl ->
|
|
775
|
-
#main struct_decl.#struct_decl(structKw, sym, body, semi) ;
|
|
794
|
+
#main struct_decl.#struct_decl(access, structKw, sym, body, semi) ;
|
|
776
795
|
|
|
777
796
|
struct_body ->
|
|
778
797
|
#main struct_body.#struct_body(open, struct_body$repeat_0, close) ;
|
|
@@ -792,17 +811,14 @@ transform
|
|
|
792
811
|
| #methodParams method_decl.#method(type, sym, open, params, close, body) ;
|
|
793
812
|
|
|
794
813
|
function_decl ->
|
|
795
|
-
#defined function_decl.#defined(type, sym, open, close, body)
|
|
796
|
-
| #definedParams function_decl.#defined(type, sym, open, params, close, body)
|
|
797
|
-
| #prototype function_decl.#prototype(type, sym, open, close, semi)
|
|
798
|
-
| #prototypeParams function_decl.#prototype(type, sym, open, params, close, semi) ;
|
|
814
|
+
#defined function_decl.#defined(access, type, sym, open, close, body)
|
|
815
|
+
| #definedParams function_decl.#defined(access, type, sym, open, params, close, body)
|
|
816
|
+
| #prototype function_decl.#prototype(access, type, sym, open, close, semi)
|
|
817
|
+
| #prototypeParams function_decl.#prototype(access, type, sym, open, params, close, semi) ;
|
|
799
818
|
|
|
800
819
|
param_list ->
|
|
801
820
|
#main flatten(param_list.#list, first, param_list$repeat_0) ;
|
|
802
821
|
|
|
803
|
-
param_list$repeat_0 ->
|
|
804
|
-
#main flatten(param_list.#list, param_sep, param_list$repeat_0) ;
|
|
805
|
-
|
|
806
822
|
param_sep ->
|
|
807
823
|
#main param_sep.#sep(commaTok, rest) ;
|
|
808
824
|
|
|
@@ -854,9 +870,6 @@ transform
|
|
|
854
870
|
init_list ->
|
|
855
871
|
#main flatten(init_list.#list, first, init_list$repeat_0) ;
|
|
856
872
|
|
|
857
|
-
init_list$repeat_0 ->
|
|
858
|
-
#main flatten(init_list.#list, expr_sep, init_list$repeat_0) ;
|
|
859
|
-
|
|
860
873
|
expr_sep ->
|
|
861
874
|
#main expr_sep.#sep(commaTok, rest) ;
|
|
862
875
|
|
|
@@ -974,9 +987,6 @@ transform
|
|
|
974
987
|
arg_list ->
|
|
975
988
|
#main flatten(arg_list.#list, first, arg_list$repeat_0) ;
|
|
976
989
|
|
|
977
|
-
arg_list$repeat_0 ->
|
|
978
|
-
#main flatten(arg_list.#list, expr_sep, arg_list$repeat_0) ;
|
|
979
|
-
|
|
980
990
|
primary_expr ->
|
|
981
991
|
#ident pass(sym)
|
|
982
992
|
| #int pass(value)
|