Skip to content

Commit ca4041d

Browse files
committed
Transform expr? %action into (expr %action)?
1 parent 39d9c20 commit ca4041d

4 files changed

Lines changed: 132 additions & 85 deletions

File tree

src/ast/action.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
'use strict';
22

3-
var util = require('../util');
3+
var util = require('../util');
4+
var Maybe = require('./maybe');
45

56
var Action = function(expression, actionName) {
7+
if (expression instanceof Maybe)
8+
return new Maybe(new Action(expression._expression, actionName));
9+
610
this._expression = expression;
711
this._actionName = actionName;
812
};

src/meta_grammar.js

Lines changed: 88 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,88 +1170,95 @@
11701170
address0 = this._read_repeated_atom();
11711171
if (address0 === FAILURE) {
11721172
this._offset = index1;
1173-
address0 = this._read_terminal();
1173+
address0 = this._read_maybe_atom();
11741174
if (address0 === FAILURE) {
11751175
this._offset = index1;
1176-
var index2 = this._offset, elements0 = new Array(5);
1177-
var address1 = FAILURE;
1178-
var chunk0 = null, max0 = this._offset + 1;
1179-
if (max0 <= this._inputSize) {
1180-
chunk0 = this._input.substring(this._offset, max0);
1181-
}
1182-
if (chunk0 === '(') {
1183-
address1 = new TreeNode(this._input.substring(this._offset, this._offset + 1), this._offset, []);
1184-
this._offset = this._offset + 1;
1185-
} else {
1186-
address1 = FAILURE;
1187-
if (this._offset > this._failure) {
1188-
this._failure = this._offset;
1189-
this._expected = [];
1190-
}
1191-
if (this._offset === this._failure) {
1192-
this._expected.push('"("');
1193-
}
1194-
}
1195-
if (address1 !== FAILURE) {
1196-
elements0[0] = address1;
1197-
var address2 = FAILURE;
1198-
var remaining0 = 0, index3 = this._offset, elements1 = [], address3 = true;
1199-
while (address3 !== FAILURE) {
1200-
address3 = this._read__();
1201-
if (address3 !== FAILURE) {
1202-
elements1.push(address3);
1203-
--remaining0;
1204-
}
1176+
address0 = this._read_terminal();
1177+
if (address0 === FAILURE) {
1178+
this._offset = index1;
1179+
var index2 = this._offset, elements0 = new Array(5);
1180+
var address1 = FAILURE;
1181+
var chunk0 = null, max0 = this._offset + 1;
1182+
if (max0 <= this._inputSize) {
1183+
chunk0 = this._input.substring(this._offset, max0);
12051184
}
1206-
if (remaining0 <= 0) {
1207-
address2 = new TreeNode(this._input.substring(index3, this._offset), index3, elements1);
1208-
this._offset = this._offset;
1185+
if (chunk0 === '(') {
1186+
address1 = new TreeNode(this._input.substring(this._offset, this._offset + 1), this._offset, []);
1187+
this._offset = this._offset + 1;
12091188
} else {
1210-
address2 = FAILURE;
1189+
address1 = FAILURE;
1190+
if (this._offset > this._failure) {
1191+
this._failure = this._offset;
1192+
this._expected = [];
1193+
}
1194+
if (this._offset === this._failure) {
1195+
this._expected.push('"("');
1196+
}
12111197
}
1212-
if (address2 !== FAILURE) {
1213-
elements0[1] = address2;
1214-
var address4 = FAILURE;
1215-
address4 = this._read_actionable();
1216-
if (address4 !== FAILURE) {
1217-
elements0[2] = address4;
1218-
var address5 = FAILURE;
1219-
var remaining1 = 0, index4 = this._offset, elements2 = [], address6 = true;
1220-
while (address6 !== FAILURE) {
1221-
address6 = this._read__();
1222-
if (address6 !== FAILURE) {
1223-
elements2.push(address6);
1224-
--remaining1;
1225-
}
1226-
}
1227-
if (remaining1 <= 0) {
1228-
address5 = new TreeNode(this._input.substring(index4, this._offset), index4, elements2);
1229-
this._offset = this._offset;
1230-
} else {
1231-
address5 = FAILURE;
1198+
if (address1 !== FAILURE) {
1199+
elements0[0] = address1;
1200+
var address2 = FAILURE;
1201+
var remaining0 = 0, index3 = this._offset, elements1 = [], address3 = true;
1202+
while (address3 !== FAILURE) {
1203+
address3 = this._read__();
1204+
if (address3 !== FAILURE) {
1205+
elements1.push(address3);
1206+
--remaining0;
12321207
}
1233-
if (address5 !== FAILURE) {
1234-
elements0[3] = address5;
1235-
var address7 = FAILURE;
1236-
var chunk1 = null, max1 = this._offset + 1;
1237-
if (max1 <= this._inputSize) {
1238-
chunk1 = this._input.substring(this._offset, max1);
1208+
}
1209+
if (remaining0 <= 0) {
1210+
address2 = new TreeNode(this._input.substring(index3, this._offset), index3, elements1);
1211+
this._offset = this._offset;
1212+
} else {
1213+
address2 = FAILURE;
1214+
}
1215+
if (address2 !== FAILURE) {
1216+
elements0[1] = address2;
1217+
var address4 = FAILURE;
1218+
address4 = this._read_actionable();
1219+
if (address4 !== FAILURE) {
1220+
elements0[2] = address4;
1221+
var address5 = FAILURE;
1222+
var remaining1 = 0, index4 = this._offset, elements2 = [], address6 = true;
1223+
while (address6 !== FAILURE) {
1224+
address6 = this._read__();
1225+
if (address6 !== FAILURE) {
1226+
elements2.push(address6);
1227+
--remaining1;
1228+
}
12391229
}
1240-
if (chunk1 === ')') {
1241-
address7 = new TreeNode(this._input.substring(this._offset, this._offset + 1), this._offset, []);
1242-
this._offset = this._offset + 1;
1230+
if (remaining1 <= 0) {
1231+
address5 = new TreeNode(this._input.substring(index4, this._offset), index4, elements2);
1232+
this._offset = this._offset;
12431233
} else {
1244-
address7 = FAILURE;
1245-
if (this._offset > this._failure) {
1246-
this._failure = this._offset;
1247-
this._expected = [];
1234+
address5 = FAILURE;
1235+
}
1236+
if (address5 !== FAILURE) {
1237+
elements0[3] = address5;
1238+
var address7 = FAILURE;
1239+
var chunk1 = null, max1 = this._offset + 1;
1240+
if (max1 <= this._inputSize) {
1241+
chunk1 = this._input.substring(this._offset, max1);
12481242
}
1249-
if (this._offset === this._failure) {
1250-
this._expected.push('")"');
1243+
if (chunk1 === ')') {
1244+
address7 = new TreeNode(this._input.substring(this._offset, this._offset + 1), this._offset, []);
1245+
this._offset = this._offset + 1;
1246+
} else {
1247+
address7 = FAILURE;
1248+
if (this._offset > this._failure) {
1249+
this._failure = this._offset;
1250+
this._expected = [];
1251+
}
1252+
if (this._offset === this._failure) {
1253+
this._expected.push('")"');
1254+
}
1255+
}
1256+
if (address7 !== FAILURE) {
1257+
elements0[4] = address7;
1258+
} else {
1259+
elements0 = null;
1260+
this._offset = index2;
12511261
}
1252-
}
1253-
if (address7 !== FAILURE) {
1254-
elements0[4] = address7;
12551262
} else {
12561263
elements0 = null;
12571264
this._offset = index2;
@@ -1268,18 +1275,15 @@
12681275
elements0 = null;
12691276
this._offset = index2;
12701277
}
1271-
} else {
1272-
elements0 = null;
1273-
this._offset = index2;
1274-
}
1275-
if (elements0 === null) {
1276-
address0 = FAILURE;
1277-
} else {
1278-
address0 = this._actions.paren_expr(this._input, index2, this._offset, elements0);
1279-
this._offset = this._offset;
1280-
}
1281-
if (address0 === FAILURE) {
1282-
this._offset = index1;
1278+
if (elements0 === null) {
1279+
address0 = FAILURE;
1280+
} else {
1281+
address0 = this._actions.paren_expr(this._input, index2, this._offset, elements0);
1282+
this._offset = this._offset;
1283+
}
1284+
if (address0 === FAILURE) {
1285+
this._offset = index1;
1286+
}
12831287
}
12841288
}
12851289
}

src/meta_grammar.peg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ action_expression <- actionable _+ action_tag %action
5555

5656
actionable <- sequence
5757
/ repeated_atom
58+
/ maybe_atom
5859
/ terminal
5960
/ "(" _* actionable _* ")" %paren_expr
6061

test/canopy/meta_grammar_spec.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,25 @@ jstest.describe("MetaGrammar", function() { with(this) {
330330
}})
331331
}})
332332

333+
describe('on repetitions', function() { with(this) {
334+
before(function() { with(this) {
335+
this.compiler = new Compiler(' \
336+
grammar ActionRepetition \
337+
string <- "foo"+ %make_rep \
338+
')
339+
}})
340+
341+
it('wraps the repetition with an action', function() { with(this) {
342+
assertEqual(['grammar', 'ActionRepetition',
343+
['rule', 'string',
344+
['action', 'make_rep',
345+
['repeat', 1,
346+
['string', 'foo']]]]],
347+
348+
compiler.toSexp() )
349+
}})
350+
}})
351+
333352
describe('on sequences', function() { with(this) {
334353
before(function() { with(this) {
335354
this.compiler = new Compiler(' \
@@ -349,6 +368,25 @@ jstest.describe("MetaGrammar", function() { with(this) {
349368
compiler.toSexp() )
350369
}})
351370
}})
371+
372+
describe('on maybe nodes', function() { with(this) {
373+
before(function() { with(this) {
374+
this.compiler = new Compiler(' \
375+
grammar ActionMaybe \
376+
string <- "foo"? %make_maybe \
377+
')
378+
}})
379+
380+
it('transforms the action inside the maybe', function() { with(this) {
381+
assertEqual(['grammar', 'ActionMaybe',
382+
['rule', 'string',
383+
['maybe',
384+
['action', 'make_maybe',
385+
['string', 'foo']]]]],
386+
387+
compiler.toSexp() )
388+
}})
389+
}})
352390
}})
353391

354392
describe('type annotation', function() { with(this) {

0 commit comments

Comments
 (0)