Skip to content

Commit b01923e

Browse files
authored
Merge pull request #22 from streamich/calculator
Calculator
2 parents 938de71 + 9f049b1 commit b01923e

File tree

2 files changed

+116
-0
lines changed

2 files changed

+116
-0
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import {CodegenGrammar} from '../../codegen/CodegenGrammar';
2+
import {CodegenContext, ParseContext} from '../../context';
3+
import {GrammarPrinter, printCst, printTraceNode} from '../../print';
4+
import {RootTraceNode} from '../../types';
5+
import {grammar} from '../calculator';
6+
7+
const codegenCtx = new CodegenContext(true, true, true);
8+
const codegen = new CodegenGrammar(grammar, codegenCtx);
9+
10+
const toCst = (src: string) => {
11+
const parser = codegen.compile();
12+
const trace: RootTraceNode = {pos: 0, children: []};
13+
const ctx = new ParseContext(src, true, [trace]);
14+
const cst = parser(ctx, 0)!;
15+
// console.log(printTraceNode(trace.children[0], '', src));
16+
// console.log(printCst(cst, '', src));
17+
return {cst, trace};
18+
};
19+
20+
const toAst = (src: string) => {
21+
const cst = toCst(src);
22+
const ast = cst.cst.ptr.toAst(cst.cst, src);
23+
return {...cst, ast};
24+
};
25+
26+
test('can evaluate a simple expression', () => {
27+
const text = '2 * 2 + 4 * 3';
28+
const res = toAst(text);
29+
// console.log(GrammarPrinter.print(grammar));
30+
// console.log(printTraceNode(res.trace, '', text));
31+
// console.log(printCst(res.cst, '', text));
32+
expect(res.ast).toBe(16);
33+
});

src/grammars/calculator.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import type {Grammar} from '../types';
2+
3+
/**
4+
* A simple math expression grammar.
5+
*/
6+
export const grammar: Grammar = {
7+
start: 'SingleExpression',
8+
9+
cst: {
10+
Whitespace: {t: /\s*/, ast: null},
11+
12+
SingleExpression: {
13+
p: [{r: 'Whitespace'}, {r: 'Expression'}, {r: 'Whitespace'}],
14+
ast: ['$', '/children/0'],
15+
},
16+
17+
Expression: {
18+
u: [{r: 'AdditiveExpression'}, {r: 'Literal'}],
19+
ast: ['$', '/children/0'],
20+
},
21+
22+
AdditiveExpression: {
23+
p: [{r: 'MultiplicativeExpression'}, {r: 'AdditiveExpressionCont'}],
24+
ast: [
25+
'?',
26+
['==', ['len', ['$', '/children']], 1],
27+
['$', '/children/0'],
28+
[
29+
'?',
30+
['==', ['$', '/children/1/children/0'], '+'],
31+
['+', ['$', '/children/0'], ['$', '/children/1/children/1', 1]],
32+
['-', ['$', '/children/0'], ['$', '/children/1/children/1', 1]],
33+
],
34+
],
35+
},
36+
AdditiveExpressionCont: {
37+
u: [
38+
[
39+
{r: 'Whitespace'},
40+
{t: ['+', '-'], ast: ['$', '/raw']},
41+
{r: 'Whitespace'},
42+
{r: 'AdditiveExpression'},
43+
{r: 'AdditiveExpressionCont'},
44+
],
45+
'',
46+
],
47+
ast: ['$', '/children/0', 0],
48+
},
49+
50+
MultiplicativeExpression: {
51+
p: [{r: 'Literal'}, {r: 'MultiplicativeExpressionCont'}],
52+
ast: [
53+
'?',
54+
['==', ['len', ['$', '/children']], 1],
55+
['$', '/children/0'],
56+
[
57+
'?',
58+
['==', ['$', '/children/1/children/0'], '*'],
59+
['*', ['$', '/children/0'], ['$', '/children/1/children/1', 1]],
60+
['/', ['$', '/children/0'], ['$', '/children/1/children/1', 1]],
61+
],
62+
],
63+
},
64+
MultiplicativeExpressionCont: {
65+
u: [
66+
[
67+
{r: 'Whitespace'},
68+
{t: ['*', '/'], ast: ['$', '/raw']},
69+
{r: 'Whitespace'},
70+
{r: 'MultiplicativeExpression'},
71+
{r: 'MultiplicativeExpressionCont'},
72+
],
73+
'',
74+
],
75+
ast: ['$', '/children/0', 0],
76+
},
77+
78+
Literal: {
79+
t: /\d+/,
80+
ast: ['num', ['$', '/raw']],
81+
},
82+
},
83+
};

0 commit comments

Comments
 (0)