Skip to content

Commit

Permalink
feat(parse): add ! discard modifier to grammar
Browse files Browse the repository at this point in the history
  • Loading branch information
postspectacular committed Jun 27, 2020
1 parent 670aed7 commit 456efdc
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 12 deletions.
37 changes: 30 additions & 7 deletions packages/parse/src/grammar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import { oneOf } from "./prims/one-of";
import { range } from "./prims/range";
import { string, stringD } from "./prims/string";
import { collect, xfCollect } from "./xform/collect";
import { xfDiscard } from "./xform/discard";
import { discard, xfDiscard } from "./xform/discard";
import { hoistResult, xfHoist, xfHoistResult } from "./xform/hoist";
import { join, xfJoin } from "./xform/join";
import { xfFloat, xfInt } from "./xform/number";
Expand All @@ -64,6 +64,8 @@ const REPEAT = maybe(
])
);

const DISCARD = maybe(lit("!"), undefined, "discard");

const CHAR_OR_ESC = alt([UNICODE, ESC, always()]);

const CHAR_RANGE = seq([CHAR_OR_ESC, dash, CHAR_OR_ESC], "charRange");
Expand All @@ -84,7 +86,10 @@ const SYM = join(oneOrMore(alt([ALPHA_NUM, oneOf(".-_$")]), "sym"));

const RULE_REF = seq([litD("<"), SYM, litD(">")], "ref");

const TERM = seq([alt([RULE_REF, LIT, STRING, CHAR_SEL]), REPEAT], "term");
const TERM = seq(
[alt([RULE_REF, LIT, STRING, CHAR_SEL]), REPEAT, DISCARD],
"term"
);

const ALT = seq(
[
Expand All @@ -95,6 +100,7 @@ const ALT = seq(
WS0,
litD(")"),
REPEAT,
DISCARD,
],
"alt"
);
Expand Down Expand Up @@ -164,9 +170,13 @@ compile.addAll({
return ref || illegalArgs(`invalid rule ref: ${id}`);
},
term: ($, lang, opts) => {
const [term, repeat] = $!.children!;
const [term, repeat, discard] = $!.children!;
opts.debug && console.log(`term: ${term.id}`);
return compileRepeat(compile(term, lang, opts), repeat, opts);
return compileDiscard(
compileRepeat(compile(term, lang, opts), repeat, opts),
discard,
opts
);
},
alt: ($, lang, opts) => {
opts.debug && console.log(`alt: ${$.id}`);
Expand All @@ -177,9 +187,13 @@ compile.addAll({
acc.push(compile(first(c), lang, opts));
}
}
return compileRepeat(
acc.length > 1 ? alt(acc) : acc[0],
$.children![2],
return compileDiscard(
compileRepeat(
acc.length > 1 ? alt(acc) : acc[0],
$.children![2],
opts
),
$.children![3],
opts
);
},
Expand Down Expand Up @@ -233,6 +247,15 @@ const compileRepeat = (
return parser;
};

const compileDiscard = (
parser: Parser<string>,
dspec: ParseScope<string>,
opts: GrammarOpts
) => {
opts.debug && console.log(`discard:`, dspec.result);
return dspec.result === "!" ? discard(parser) : parser;
};

export const defGrammar = (
rules: string,
env?: RuleTransforms,
Expand Down
21 changes: 16 additions & 5 deletions packages/parse/test/grammar.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as assert from "assert";
import { defContext, defGrammar, Parser, xfCollect, xfJoin } from "../src";
import { defContext, defGrammar, Parser } from "../src";

const check = (
parser: Parser<string>,
Expand All @@ -13,13 +13,24 @@ const check = (
return ctx;
};

describe("parse", () => {
it("grammar", () => {
describe("grammar", () => {
it("basics", () => {
const lang = defGrammar(
"_: [ ]+ => discard ; num: [0-9a-f]+ => join ; prog: (<_> | <num>)* => collect ;",
{ discard: () => null, join: xfJoin, collect: xfCollect }
"_: [ ]+ => discard ; num: [0-9a-f]+ => join ; prog: (<_> | <num>)* => collect ;"
);
const ctx = check(lang!.rules.prog, "decafbad 55 aa", true, 14);
assert.deepEqual(ctx.result, ["decafbad", "55", "aa"]);
});

it("discard flag", () => {
const lang = defGrammar(`
title: [^\\u005d]* => join ;
url: [^\\u0029]* => join ;
end: ')' ;
link: '['! <title> "]("! <url> <end>! => collect ;
`);
const ctx = defContext("[abc](def)");
assert(lang!.rules.link(ctx));
assert.deepEqual(ctx.result, ["abc", "def"]);
});
});

0 comments on commit 456efdc

Please sign in to comment.