Browse Source

Avoid aligning object keys

The only exception left are objects representing a mapping with simple
keys and values -- essentially tables written as object literals.

See #443.
redux
David Majda 5 years ago
parent
commit
400a3cfa3c
  1. 6
      README.md
  2. 8
      benchmark/benchmarks.js
  3. 8
      benchmark/index.js
  4. 2
      benchmark/run
  5. 14
      bin/pegjs
  6. 62
      examples/css.pegjs
  7. 198
      examples/javascript.pegjs
  8. 18
      lib/compiler/asts.js
  9. 28
      lib/compiler/index.js
  10. 52
      lib/compiler/passes/generate-bytecode.js
  11. 26
      lib/compiler/passes/generate-js.js
  12. 12
      lib/compiler/passes/report-duplicate-labels.js
  13. 34
      lib/compiler/visitor.js
  14. 72
      lib/parser.js
  15. 4
      lib/peg.js
  16. 40
      spec/api/generated-parser-api.spec.js
  17. 4
      spec/api/pegjs-api.spec.js
  18. 8
      spec/api/plugin-api.spec.js
  19. 124
      spec/behavior/generated-parser-behavior.spec.js
  20. 6
      spec/unit/compiler/passes/remove-proxy-rules.spec.js
  21. 8
      spec/unit/compiler/passes/report-duplicate-labels.spec.js
  22. 6
      spec/unit/compiler/passes/report-duplicate-rules.spec.js
  23. 12
      spec/unit/compiler/passes/report-infinite-recursion.spec.js
  24. 12
      spec/unit/compiler/passes/report-infinite-repetition.spec.js
  25. 6
      spec/unit/compiler/passes/report-undefined-rules.spec.js
  26. 62
      spec/unit/parser.spec.js
  27. 64
      src/parser.pegjs

6
README.md

@ -371,7 +371,7 @@ The code inside the predicate can also access location information using the
```javascript
{
start: { offset: 23, line: 5, column: 6 },
end: { offset: 23, line: 5, column: 6 }
end: { offset: 23, line: 5, column: 6 }
}
```
@ -402,7 +402,7 @@ The code inside the predicate can also access location information using the
```javascript
{
start: { offset: 23, line: 5, column: 6 },
end: { offset: 23, line: 5, column: 6 }
end: { offset: 23, line: 5, column: 6 }
}
```
@ -469,7 +469,7 @@ The code inside the action can also access location information using the
```javascript
{
start: { offset: 23, line: 5, column: 6 },
end: { offset: 25, line: 5, column: 8 }
end: { offset: 25, line: 5, column: 8 }
}
```

8
benchmark/benchmarks.js

@ -2,8 +2,8 @@
let benchmarks = [
{
id: "json",
title: "JSON",
id: "json",
title: "JSON",
tests: [
{ file: "example1.json", title: "Example 1" },
{ file: "example2.json", title: "Example 2" },
@ -13,8 +13,8 @@ let benchmarks = [
]
},
{
id: "css",
title: "CSS",
id: "css",
title: "CSS",
tests: [
{ file: "blueprint/src/reset.css", title: "Blueprint - reset.css (source)" },
{ file: "blueprint/src/typography.css", title: "Blueprint - typography.css (source)" },

8
benchmark/index.js

@ -62,7 +62,7 @@ $("#run").click(() => {
let runCount = parseInt($("#run-count").val(), 10);
let options = {
cache: $("#cache").is(":checked"),
cache: $("#cache").is(":checked"),
optimize: $("#optimize").val()
};
@ -74,10 +74,10 @@ $("#run").click(() => {
Runner.run(benchmarks, runCount, options, {
readFile: function(file) {
return $.ajax({
type: "GET",
url: file,
type: "GET",
url: file,
dataType: "text",
async: false
async: false
}).responseText;
},

2
benchmark/run

@ -113,7 +113,7 @@ function nextArg() {
let runCount = 10;
let options = {
cache: false,
cache: false,
optimize: "speed"
};

14
bin/pegjs

@ -106,14 +106,14 @@ let inputFile = null;
let outputFile = null;
let options = {
cache: false,
cache: false,
dependencies: {},
exportVar: null,
format: "commonjs",
optimize: "speed",
output: "source",
plugins: [],
trace: false
exportVar: null,
format: "commonjs",
optimize: "speed",
output: "source",
plugins: [],
trace: false
};
while (args.length > 0 && isOption(args[0])) {

62
examples/css.pegjs

@ -35,10 +35,10 @@
function buildExpression(head, tail) {
return tail.reduce(function(result, element) {
return {
type: "Expression",
type: "Expression",
operator: element[0],
left: result,
right: element[1]
left: result,
right: element[1]
};
}, head);
}
@ -55,18 +55,18 @@ stylesheet
rules:((ruleset / media / page) (CDO S* / CDC S*)*)*
{
return {
type: "StyleSheet",
type: "StyleSheet",
charset: extractOptional(charset, 1),
imports: extractList(imports, 0),
rules: extractList(rules, 0)
rules: extractList(rules, 0)
};
}
import
= IMPORT_SYM S* href:(STRING / URI) S* media:media_list? ";" S* {
return {
type: "ImportRule",
href: href,
type: "ImportRule",
href: href,
media: media !== null ? media : []
};
}
@ -94,8 +94,8 @@ page
"}" S*
{
return {
type: "PageRule",
selector: selector,
type: "PageRule",
selector: selector,
declarations: buildList(declarationsHead, declarationsTail, 2)
};
}
@ -123,8 +123,8 @@ ruleset
"}" S*
{
return {
type: "RuleSet",
selectors: buildList(selectorsHead, selectorsTail, 2),
type: "RuleSet",
selectors: buildList(selectorsHead, selectorsTail, 2),
declarations: buildList(declarationsHead, declarationsTail, 2)
};
}
@ -132,18 +132,18 @@ ruleset
selector
= left:simple_selector S* combinator:combinator right:selector {
return {
type: "Selector",
type: "Selector",
combinator: combinator,
left: left,
right: right
left: left,
right: right
};
}
/ left:simple_selector S+ right:selector {
return {
type: "Selector",
type: "Selector",
combinator: " ",
left: left,
right: right
left: left,
right: right
};
}
/ selector:simple_selector S* { return selector; }
@ -151,15 +151,15 @@ selector
simple_selector
= element:element_name qualifiers:(id / class / attrib / pseudo)* {
return {
type: "SimpleSelector",
element: element,
type: "SimpleSelector",
element: element,
qualifiers: qualifiers
};
}
/ qualifiers:(id / class / attrib / pseudo)+ {
return {
type: "SimpleSelector",
element: "*",
type: "SimpleSelector",
element: "*",
qualifiers: qualifiers
};
}
@ -181,10 +181,10 @@ attrib
"]"
{
return {
type: "AttributeSelector",
type: "AttributeSelector",
attribute: attribute,
operator: extractOptional(operatorAndValue, 0),
value: extractOptional(operatorAndValue, 2)
operator: extractOptional(operatorAndValue, 0),
value: extractOptional(operatorAndValue, 2)
};
}
@ -193,8 +193,8 @@ pseudo
value:(
name:FUNCTION S* params:(IDENT S*)? ")" {
return {
type: "Function",
name: name,
type: "Function",
name: name,
params: params !== null ? [params[0]] : []
};
}
@ -205,9 +205,9 @@ pseudo
declaration
= name:property ':' S* value:expr prio:prio? {
return {
type: "Declaration",
name: name,
value: value,
type: "Declaration",
name: name,
value: value,
important: prio !== null
};
}
@ -223,9 +223,9 @@ term
S*
{
return {
type: "Quantity",
type: "Quantity",
value: quantity.value,
unit: quantity.unit
unit: quantity.unit
};
}
/ value:STRING S* { return { type: "String", value: value }; }

198
examples/javascript.pegjs

@ -56,10 +56,10 @@
function buildBinaryExpression(head, tail) {
return tail.reduce(function(result, element) {
return {
type: "BinaryExpression",
type: "BinaryExpression",
operator: element[1],
left: result,
right: element[3]
left: result,
right: element[3]
};
}, head);
}
@ -67,10 +67,10 @@
function buildLogicalExpression(head, tail) {
return tail.reduce(function(result, element) {
return {
type: "LogicalExpression",
type: "LogicalExpression",
operator: element[1],
left: result,
right: element[3]
left: result,
right: element[3]
};
}, head);
}
@ -504,19 +504,19 @@ PrimaryExpression
ArrayLiteral
= "[" __ elision:(Elision __)? "]" {
return {
type: "ArrayExpression",
type: "ArrayExpression",
elements: optionalList(extractOptional(elision, 0))
};
}
/ "[" __ elements:ElementList __ "]" {
return {
type: "ArrayExpression",
type: "ArrayExpression",
elements: elements
};
}
/ "[" __ elements:ElementList __ "," __ elision:(Elision __)? "]" {
return {
type: "ArrayExpression",
type: "ArrayExpression",
elements: elements.concat(optionalList(extractOptional(elision, 0)))
};
}
@ -559,15 +559,15 @@ PropertyAssignment
"{" __ body:FunctionBody __ "}"
{
return {
type: "Property",
key: key,
type: "Property",
key: key,
value: {
type: "FunctionExpression",
id: null,
type: "FunctionExpression",
id: null,
params: [],
body: body
body: body
},
kind: "get"
kind: "get"
};
}
/ SetToken __ key:PropertyName __
@ -575,15 +575,15 @@ PropertyAssignment
"{" __ body:FunctionBody __ "}"
{
return {
type: "Property",
key: key,
type: "Property",
key: key,
value: {
type: "FunctionExpression",
id: null,
type: "FunctionExpression",
id: null,
params: params,
body: body
body: body
},
kind: "set"
kind: "set"
};
}
@ -614,8 +614,8 @@ MemberExpression
{
return tail.reduce(function(result, element) {
return {
type: "MemberExpression",
object: result,
type: "MemberExpression",
object: result,
property: element.property,
computed: element.computed
};
@ -640,14 +640,14 @@ CallExpression
}
/ __ "[" __ property:Expression __ "]" {
return {
type: "MemberExpression",
type: "MemberExpression",
property: property,
computed: true
};
}
/ __ "." __ property:IdentifierName {
return {
type: "MemberExpression",
type: "MemberExpression",
property: property,
computed: false
};
@ -678,10 +678,10 @@ LeftHandSideExpression
PostfixExpression
= argument:LeftHandSideExpression _ operator:PostfixOperator {
return {
type: "UpdateExpression",
type: "UpdateExpression",
operator: operator,
argument: argument,
prefix: false
prefix: false
};
}
/ LeftHandSideExpression
@ -698,10 +698,10 @@ UnaryExpression
: "UnaryExpression";
return {
type: type,
type: type,
operator: operator,
argument: argument,
prefix: true
prefix: true
};
}
@ -857,10 +857,10 @@ ConditionalExpression
":" __ alternate:AssignmentExpression
{
return {
type: "ConditionalExpression",
test: test,
type: "ConditionalExpression",
test: test,
consequent: consequent,
alternate: alternate
alternate: alternate
};
}
/ LogicalORExpression
@ -871,10 +871,10 @@ ConditionalExpressionNoIn
":" __ alternate:AssignmentExpressionNoIn
{
return {
type: "ConditionalExpression",
test: test,
type: "ConditionalExpression",
test: test,
consequent: consequent,
alternate: alternate
alternate: alternate
};
}
/ LogicalORExpressionNoIn
@ -885,10 +885,10 @@ AssignmentExpression
right:AssignmentExpression
{
return {
type: "AssignmentExpression",
type: "AssignmentExpression",
operator: "=",
left: left,
right: right
left: left,
right: right
};
}
/ left:LeftHandSideExpression __
@ -896,10 +896,10 @@ AssignmentExpression
right:AssignmentExpression
{
return {
type: "AssignmentExpression",
type: "AssignmentExpression",
operator: operator,
left: left,
right: right
left: left,
right: right
};
}
/ ConditionalExpression
@ -910,10 +910,10 @@ AssignmentExpressionNoIn
right:AssignmentExpressionNoIn
{
return {
type: "AssignmentExpression",
type: "AssignmentExpression",
operator: "=",
left: left,
right: right
left: left,
right: right
};
}
/ left:LeftHandSideExpression __
@ -921,10 +921,10 @@ AssignmentExpressionNoIn
right:AssignmentExpressionNoIn
{
return {
type: "AssignmentExpression",
type: "AssignmentExpression",
operator: operator,
left: left,
right: right
left: left,
right: right
};
}
/ ConditionalExpressionNoIn
@ -989,9 +989,9 @@ StatementList
VariableStatement
= VarToken __ declarations:VariableDeclarationList EOS {
return {
type: "VariableDeclaration",
type: "VariableDeclaration",
declarations: declarations,
kind: "var"
kind: "var"
};
}
@ -1009,7 +1009,7 @@ VariableDeclaration
= id:Identifier init:(__ Initialiser)? {
return {
type: "VariableDeclarator",
id: id,
id: id,
init: extractOptional(init, 1)
};
}
@ -1018,7 +1018,7 @@ VariableDeclarationNoIn
= id:Identifier init:(__ InitialiserNoIn)? {
return {
type: "VariableDeclarator",
id: id,
id: id,
init: extractOptional(init, 1)
};
}
@ -1035,7 +1035,7 @@ EmptyStatement
ExpressionStatement
= !("{" / FunctionToken) expression:Expression EOS {
return {
type: "ExpressionStatement",
type: "ExpressionStatement",
expression: expression
};
}
@ -1047,19 +1047,19 @@ IfStatement
alternate:Statement
{
return {
type: "IfStatement",
test: test,
type: "IfStatement",
test: test,
consequent: consequent,
alternate: alternate
alternate: alternate
};
}
/ IfToken __ "(" __ test:Expression __ ")" __
consequent:Statement {
return {
type: "IfStatement",
test: test,
type: "IfStatement",
test: test,
consequent: consequent,
alternate: null
alternate: null
};
}
@ -1080,11 +1080,11 @@ IterationStatement
body:Statement
{
return {
type: "ForStatement",
init: extractOptional(init, 0),
test: extractOptional(test, 0),
type: "ForStatement",
init: extractOptional(init, 0),
test: extractOptional(test, 0),
update: extractOptional(update, 0),
body: body
body: body
};
}
/ ForToken __
@ -1096,15 +1096,15 @@ IterationStatement
body:Statement
{
return {
type: "ForStatement",
init: {
type: "VariableDeclaration",
type: "ForStatement",
init: {
type: "VariableDeclaration",
declarations: declarations,
kind: "var"
kind: "var"
},
test: extractOptional(test, 0),
test: extractOptional(test, 0),
update: extractOptional(update, 0),
body: body
body: body
};
}
/ ForToken __
@ -1116,10 +1116,10 @@ IterationStatement
body:Statement
{
return {
type: "ForInStatement",
left: left,
type: "ForInStatement",
left: left,
right: right,
body: body
body: body
};
}
/ ForToken __
@ -1131,14 +1131,14 @@ IterationStatement
body:Statement
{
return {
type: "ForInStatement",
left: {
type: "VariableDeclaration",
type: "ForInStatement",
left: {
type: "VariableDeclaration",
declarations: declarations,
kind: "var"
kind: "var"
},
right: right,
body: body
body: body
};
}
@ -1176,9 +1176,9 @@ SwitchStatement
cases:CaseBlock
{
return {
type: "SwitchStatement",
type: "SwitchStatement",
discriminant: discriminant,
cases: cases
cases: cases
};
}
@ -1202,8 +1202,8 @@ CaseClauses
CaseClause
= CaseToken __ test:Expression __ ":" consequent:(__ StatementList)? {
return {
type: "SwitchCase",
test: test,
type: "SwitchCase",
test: test,
consequent: optionalList(extractOptional(consequent, 1))
};
}
@ -1211,8 +1211,8 @@ CaseClause
DefaultClause
= DefaultToken __ ":" consequent:(__ StatementList)? {
return {
type: "SwitchCase",
test: null,
type: "SwitchCase",
test: null,
consequent: optionalList(extractOptional(consequent, 1))
};
}
@ -1230,25 +1230,25 @@ ThrowStatement
TryStatement
= TryToken __ block:Block __ handler:Catch __ finalizer:Finally {
return {
type: "TryStatement",
block: block,
handler: handler,
type: "TryStatement",
block: block,
handler: handler,
finalizer: finalizer
};
}
/ TryToken __ block:Block __ handler:Catch {
return {
type: "TryStatement",
block: block,
handler: handler,
type: "TryStatement",
block: block,
handler: handler,
finalizer: null
};
}
/ TryToken __ block:Block __ finalizer:Finally {
return {
type: "TryStatement",
block: block,
handler: null,
type: "TryStatement",
block: block,
handler: null,
finalizer: finalizer
};
}
@ -1256,9 +1256,9 @@ TryStatement
Catch
= CatchToken __ "(" __ param:Identifier __ ")" __ body:Block {
return {
type: "CatchClause",
type: "CatchClause",
param: param,
body: body
body: body
};
}
@ -1276,10 +1276,10 @@ FunctionDeclaration
"{" __ body:FunctionBody __ "}"
{
return {
type: "FunctionDeclaration",
id: id,
type: "FunctionDeclaration",
id: id,
params: optionalList(extractOptional(params, 0)),
body: body
body: body
};
}
@ -1289,10 +1289,10 @@ FunctionExpression
"{" __ body:FunctionBody __ "}"
{
return {
type: "FunctionExpression",
id: extractOptional(id, 0),
type: "FunctionExpression",
id: extractOptional(id, 0),
params: optionalList(extractOptional(params, 0)),
body: body
body: body
};
}

18
lib/compiler/asts.js

@ -33,7 +33,7 @@ let asts = {
}
let consumes = visitor.build({
rule: consumesExpression,
rule: consumesExpression,
named: consumesExpression,
choice: function(node) {
@ -46,14 +46,14 @@ let asts = {
return node.elements.some(consumes);
},
labeled: consumesExpression,
text: consumesExpression,
simple_and: consumesFalse,
simple_not: consumesFalse,
optional: consumesFalse,
labeled: consumesExpression,
text: consumesExpression,
simple_and: consumesFalse,
simple_not: consumesFalse,
optional: consumesFalse,
zero_or_more: consumesFalse,
one_or_more: consumesExpression,
group: consumesExpression,
one_or_more: consumesExpression,
group: consumesExpression,
semantic_and: consumesFalse,
semantic_not: consumesFalse,
@ -66,7 +66,7 @@ let asts = {
},
"class": consumesTrue,
any: consumesTrue
any: consumesTrue
});
return consumes(node);

28
lib/compiler/index.js

@ -28,18 +28,18 @@ let compiler = {
// |peg.GrammarError|.
passes: {
check: {
reportUndefinedRules: require("./passes/report-undefined-rules"),
reportDuplicateRules: require("./passes/report-duplicate-rules"),
reportDuplicateLabels: require("./passes/report-duplicate-labels"),
reportInfiniteRecursion: require("./passes/report-infinite-recursion"),
reportUndefinedRules: require("./passes/report-undefined-rules"),
reportDuplicateRules: require("./passes/report-duplicate-rules"),
reportDuplicateLabels: require("./passes/report-duplicate-labels"),
reportInfiniteRecursion: require("./passes/report-infinite-recursion"),
reportInfiniteRepetition: require("./passes/report-infinite-repetition")
},
transform: {
removeProxyRules: require("./passes/remove-proxy-rules")
removeProxyRules: require("./passes/remove-proxy-rules")
},
generate: {
generateBytecode: require("./passes/generate-bytecode"),
generateJS: require("./passes/generate-js")
generateBytecode: require("./passes/generate-bytecode"),
generateJS: require("./passes/generate-js")
}
},
@ -52,13 +52,13 @@ let compiler = {
options = processOptions(options, {
allowedStartRules: [ast.rules[0].name],
cache: false,
dependencies: {},
exportVar: null,
format: "bare",
optimize: "speed",
output: "parser",
trace: false
cache: false,
dependencies: {},
exportVar: null,
format: "bare",
optimize: "speed",
output: "parser",
trace: false
});
Object.keys(passes).forEach(stage => {

52
lib/compiler/passes/generate-bytecode.js

@ -239,8 +239,8 @@ function generateBytecode(ast) {
[op.PUSH_CURR_POS],
[op.SILENT_FAILS_ON],
generate(expression, {
sp: context.sp + 1,
env: cloneEnv(context.env),
sp: context.sp + 1,
env: cloneEnv(context.env),
action: null
}),
[op.SILENT_FAILS_OFF],
@ -296,8 +296,8 @@ function generateBytecode(ast) {
rule: function(node) {
node.bytecode = generate(node.expression, {
sp: -1, // stack pointer
env: { }, // mapping of label names to stack positions
sp: -1, // stack pointer
env: { }, // mapping of label names to stack positions
action: null // action nodes pass themselves to children here
});
},
@ -323,8 +323,8 @@ function generateBytecode(ast) {
function buildAlternativesCode(alternatives, context) {
return buildSequence(
generate(alternatives[0], {
sp: context.sp,
env: cloneEnv(context.env),
sp: context.sp,
env: cloneEnv(context.env),
action: null
}),
alternatives.length > 1
@ -348,8 +348,8 @@ function generateBytecode(ast) {
let emitCall = node.expression.type !== "sequence"
|| node.expression.elements.length === 0;
let expressionCode = generate(node.expression, {
sp: context.sp + (emitCall ? 1 : 0),
env: env,
sp: context.sp + (emitCall ? 1 : 0),
env: env,
action: node
});
let functionIndex = addFunctionConst(Object.keys(env), node.code);
@ -378,15 +378,15 @@ function generateBytecode(ast) {
return buildSequence(
generate(elements[0], {
sp: context.sp,
env: context.env,
sp: context.sp,
env: context.env,
action: null
}),
buildCondition(
[op.IF_NOT_ERROR],
buildElementsCode(elements.slice(1), {
sp: context.sp + 1,
env: context.env,
sp: context.sp + 1,
env: context.env,
action: context.action
}),
buildSequence(
@ -422,8 +422,8 @@ function generateBytecode(ast) {
return buildSequence(
[op.PUSH_CURR_POS],
buildElementsCode(node.elements, {
sp: context.sp + 1,
env: context.env,
sp: context.sp + 1,
env: context.env,
action: context.action
})
);
@ -435,8 +435,8 @@ function generateBytecode(ast) {
context.env[node.label] = context.sp + 1;
return generate(node.expression, {
sp: context.sp,
env: env,
sp: context.sp,
env: env,
action: null
});
},
@ -445,8 +445,8 @@ function generateBytecode(ast) {
return buildSequence(
[op.PUSH_CURR_POS],
generate(node.expression, {
sp: context.sp + 1,
env: cloneEnv(context.env),
sp: context.sp + 1,
env: cloneEnv(context.env),
action: null
}),
buildCondition(
@ -468,8 +468,8 @@ function generateBytecode(ast) {
optional: function(node, context) {
return buildSequence(
generate(node.expression, {
sp: context.sp,
env: cloneEnv(context.env),
sp: context.sp,
env: cloneEnv(context.env),
action: null
}),
buildCondition(
@ -482,8 +482,8 @@ function generateBytecode(ast) {
zero_or_more: function(node, context) {
let expressionCode = generate(node.expression, {
sp: context.sp + 1,
env: cloneEnv(context.env),
sp: context.sp + 1,
env: cloneEnv(context.env),
action: null
});
@ -497,8 +497,8 @@ function generateBytecode(ast) {
one_or_more: function(node, context) {
let expressionCode = generate(node.expression, {
sp: context.sp + 1,
env: cloneEnv(context.env),
sp: context.sp + 1,
env: cloneEnv(context.env),
action: null
});
@ -515,8 +515,8 @@ function generateBytecode(ast) {
group: function(node, context) {
return generate(node.expression, {
sp: context.sp,
env: cloneEnv(context.env),
sp: context.sp,
env: cloneEnv(context.env),
action: null
});
},

26
lib/compiler/passes/generate-js.js

@ -40,8 +40,8 @@ function generateJS(ast, options) {
if (options.trace) {
parts.push([
"peg$tracer.trace({",
" type: \"rule.enter\",",
" rule: " + ruleNameCode + ",",
" type: \"rule.enter\",",
" rule: " + ruleNameCode + ",",
" location: peg$computeLocation(startPos, startPos)",
"});",
""
@ -62,8 +62,8 @@ function generateJS(ast, options) {
parts.push([
"if (cached.result !== peg$FAILED) {",
" peg$tracer.trace({",
" type: \"rule.match\",",
" rule: " + ruleNameCode + ",",
" type: \"rule.match\",",
" rule: " + ruleNameCode + ",",
" result: cached.result,",
" location: peg$computeLocation(startPos, peg$currPos)",
" });",
@ -103,8 +103,8 @@ function generateJS(ast, options) {
"",
"if (" + resultCode + " !== peg$FAILED) {",
" peg$tracer.trace({",
" type: \"rule.match\",",
" rule: " + ruleNameCode + ",",
" type: \"rule.match\",",
" rule: " + ruleNameCode + ",",
" result: " + resultCode + ",",
" location: peg$computeLocation(startPos, peg$currPos)",
" });",
@ -411,7 +411,7 @@ function generateJS(ast, options) {
function s(i) { return "s" + i; } // |stack[i]| of the abstract machine
let stack = {
sp: -1,
sp: -1,
maxSp: -1,
push: function(exprCode) {
@ -1088,7 +1088,7 @@ function generateJS(ast, options) {
"",
" details = peg$posDetailsCache[p];",
" details = {",
" line: details.line,",
" line: details.line,",
" column: details.column",
" };",
"",
@ -1115,12 +1115,12 @@ function generateJS(ast, options) {
" return {",
" start: {",
" offset: startPos,",
" line: startPosDetails.line,",
" line: startPosDetails.line,",
" column: startPosDetails.column",
" },",
" end: {",
" offset: endPos,",
" line: endPosDetails.line,",
" line: endPosDetails.line,",
" column: endPosDetails.column",
" }",
" };",
@ -1209,15 +1209,15 @@ function generateJS(ast, options) {
return options.trace
? [
"{",
" SyntaxError: peg$SyntaxError,",
" SyntaxError: peg$SyntaxError,",
" DefaultTracer: peg$DefaultTracer,",
" parse: peg$parse",
" parse: peg$parse",
"}"
].join("\n")
: [
"{",
" SyntaxError: peg$SyntaxError,",
" parse: peg$parse",
" parse: peg$parse",
"}"
].join("\n");
}

12
lib/compiler/passes/report-duplicate-labels.js

@ -47,13 +47,13 @@ function reportDuplicateLabels(ast) {
env[node.label] = node.location;
},
text: checkExpressionWithClonedEnv,
simple_and: checkExpressionWithClonedEnv,
simple_not: checkExpressionWithClonedEnv,
optional: checkExpressionWithClonedEnv,
text: checkExpressionWithClonedEnv,
simple_and: checkExpressionWithClonedEnv,
simple_not: checkExpressionWithClonedEnv,
optional: checkExpressionWithClonedEnv,
zero_or_more: checkExpressionWithClonedEnv,
one_or_more: checkExpressionWithClonedEnv,
group: checkExpressionWithClonedEnv
one_or_more: checkExpressionWithClonedEnv,
group: checkExpressionWithClonedEnv
});
check(ast);

34
lib/compiler/visitor.js

@ -38,26 +38,26 @@ let visitor = {
});
},
initializer: visitNop,
rule: visitExpression,
named: visitExpression,
choice: visitChildren("alternatives"),
action: visitExpression,
sequence: visitChildren("elements"),
labeled: visitExpression,
text: visitExpression,
simple_and: visitExpression,
simple_not: visitExpression,
optional: visitExpression,
initializer: visitNop,
rule: visitExpression,
named: visitExpression,
choice: visitChildren("alternatives"),
action: visitExpression,
sequence: visitChildren("elements"),
labeled: visitExpression,
text: visitExpression,
simple_and: visitExpression,
simple_not: visitExpression,
optional: visitExpression,
zero_or_more: visitExpression,
one_or_more: visitExpression,
group: visitExpression,
one_or_more: visitExpression,
group: visitExpression,
semantic_and: visitNop,
semantic_not: visitNop,
rule_ref: visitNop,
literal: visitNop,
"class": visitNop,
any: visitNop
rule_ref: visitNop,
literal: visitNop,
"class": visitNop,
any: visitNop
};
Object.keys(DEFAULT_FUNCTIONS).forEach(type => {

72
lib/parser.js

@ -137,10 +137,10 @@ function peg$parse(input, options) {
var peg$c0 = function(initializer, rules) {
return {
type: "grammar",
type: "grammar",
initializer: extractOptional(initializer, 0),
rules: extractList(rules, 0),
location: location()
rules: extractList(rules, 0),
location: location()
};
};
var peg$c1 = function(code) {
@ -150,17 +150,17 @@ function peg$parse(input, options) {
var peg$c3 = peg$literalExpectation("=", false);
var peg$c4 = function(name, displayName, expression) {
return {
type: "rule",
name: name,
expression: displayName !== null
type: "rule",
name: name,
expression: displayName !== null
? {
type: "named",
name: displayName[0],
type: "named",
name: displayName[0],
expression: expression,
location: location()
location: location()
}
: expression,
location: location()
location: location()
};
};
var peg$c5 = "/";
@ -168,26 +168,26 @@ function peg$parse(input, options) {
var peg$c7 = function(head, tail) {
return tail.length > 0
? {
type: "choice",
type: "choice",
alternatives: buildList(head, tail, 3),
location: location()
location: location()
}
: head;
};
var peg$c8 = function(expression, code) {
return code !== null
? {
type: "action",
type: "action",
expression: expression,
code: code[1],
location: location()
code: code[1],
location: location()
}
: expression;
};
var peg$c9 = function(head, tail) {
return tail.length > 0
? {
type: "sequence",
type: "sequence",
elements: buildList(head, tail, 1),
location: location()
}
@ -197,17 +197,17 @@ function peg$parse(input, options) {
var peg$c11 = peg$literalExpectation(":", false);
var peg$c12 = function(label, expression) {
return {
type: "labeled",
label: label,
type: "labeled",
label: label,
expression: expression,
location: location()
location: location()
};
};
var peg$c13 = function(operator, expression) {
return {
type: OPS_TO_PREFIXED_TYPES[operator],
type: OPS_TO_PREFIXED_TYPES[operator],
expression: expression,
location: location()
location: location()
};
};
var peg$c14 = "$";
@ -218,9 +218,9 @@ function peg$parse(input, options) {
var peg$c19 = peg$literalExpectation("!", false);
var peg$c20 = function(expression, operator) {
return {
type: OPS_TO_SUFFIXED_TYPES[operator],
type: OPS_TO_SUFFIXED_TYPES[operator],
expression: expression,
location: location()
location: location()
};
};
var peg$c21 = "?";
@ -247,8 +247,8 @@ function peg$parse(input, options) {
};
var peg$c33 = function(operator, code) {
return {
type: OPS_TO_SEMANTIC_PREDICATE_TYPES[operator],
code: code,
type: OPS_TO_SEMANTIC_PREDICATE_TYPES[operator],
code: code,
location: location()
};
};
@ -303,10 +303,10 @@ function peg$parse(input, options) {
var peg$c82 = peg$literalExpectation("i", false);
var peg$c83 = function(value, ignoreCase) {
return {
type: "literal",
value: value,
type: "literal",
value: value,
ignoreCase: ignoreCase !== null,
location: location()
location: location()
};
};
var peg$c84 = peg$otherExpectation("string");
@ -325,11 +325,11 @@ function peg$parse(input, options) {
var peg$c97 = peg$literalExpectation("]", false);
var peg$c98 = function(inverted, parts, ignoreCase) {
return {
type: "class",
parts: parts.filter(part => part !== ""),
inverted: inverted !== null,
type: "class",
parts: parts.filter(part => part !== ""),
inverted: inverted !== null,
ignoreCase: ignoreCase !== null,
location: location()
location: location()
};
};
var peg$c99 = "-";
@ -559,7 +559,7 @@ function peg$parse(input, options) {
details = peg$posDetailsCache[p];
details = {
line: details.line,
line: details.line,
column: details.column
};
@ -586,12 +586,12 @@ function peg$parse(input, options) {
return {
start: {
offset: startPos,
line: startPosDetails.line,
line: startPosDetails.line,
column: startPosDetails.column
},
end: {
offset: endPos,
line: endPosDetails.line,
line: endPosDetails.line,
column: endPosDetails.column
}
};
@ -5008,5 +5008,5 @@ function peg$parse(input, options) {
module.exports = {
SyntaxError: peg$SyntaxError,
parse: peg$parse
parse: peg$parse
};

4
lib/peg.js

@ -5,8 +5,8 @@ let peg = {
VERSION: "0.10.0",
GrammarError: require("./grammar-error"),
parser: require("./parser"),
compiler: require("./compiler"),
parser: require("./parser"),
compiler: require("./compiler"),
// Generates a parser from a specified grammar and returns it.
//

40
spec/api/generated-parser-api.spec.js

@ -80,53 +80,53 @@ describe("generated parser API", function() {
parser.parse("b", { tracer: tracer });
expect(tracer.trace).toHaveBeenCalledWith({
type: "rule.enter",
rule: "start",
type: "rule.enter",
rule: "start",
location: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 0, line: 1, column: 1 }
end: { offset: 0, line: 1, column: 1 }
}
});
expect(tracer.trace).toHaveBeenCalledWith({
type: "rule.enter",
rule: "a",
type: "rule.enter",
rule: "a",
location: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 0, line: 1, column: 1 }
end: { offset: 0, line: 1, column: 1 }
}
});
expect(tracer.trace).toHaveBeenCalledWith({
type: "rule.fail",
rule: "a",
type: "rule.fail",
rule: "a",
location: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 0, line: 1, column: 1 }
end: { offset: 0, line: 1, column: 1 }
}
});
expect(tracer.trace).toHaveBeenCalledWith({
type: "rule.enter",
rule: "b",
type: "rule.enter",
rule: "b",
location: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 0, line: 1, column: 1 }
end: { offset: 0, line: 1, column: 1 }
}
});
expect(tracer.trace).toHaveBeenCalledWith({
type: "rule.match",
rule: "b",
result: "b",
type: "rule.match",
rule: "b",
result: "b",
location: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 1, line: 1, column: 2 }
end: { offset: 1, line: 1, column: 2 }
}
});
expect(tracer.trace).toHaveBeenCalledWith({
type: "rule.match",
rule: "start",
result: "b",
type: "rule.match",
rule: "start",
result: "b",
location: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 1, line: 1, column: 2 }
end: { offset: 1, line: 1, column: 2 }
}
});
});

4
spec/api/pegjs-api.spec.js

@ -43,7 +43,7 @@ describe("PEG.js API", function() {
describe("when |allowedStartRules| is set", function() {
it("generated parser can start only from specified rules", function() {
let parser = peg.generate(grammar, {
optimize: "speed",
optimize: "speed",
allowedStartRules: ["b", "c"]
});
@ -68,7 +68,7 @@ describe("PEG.js API", function() {
describe("when |allowedStartRules| is set", function() {
it("generated parser can start only from specified rules", function() {
let parser = peg.generate(grammar, {
optimize: "size",
optimize: "size",
allowedStartRules: ["b", "c"]
});

8
spec/api/plugin-api.spec.js

@ -97,11 +97,11 @@ describe("plugin API", function() {
let parser = peg.generate([
"start = .* {",
" return {",
" type: 'grammar',",
" type: 'grammar',",
" rules: [",
" {",
" type: 'rule',",
" name: 'start',",
" type: 'rule',",
" name: 'start',",
" expression: { type: 'literal', value: text(), ignoreCase: false }",
" }",
" ]",
@ -145,7 +145,7 @@ describe("plugin API", function() {
};
let parser = peg.generate(grammar, {
allowedStartRules: ["a"],
plugins: [plugin]
plugins: [plugin]
});
expect(() => { parser.parse("x", { startRule: "a" }); }).toThrow();

124
spec/behavior/generated-parser-behavior.spec.js

@ -460,47 +460,47 @@ describe("generated parser behavior", function() {
let testcases = [
{
grammar: "start = (a:'a') &{ return a === 'a'; }",
input: "a"
input: "a"
},
{
grammar: "start = (a:'a')? &{ return a === 'a'; }",