Skip to content

Commit

Permalink
refactor: replace Parsimmon with bread-n-butter
Browse files Browse the repository at this point in the history
  • Loading branch information
golopot committed Apr 16, 2022
1 parent 546d7fe commit 2caf709
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 113 deletions.
184 changes: 84 additions & 100 deletions lib/parser.js
Original file line number Diff line number Diff line change
@@ -1,119 +1,103 @@
const Parsimmon = require('parsimmon');
const bnb = require('bread-n-butter');

function makeNode(type) {
return function makeNodeWrapper(parser) {
return Parsimmon.seqMap(
Parsimmon.index,
parser,
Parsimmon.index,
function makeNode_(start, value, end) {
return bnb
.all(bnb.location, parser, bnb.location)
.map(function makeNode_([start, value, end]) {
return {
type,
start: start.offset,
end: end.offset,
start: start.index,
end: end.index,
// @ts-ignore
...value,
};
}
);
});
};
}

const Lang = Parsimmon.createLanguage({
Program: (r) =>
Parsimmon.alt(
r.Superscript,
r.Subscript,
r.UnaryMacro,
r.NullaryMacro,
r.Illegal,
r.PlainText
)
.many()
.map((nodes) => {
return {
body: nodes,
};
})
.thru(makeNode('Program')),
const Spaces = bnb.match(/\s*/);

Superscript: () =>
Parsimmon.seq(
Parsimmon.regexp(/\^\s*/),
Parsimmon.alt(
Parsimmon.regexp(/{[a-zA-Z0-9+-]+}/),
Parsimmon.regexp(/[a-zA-Z0-9+-]/)
)
)
.map(([, b]) => ({
content: b,
}))
.thru(makeNode('Superscript')),
const Superscript = bnb
.all(
bnb.match(/\^\s*/),
bnb.choice(bnb.match(/{[a-zA-Z0-9+-]+}/), bnb.match(/[a-zA-Z0-9+-]/))
)
.map(([, b]) => ({
content: b,
}))
.thru(makeNode('Superscript'));

Subscript: () =>
Parsimmon.seq(
Parsimmon.regexp(/_\s*/),
Parsimmon.alt(
Parsimmon.regexp(/{[a-zA-Z0-9+-]+}/),
Parsimmon.regexp(/[a-zA-Z0-9+-]/)
)
)
.map(([_, b]) => {
return {
content: b,
};
})
.thru(makeNode('Subscript')),
const Subscript = bnb
.all(
bnb.match(/_\s*/),
bnb.choice(bnb.match(/{[a-zA-Z0-9+-]+}/), bnb.match(/[a-zA-Z0-9+-]/))
)
.map(([_, b]) => {
return {
content: b,
};
})
.thru(makeNode('Subscript'));

UnaryMacro: (r) =>
Parsimmon.seq(
Parsimmon.alt(
Parsimmon.regexp(/\\mathbb(?![a-zA-Z])/),
Parsimmon.regexp(/\\mathfrak(?![a-zA-Z])/),
Parsimmon.regexp(/\\mathcal(?![a-zA-Z])/),
Parsimmon.regexp(/\\not(?![a-zA-Z])/)
),
r._,
Parsimmon.alt(
r.CurlyGroup,
r.NullaryMacro,
Parsimmon.regexp(/[a-zA-Z0-9]/)
.map((x) => ({value: x}))
.thru(makeNode('PlainText'))
)
)
.map(([a, _, c]) => ({
macro: a,
argument: c,
}))
.thru(makeNode('UnaryMacro')),
const NullaryMacro = bnb
.choice(bnb.match(/\\[a-zA-Z]+/), bnb.match(/\\\|/))
.map((x) => {
return {
macro: x,
};
})
.thru(makeNode('NullaryMacro'));

NullaryMacro: () =>
Parsimmon.alt(Parsimmon.regexp(/\\[a-zA-Z]+/), Parsimmon.regexp(/\\\|/))
.map((x) => {
return {
macro: x,
};
})
.thru(makeNode('NullaryMacro')),
const CurlyGroup = bnb
.match(/\{.*?\}/)
.map((x) => ({value: x}))
.thru(makeNode('CurlyGroup'));

Illegal: () =>
Parsimmon.regexp(/[\^_\\]/)
.map((r) => ({
value: r,
}))
.thru(makeNode('PlainText')),
const UnaryMacro = bnb
.all(
bnb.choice(
bnb.match(/\\mathbb(?![a-zA-Z])/),
bnb.match(/\\mathfrak(?![a-zA-Z])/),
bnb.match(/\\mathcal(?![a-zA-Z])/),
bnb.match(/\\not(?![a-zA-Z])/)
),
Spaces,
bnb.choice(
CurlyGroup,
NullaryMacro,
bnb
.match(/[a-zA-Z0-9]/)
.map((x) => ({value: x}))
.thru(makeNode('PlainText'))
)
)
.map(([a, _, c]) => ({
macro: a,
argument: c,
}))
.thru(makeNode('UnaryMacro'));

PlainText: () =>
Parsimmon.regexp(/[^_^\\]+/)
.map((x) => ({value: x}))
.thru(makeNode('PlainText')),
const Illegal = bnb
.match(/[\^_\\]/)
.map((r) => ({
value: r,
}))
.thru(makeNode('PlainText'));

CurlyGroup: () =>
Parsimmon.regexp(/\{.*?\}/)
.map((x) => ({value: x}))
.thru(makeNode('CurlyGroup')),
const PlainText = bnb
.match(/[^_^\\]+/)
.map((x) => ({value: x}))
.thru(makeNode('PlainText'));

_: () => Parsimmon.regexp(/\s*/),
});
const Program = bnb
.choice(Superscript, Subscript, UnaryMacro, NullaryMacro, Illegal, PlainText)
.repeat()
.map((nodes) => {
return {
body: nodes,
};
})
.thru(makeNode('Program'));

module.exports = Lang.Program;
module.exports = Program;
22 changes: 11 additions & 11 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"ci": "npm run prettier && npm run lint && npm run tsc && npm run test"
},
"dependencies": {
"parsimmon": "^1.12.0"
"bread-n-butter": "^0.6.0"
},
"devDependencies": {
"@types/chrome": "^0.0.176",
Expand Down
2 changes: 1 addition & 1 deletion test/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ describe('convertText', () => {

describe('Parser', () => {
test('Should successfully parse \\\\^^__', () => {
expect(parser.parse('\\\\^^__').status).toEqual(true);
expect(parser.parse('\\\\^^__').type).toEqual('ParseOK');
});
});

Expand Down

0 comments on commit 2caf709

Please sign in to comment.