Javascript 使用PEG.js匹配包含下范围的字符串文字

Javascript 使用PEG.js匹配包含下范围的字符串文字,javascript,parsing,qmake,peg,pegjs,Javascript,Parsing,Qmake,Peg,Pegjs,我正在继续学习PEG.js,但仍停留在下一个问题上 PEG.js生成的解析器无法匹配包含底镜的字符串: CONFIG += stl_off 但是成功地在没有它们的情况下解析字符串: CONFIG += static (这是一个内置变量CONFIG“追加赋值”语句,rvalue是一组有限字符串的列表) 我做错了什么 语法: Start = Statement* {return env; } Statement = Comment / GenericAssignmen

我正在继续学习PEG.js,但仍停留在下一个问题上

PEG.js生成的解析器无法匹配包含底镜的字符串:

CONFIG += stl_off
但是成功地在没有它们的情况下解析字符串:

CONFIG += static
(这是一个内置变量
CONFIG
“追加赋值”语句,
rvalue
是一组有限字符串的列表)

我做错了什么


语法:

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";
}
测试输入:

TEMPLATE = app
CONFIG += debug_and_release
Test PEG.js输出:

Line 2, column 16: Expected "CONFIG", "TEMPLATE", Comment string, [ \t], [\r\n], or end of input but "_" found.

PEG从左到右计算
SystemConfigVariableValue
,因此
debug_和_release
实际上将由
release
文本匹配(之后解析器会感到困惑)

如果先声明更具体的文字,它将起作用:

SystemConfigVariableValue = "debug_and_release_target" / "debug_and_release" / "release" / "debug"

谢谢,它很管用!然而,这对我来说很奇怪-你能给我指出任何文章/教程/论文中描述的PEG.js关键字匹配吗?@eraxillan文档状态,对于
expression\u 1/expression\u 2/…/表达式\u n
:“尝试匹配第一个表达式,如果不成功,请尝试第二个表达式,以此类推。返回第一个成功匹配表达式的匹配结果”。它不检查哪个文本最匹配,而是首先检查哪个文本匹配。我假设它不会在随后无法解析其余部分时回溯。再次感谢你,罗伯特。所以,我需要搜索“最佳实践”文档或使用另一个解析器生成工具——我的语法似乎太复杂了,我对此感到非常困惑。我知道PEG从左到右计算条件,但匹配字符串文字的子集并不匹配字符串文字。我将在会议上提出一个问题github@Arman语法中的“release”与输入中的“debug”和“release”匹配。顺便说一句,没有任何东西表明PEG将提供最佳匹配,或者匹配是以标记化的方式进行的(在匹配之前,输入以某种方式被非单词边界分隔)。