simple parser

This commit is contained in:
Elizabeth Hunt 2024-02-23 17:27:16 -07:00
parent d0d6aae1e5
commit e8e9ee18f2
Signed by: simponic
GPG Key ID: 52B3774857EB24B1
6 changed files with 198 additions and 142 deletions

View File

@ -17,7 +17,7 @@ SelectExpression
_?
LPAREN
_?
select:Integer
record:Integer
_?
COMMA
_?
@ -27,16 +27,18 @@ SelectExpression
_?
bind:Identifier
_?
COMMA
_?
continuation:ContinuationExpression
_?
RPAREN { return { select, val, bind, continuation }; }
RPAREN { return { select: { record, val, bind, continuation } }; }
OffsetExpression
= OFFSET
_?
LPAREN
_?
offset:Integer
index:Integer
_?
COMMA
_?
@ -48,31 +50,25 @@ OffsetExpression
_?
continuation:ContinuationExpression
_?
RPAREN { return { offset, val, bind, continuation }; }
RPAREN { return { offset: { index, val, bind, continuation } }; }
IdentifierList
= LBRACKET
_?
identifiers:(ident:Identifier _? COMMA _?)*
identifiers:(Identifier _? COMMA _?)*
_?
lastIdent:Identifier?
_?
RBRACKET {
return identifiers.length || lastIdent
? [...identifiers.map(x => x.ident), lastIdent]
? [...identifiers.map(x => x[0]), lastIdent]
: [];
}
ValueList
= LBRACKET
_?
values:(value:Value _? COMMA _?)*
_?
lastValue:Value?
_?
RBRACKET {
= LBRACKET _? values:(Value _? COMMA _?)* _? lastValue:Value? _? RBRACKET {
return values.length || lastValue
? [...values.map(x => x.value), lastValue]
? [...values.map(x => x[0]), lastValue]
: [];
}
@ -87,11 +83,11 @@ SwitchExpression
_?
continuations:ContinuationList
_?
RPAREN { return { switchIndex, continuations }; }
RPAREN { return { switch: { switchIndex, continuations } }; }
ApplicationExpression
= APP _? LPAREN _? fn:Value _? COMMA _? args:ValueList _? RPAREN {
return { fn, args };
return { application: { fn, args } };
}
FixBinding
@ -111,14 +107,14 @@ FixBinding
FixBindingList
= LBRACKET
_
bindings:(binding:FixBinding _? COMMA _?)*
_?
bindings:(FixBinding _? COMMA _?)*
_?
lastBinding:FixBinding?
_?
RBRACKET {
return bindings.length || lastBinding
? [...bindings.map(x => x.binding), lastBinding]
? [...bindings.map(x => x[0]), lastBinding]
: [];
}
@ -133,18 +129,18 @@ FixExpression
_?
continuation:ContinuationExpression
_?
RPAREN { return { fixBindings, continuation }; }
RPAREN { return { fix: { fixBindings, continuation } }; }
ContinuationList
= LBRACKET
_?
continuations:(continuation:ContinuationExpression _? COMMA _?)*
continuations:(ContinuationExpression _? COMMA _?)*
_?
lastContinuation:ContinuationExpression?
_?
RBRACKET {
return lastContinuation || continuations.length
? [...continuations.map(x => x.continuation), lastContinuation]
? [...continuations.map(x => x[0]), lastContinuation]
: [];
}
@ -167,7 +163,11 @@ PrimitiveOperationExpression
_?
continuations:ContinuationList
_?
RPAREN { return { opr, operands, resultBindings, continuations }; }
RPAREN {
return {
primitiveOperation: { opr, operands, resultBindings, continuations },
};
}
RecordExpressionTuple
= LPAREN
@ -183,13 +183,13 @@ RecordExpressionTuple
RecordExpressionTupleList
= LBRACKET
_?
records:(record:RecordExpressionTuple _? COMMA _?)*
records:(RecordExpressionTuple _? COMMA _?)*
_?
lastRecord:RecordExpressionTuple?
_?
RBRACKET {
return records.length || lastRecord
? [...records.map(x => x.record), lastRecord]
? [...records.map(x => x[0]), lastRecord]
: [];
}
@ -210,9 +210,11 @@ RecordExpression
_?
RPAREN {
return {
record: {
records,
address,
body,
},
};
}

View File

@ -408,17 +408,17 @@ function peg$parse(input, options) {
return exprs.filter(x => !Array.isArray(x));
};// @ts-ignore
var peg$f1 = function(select, val, bind, continuation) {// @ts-ignore
return { select, val, bind, continuation }; };// @ts-ignore
var peg$f1 = function(record, val, bind, continuation) {// @ts-ignore
return { select: { record, val, bind, continuation } }; };// @ts-ignore
var peg$f2 = function(offset, val, bind, continuation) {// @ts-ignore
return { offset, val, bind, continuation }; };// @ts-ignore
var peg$f2 = function(index, val, bind, continuation) {// @ts-ignore
return { offset: { index, val, bind, continuation } }; };// @ts-ignore
var peg$f3 = function(identifiers, lastIdent) {
// @ts-ignore
return identifiers.length || lastIdent
// @ts-ignore
? [...identifiers.map(x => x.ident), lastIdent]
? [...identifiers.map(x => x[0]), lastIdent]
: [];
};// @ts-ignore
@ -426,39 +426,44 @@ function peg$parse(input, options) {
// @ts-ignore
return values.length || lastValue
// @ts-ignore
? [...values.map(x => x.value), lastValue]
? [...values.map(x => x[0]), lastValue]
: [];
};// @ts-ignore
var peg$f5 = function(switchIndex, continuations) {// @ts-ignore
return { switchIndex, continuations }; };// @ts-ignore
return { switch: { switchIndex, continuations } }; };// @ts-ignore
var peg$f6 = function(fn, args) {
// @ts-ignore
return { fn, args };
return { application: { fn, args } };
};// @ts-ignore
var peg$f7 = function(bindings, lastBinding) {
// @ts-ignore
return bindings.length || lastBinding
// @ts-ignore
? [...bindings.map(x => x.binding), lastBinding]
? [...bindings.map(x => x[0]), lastBinding]
: [];
};// @ts-ignore
var peg$f8 = function(fixBindings, continuation) {// @ts-ignore
return { fixBindings, continuation }; };// @ts-ignore
return { fix: { fixBindings, continuation } }; };// @ts-ignore
var peg$f9 = function(continuations, lastContinuation) {
// @ts-ignore
return lastContinuation || continuations.length
// @ts-ignore
? [...continuations.map(x => x.continuation), lastContinuation]
? [...continuations.map(x => x[0]), lastContinuation]
: [];
};// @ts-ignore
var peg$f10 = function(opr, operands, resultBindings, continuations) {// @ts-ignore
return { opr, operands, resultBindings, continuations }; };// @ts-ignore
var peg$f10 = function(opr, operands, resultBindings, continuations) {
// @ts-ignore
return {
// @ts-ignore
primitiveOperation: { opr, operands, resultBindings, continuations },
};
};// @ts-ignore
var peg$f11 = function(variable, offset) {// @ts-ignore
return { variable, offset }; };// @ts-ignore
@ -467,19 +472,22 @@ function peg$parse(input, options) {
// @ts-ignore
return records.length || lastRecord
// @ts-ignore
? [...records.map(x => x.record), lastRecord]
? [...records.map(x => x[0]), lastRecord]
: [];
};// @ts-ignore
var peg$f13 = function(records, address, body) {
// @ts-ignore
return {
// @ts-ignore
record: {
// @ts-ignore
records,
// @ts-ignore
address,
// @ts-ignore
body,
},
};
};// @ts-ignore
@ -874,7 +882,7 @@ peg$parseContinuationExpression() {
function // @ts-ignore
peg$parseSelectExpression() {
// @ts-ignore
var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17;
var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19;
// @ts-ignore
s0 = peg$currPos;
@ -956,7 +964,7 @@ peg$parseSelectExpression() {
s14 = null;
}
// @ts-ignore
s15 = peg$parseContinuationExpression();
s15 = peg$parseCOMMA();
// @ts-ignore
if (s15 !== peg$FAILED) {
// @ts-ignore
@ -967,13 +975,31 @@ peg$parseSelectExpression() {
s16 = null;
}
// @ts-ignore
s17 = peg$parseRPAREN();
s17 = peg$parseContinuationExpression();
// @ts-ignore
if (s17 !== peg$FAILED) {
// @ts-ignore
s18 = peg$parse_();
// @ts-ignore
if (s18 === peg$FAILED) {
// @ts-ignore
s18 = null;
}
// @ts-ignore
s19 = peg$parseRPAREN();
// @ts-ignore
if (s19 !== peg$FAILED) {
// @ts-ignore
peg$savedPos = s0;
// @ts-ignore
s0 = peg$f1(s5, s9, s13, s15);
s0 = peg$f1(s5, s9, s13, s17);
// @ts-ignore
} else {
// @ts-ignore
peg$currPos = s0;
// @ts-ignore
s0 = peg$FAILED;
}
// @ts-ignore
} else {
// @ts-ignore
@ -1917,7 +1943,10 @@ peg$parseFixBindingList() {
// @ts-ignore
s2 = peg$parse_();
// @ts-ignore
if (s2 !== peg$FAILED) {
if (s2 === peg$FAILED) {
// @ts-ignore
s2 = null;
}
// @ts-ignore
s3 = [];
// @ts-ignore
@ -2052,13 +2081,6 @@ peg$parseFixBindingList() {
// @ts-ignore
s0 = peg$FAILED;
}
// @ts-ignore
} else {
// @ts-ignore
peg$currPos = s0;
// @ts-ignore
s0 = peg$FAILED;
}
// @ts-ignore
return s0;
@ -5112,24 +5134,29 @@ export type ContinuationExpression =
| SwitchExpression
| PrimitiveOperationExpression;
export type SelectExpression = {
select: Integer;
select: {
record: Integer;
val: Value;
bind: Identifier;
continuation: ContinuationExpression;
};
};
export type OffsetExpression = {
offset: Integer;
offset: {
index: Integer;
val: Value;
bind: Identifier;
continuation: ContinuationExpression;
};
};
export type IdentifierList = any[];
export type ValueList = any[];
export type SwitchExpression = {
switchIndex: Value;
continuations: ContinuationList;
switch: { switchIndex: Value; continuations: ContinuationList };
};
export type ApplicationExpression = {
application: { fn: Value; args: ValueList };
};
export type ApplicationExpression = { fn: Value; args: ValueList };
export type FixBinding = [
LPAREN,
_ | null,
@ -5147,15 +5174,16 @@ export type FixBinding = [
];
export type FixBindingList = any[];
export type FixExpression = {
fixBindings: FixBindingList;
continuation: ContinuationExpression;
fix: { fixBindings: FixBindingList; continuation: ContinuationExpression };
};
export type ContinuationList = any[];
export type PrimitiveOperationExpression = {
primitiveOperation: {
opr: PrimitiveOperation;
operands: ValueList;
resultBindings: IdentifierList;
continuations: ContinuationList;
};
};
export type RecordExpressionTuple = {
variable: VarStatement;
@ -5163,9 +5191,11 @@ export type RecordExpressionTuple = {
};
export type RecordExpressionTupleList = any[];
export type RecordExpression = {
record: {
records: RecordExpressionTupleList;
address: Literal;
body: ContinuationExpression;
};
};
export type Value =
| VarStatement

8
test/logger.ts Normal file
View File

@ -0,0 +1,8 @@
import { ConsoleTracingLogger } from '@/utils';
export const testingLogger = new ConsoleTracingLogger('test', [
'info',
'warn',
'error',
'debug',
]);

7
test/parser.spec.ts Normal file
View File

@ -0,0 +1,7 @@
import { expect, test } from 'bun:test';
import { TestPrograms } from './programs';
import { peggyParse } from '@/parser';
test('Primitive Operations', async () => {
const ast = peggyParse(await TestPrograms.AddOneThree);
});

View File

@ -0,0 +1,2 @@
PRIMOP(+, [INT 1, INT 2], [u],
[APP(LABEL identity, [VAR u])])

7
test/programs/index.ts Normal file
View File

@ -0,0 +1,7 @@
import { join } from 'path';
export namespace TestPrograms {
export const AddOneThree = Bun.file(
join(import.meta.dir + '/add-1-3.cps'),
).text();
}