i am continue to learning PEG.js, but stuck on the next issue.
PEG.js-generated parser unable to match string containing underscopes:
CONFIG += stl_off
but successfully parse the string without them:
CONFIG += static
(this is a built-in variable CONFIG
"appending-assignment" statement, rvalue
is a list of limited set of strings)
What am i doing wrong?
The grammar:
Start =
Statement* {return env; }
Statement
= Comment
/ GenericAssignmentStatementT
GenericAssignmentStatementT = Whitespace* GenericAssignmentStatement Whitespace*
GenericAssignmentStatement
// TEMPLATE
= TemplateAssignmentStatement
// CONFIG
/ ConfigAssignmentStatement
/ ConfigAppendingAssignmentStatement
// -------------------------------------------------------------------------------------------------
// # Single-line comment
Comment "Comment string" = Whitespace* "#" rvalue:$(!LineBreak .)* LineBreak+ {
return "#" + rvalue;
}
// -------------------------------------------------------------------------------------------------
// TEMPLATE = app|lib|subdirs|aux|vcapp|vclib
SystemTemplateVariable = "TEMPLATE"
SystemTemplateVariableValue = "app" / "lib" / "subdirs" / "aux" / "vcapp" / "vclib"
TemplateAssignmentStatement = lvalue:SystemTemplateVariable AssignmentOperator rvalue:SystemTemplateVariableValue Whitespace* LineBreak* {
if (!env.qmakeVars)
env.qmakeVars = {};
env.qmakeVars[lvalue] = rvalue;
return {name:"TEMPLATE", op:"=", value:rvalue};
}
// -------------------------------------------------------------------------------------------------
// CONFIG = release|debug|debug_and_release|debug_and_release_target
SystemConfigVariable = "CONFIG"
SystemConfigVariableValue = "release" / "debug" / "debug_and_release" / "debug_and_release_target"
ConfigAssignmentStatement = lvalue:SystemConfigVariable AssignmentOperator rvalue:SystemConfigVariableValue? Whitespace* LineBreak* {
if (!env.qmakeVars)
env.qmakeVars = {};
env.qmakeVars[lvalue] = [rvalue];
return {name:"CONFIG", op:"=", value:rvalue};
}
ConfigAppendingAssignmentStatement = lvalue:SystemConfigVariable
AppendingAssignmentOperator rvalue:SystemConfigVariableValue Whitespace* LineBreak* {
if (!env.qmakeVars)
env.qmakeVars = {};
if (!env.qmakeVars[lvalue])
env.qmakeVars[lvalue] = [];
env.qmakeVars[lvalue].push(rvalue);
return {name:"CONFIG", op:"+=", value:rvalue};
}
// Assignment operators
AssignmentOperator = Whitespace* "=" Whitespace*
AppendingAssignmentOperator = Whitespace* "+=" Whitespace*
// Delimeters
LineBreak = [\r\n] {
return "LB";
}
Whitespace = [ \t] {
return "WS";
}
Test input:
TEMPLATE = app
CONFIG += debug_and_release
Test PEG.js output:
Line 2, column 16: Expected "CONFIG", "TEMPLATE", Comment string, [ \t], [\r\n], or end of input but "_" found.
PEG evaluates SystemConfigVariableValue
from left to right, so debug_and_release
will actually be matched by the release
literal (after which the parser gets confused).
If you declare the more specific literal first, it'll work:
SystemConfigVariableValue = "debug_and_release_target" / "debug_and_release" / "release" / "debug"