Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/flash/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Antlr4 在ANTLR v4中构建自定义解析树_Antlr4_Parse Tree - Fatal编程技术网

Antlr4 在ANTLR v4中构建自定义解析树

Antlr4 在ANTLR v4中构建自定义解析树,antlr4,parse-tree,Antlr4,Parse Tree,问:在Antlrv4中,有没有一种(更直接的)在解析时构建自定义解析树的方法 我想我们可以遍历并重写自动构建的树,但我想知道我们是否仍然可以在解析时手动构建树(或者调整树)(类似于ANTLR v3和ealier)。这个想法是,根据编写语法的方式,我们在ANTLR构建的树中得到了很多无用的节点,虽然我知道您只能覆盖您感兴趣的侦听器方法,但仍然需要检查和跳过无用的令牌类型,等等。否,我们对Antlr3的经验是,手动AST特性不可避免地导致代码更难维护和理解,从而导致开发人员在对语法进行任何更改时出现

问:在Antlrv4中,有没有一种(更直接的)在解析时构建自定义解析树的方法


我想我们可以遍历并重写自动构建的树,但我想知道我们是否仍然可以在解析时手动构建树(或者调整树)(类似于ANTLR v3和ealier)。这个想法是,根据编写语法的方式,我们在ANTLR构建的树中得到了很多无用的节点,虽然我知道您只能覆盖您感兴趣的侦听器方法,但仍然需要检查和跳过无用的令牌类型,等等。

否,我们对Antlr3的经验是,手动AST特性不可避免地导致代码更难维护和理解,从而导致开发人员在对语法进行任何更改时出现大量回归错误。标记不再从树中省略,因为很难判断未来版本的应用程序将需要哪些终端,并且如果新组件或功能现在需要以前未使用的终端,则不需要更改/验证解析树上运行的所有代码。

否,我们对Antlr3的经验是,手动AST特性不可避免地导致代码更难维护和理解,从而导致开发人员在对语法进行任何更改时出现大量回归错误。标记不再从树中省略,因为很难判断未来版本的应用程序将需要哪些终端,如果一个新的组件或功能现在需要一个以前未使用过的终端,那么您不需要更改/验证所有在解析树上运行的代码。

您可以覆盖
org.antlr.v4.runtime.Parser.addContextToParseTree()
,以对创建的节点进行控制。我不确定这正是你所说的习惯

@parser::members {

@Override
protected void addContextToParseTree() {
    // code is a rule enabled by semantic predicate 'full' 
    // that matches generic lines of code.
    if(!full && _ctx instanceof CodeContext){
        return;
    }

    // otherwise add the node to the tree..
    super.addContextToParseTree();
}

}

您可以重写
org.antlr.v4.runtime.Parser.addContextToParseTree()
,以对创建的节点进行控制。我不确定这正是你所说的习惯

@parser::members {

@Override
protected void addContextToParseTree() {
    // code is a rule enabled by semantic predicate 'full' 
    // that matches generic lines of code.
    if(!full && _ctx instanceof CodeContext){
        return;
    }

    // otherwise add the node to the tree..
    super.addContextToParseTree();
}

}

谢谢你的清理!当您更改/重新组织一些语法规则时,保持客户端代码不变,这确实是一个优点。。。我是从性能的角度考虑的,但我猜开销通常几乎为零。@OctavianTheodor根据我的评估,ANTLR 4的当前设计并没有被证明是一个显著的性能限制,这是我几乎痴迷的事情。其他方面,包括规则本身的实际结构(前瞻性、模糊性等),总是有更显著的影响。感谢您的澄清!当您更改/重新组织一些语法规则时,保持客户端代码不变,这确实是一个优点。。。我是从性能的角度考虑的,但我猜开销通常几乎为零。@OctavianTheodor根据我的评估,ANTLR 4的当前设计并没有被证明是一个显著的性能限制,这是我几乎痴迷的事情。其他方面,包括规则本身的实际结构(前瞻性、模糊性等),总是有更显著的影响。谢谢!虽然我已经离开了那个“问题”,但这似乎确实是一个很好的发现。(实际上还没有尝试过,但通过检查,我会说你是对的!)不用担心-到目前为止,它似乎对我有效-我的应用程序缓存解析树,因为我只需要它们用于符号表信息(函数/变量定义),创建稀疏树的功能可以节省大量的空间/时间。谢谢!虽然我已经离开了那个“问题”,但这似乎确实是一个很好的发现。(实际上还没有尝试过,但通过检查,我会说你是对的!)不用担心-到目前为止,它似乎对我有效-我的应用程序缓存解析树,因为我只需要它们用于符号表信息(函数/变量定义),所以创建稀疏树的功能可以节省大量的空间/时间。