Parsing 使用位置选择在AST中快速失败的解析器组合器

Parsing 使用位置选择在AST中快速失败的解析器组合器,parsing,parsec,parser-combinators,Parsing,Parsec,Parser Combinators,我编写了一些解析器组合器,用源位置信息构建AST。分析表明,至少30%的执行时间用于反复分析不必要的信息以生成源位置数据。我需要帮助找到一种替代方法来提高性能 问题 假设我正在解析一种只包含两个标记的语言:“a”和“B”。为了生成AST节点,我目前定义了一个组合器,用于提取位置并构建节点: // Parse body and build resulting node from function // nodeFactory called with position and result from

我编写了一些解析器组合器,用源位置信息构建AST。分析表明,至少30%的执行时间用于反复分析不必要的信息以生成源位置数据。我需要帮助找到一种替代方法来提高性能

问题 假设我正在解析一种只包含两个标记的语言:“a”和“B”。为了生成AST节点,我目前定义了一个组合器,用于提取位置并构建节点:

// Parse body and build resulting node from function
// nodeFactory called with position and result from body.
var node = function(body, nodeFactory) {
    return bind(
        locParser, // get the current location in the token stream
        body,
        prevEnd, // get the previous end position in the token stream
        function(o, x, c) {
            return always(f(Location(o, c), x));
        });
};

var a = node(char('A'), buildNodeA);
var b = node(char('B'), buildNodeB);
这种方法的问题是无论body是否成功,总是运行
locParser

var element = either(a, b);
var program = many(element);
run(program, "AAABBA");
预期行为
a
一旦明确其
主体
将失败,就会失败

实际行为 对于“B”令牌,首先运行
a
locParser
,当
body
失败时,运行
B
locParser
。随着嵌套和更多分支的出现,这将成为一个性能问题

边缘案例 该位置包含整个消费输入范围:

var c = node(next(char(' '), char('C')), buildNodeC);
“C”节点的位置从空格字符的开头开始

var d = node(between(char('('), char(')'), char('D')), buildNodeD);
“D”节点的位置从“(”的开头开始,到“')的结尾结束。
节点可以正确处理这两种情况

问题: 如何重构这些解析器,使其快速失效,但仍能访问正确的位置数据


我更愿意让每个解析器都相当独立,避免重复逻辑。此外,构造后不得修改节点。

您是否查看了有关解析器组合器的说明。他们可能会保留你的答案。如果你用一种语言来标记你的问题,你可能会得到更多的关注。一般来说,语言标记的追随者比问题域标记多得多。