Browse Source

Switch from first/rest to head/tail in the PEG.js grammar

In the past year I worked on various grammars where first/rest or
head/tail were used as labels for parts of lists. I found I associate
head/tail with a list immediately, while in case of first/rest I have to
"parse" grammar rules for a while before understanding their structure.

Moreover, I tend to assume that rest is a list of the same thigs as
first, but I don't have such assumption in case of head/tail. This
assumption was in conflict with the grammar structure.

I'm not sure how much these observations are applicable to others, but I
decided to act on them and switch from first/rest to head/tail.
redux
David Majda 6 years ago
parent
commit
a4a66a2e5b
  1. 22
      lib/parser.js
  2. 22
      src/parser.pegjs

22
lib/parser.js

@ -65,14 +65,14 @@ module.exports = (function() {
},
peg$c5 = "/",
peg$c6 = { type: "literal", value: "/", description: "\"/\"" },
peg$c7 = function(first, rest) {
return rest.length > 0
peg$c7 = function(head, tail) {
return tail.length > 0
? {
type: "choice",
alternatives: buildList(first, rest, 3),
alternatives: buildList(head, tail, 3),
location: location()
}
: first;
: head;
},
peg$c8 = function(expression, code) {
return code !== null
@ -84,14 +84,14 @@ module.exports = (function() {
}
: expression;
},
peg$c9 = function(first, rest) {
return rest.length > 0
peg$c9 = function(head, tail) {
return tail.length > 0
? {
type: "sequence",
elements: buildList(first, rest, 1),
elements: buildList(head, tail, 1),
location: location()
}
: first;
: head;
},
peg$c10 = ":",
peg$c11 = { type: "literal", value: ":", description: "\":\"" },
@ -180,7 +180,7 @@ module.exports = (function() {
peg$c67 = { type: "literal", value: "//", description: "\"//\"" },
peg$c68 = function(name) { return name; },
peg$c69 = { type: "other", description: "identifier" },
peg$c70 = function(first, rest) { return first + rest.join(""); },
peg$c70 = function(head, tail) { return head + tail.join(""); },
peg$c71 = "_",
peg$c72 = { type: "literal", value: "_", description: "\"_\"" },
peg$c73 = "\\",
@ -4920,8 +4920,8 @@ module.exports = (function() {
return result;
}
function buildList(first, rest, index) {
return [first].concat(extractList(rest, index));
function buildList(head, tail, index) {
return [head].concat(extractList(tail, index));
}

22
src/parser.pegjs

@ -67,8 +67,8 @@
return result;
}
function buildList(first, rest, index) {
return [first].concat(extractList(rest, index));
function buildList(head, tail, index) {
return [head].concat(extractList(tail, index));
}
}
@ -114,14 +114,14 @@ Expression
= ChoiceExpression
ChoiceExpression
= first:ActionExpression rest:(__ "/" __ ActionExpression)* {
return rest.length > 0
= head:ActionExpression tail:(__ "/" __ ActionExpression)* {
return tail.length > 0
? {
type: "choice",
alternatives: buildList(first, rest, 3),
alternatives: buildList(head, tail, 3),
location: location()
}
: first;
: head;
}
ActionExpression
@ -137,14 +137,14 @@ ActionExpression
}
SequenceExpression
= first:LabeledExpression rest:(__ LabeledExpression)* {
return rest.length > 0
= head:LabeledExpression tail:(__ LabeledExpression)* {
return tail.length > 0
? {
type: "sequence",
elements: buildList(first, rest, 1),
elements: buildList(head, tail, 1),
location: location()
}
: first;
: head;
}
LabeledExpression
@ -255,7 +255,7 @@ Identifier
= !ReservedWord name:IdentifierName { return name; }
IdentifierName "identifier"
= first:IdentifierStart rest:IdentifierPart* { return first + rest.join(""); }
= head:IdentifierStart tail:IdentifierPart* { return head + tail.join(""); }
IdentifierStart
= UnicodeLetter

Loading…
Cancel
Save