标签: abstract-syntax-tree

如何使用 JavaParser 在同一行添加新语句

我知道JavaParser在 AST 上运行,但我很好奇是否可以在与另一条语句相同的行上添加新语句。让我举一个例子来说明我想要实现的目标。

输入示例X.java(不要介意“逻辑”):

public class X {
    public static void main(String[] args) {
        int a = 1;
        while(a < 100) {
            a *= 2;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我想要实现的是在System.out.println("End of loop reached");每个循环体的末尾添加语句 - 但是,如果可能的话,我想在循环体中的最后一个语句旁边添加这个新语句。因此,结果应该如下所示:

public class X {
    public static void main(String[] args) {
        int a = 1;
        while(a < 100) {
            a *= 2; System.out.println("End of loop reached");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

目前我使用以下访问者(用 Kotlin 编写),只是为了了解 JavaParser。然而,这会导致为打印语句添加新行。关于如何指示 JavaParser 在同一行添加新节点有什么想法吗?

class WhileVisitor : VoidVisitorAdapter<Void>() …
Run Code Online (Sandbox Code Playgroud)

java abstract-syntax-tree visitor-pattern javaparser code-transformation

5
推荐指数
0
解决办法
544
查看次数

使用 go/ast 进行 iota 声明

我一直在与 go/ast 合作来解析 go 源代码并将其复制到另一个文件中,作为供应商练习的一部分。我已经处理了大部分事情 - 函数、类型等 - 但我正在努力处理使用 iota 的 const 声明。我正在迭代 ast.File.Scope.Objects 中的项目,并复制 Scope.Outer == nil 及其 Decl == ast.ValueSpec 的对象的源代码,基本上意味着顶级变量和常量。

在类型块中:

const (
    a = iota
    b
    c
    d
)
Run Code Online (Sandbox Code Playgroud)

...它们中的每一个都注册为一个单独的对象,这很公平。但是,我很难为它们分配值,因为当我迭代它们时,对象也可能乱序。我可以将这些值视为 ast.Object.Data,但当它设置为 1 << iota 等时,它似乎也关闭了。有人对如何获得分配了正确 iota 值的分组 const 声明有任何想法吗?

谢谢你!

abstract-syntax-tree go iota

5
推荐指数
1
解决办法
985
查看次数

如何使用 go/analysis 查找 Ident 的声明?

我使用 go/analysis 创建自己的静态分析工具。我仍然不知道如何从ast.Ident中找到def信息。

这是我的测试数据

package randomcheck
func xxx() {
}
func demo()  {
    xxx()
}

Run Code Online (Sandbox Code Playgroud)

还有我自己的分析仪

import (
    "fmt"
    "go/ast"
    "golang.org/x/tools/go/analysis"
    "golang.org/x/tools/go/analysis/passes/inspect"
)

var name string // -name flag
var Analyzer = &analysis.Analyzer{
    Name:     "fft",
    Requires: []*analysis.Analyzer{inspect.Analyzer},
    Run:      run,
}
//pass.Fset.Position(name.Pos())
func run(pass *analysis.Pass) (interface{}, error) {
    for _, f := range pass.Files {
        ast.Inspect(f, func(node ast.Node) bool {
            name,ok := node.(*ast.Ident)
            if !ok {
                return true
            }
            if name == nil {
                return true
            }
            if pass.TypesInfo.Defs[name] != nil …
Run Code Online (Sandbox Code Playgroud)

static-analysis abstract-syntax-tree go go-toolchain

5
推荐指数
1
解决办法
698
查看次数

如何省略不重要的节点?

我正在使用 ANTLR 4.9.2 来解析表示汇编指令的语法。

grammar IrohAsm;
main: line* | EOF;

line: (rangedec | instruction | comment)? EOL;

instruction: MNEMONIC firstoperand COMMA secondoperand;
rangedec : range assignment?;
firstoperand : range | mem | REGISTER;
secondoperand : range | mem | IMM | REGISTER;
range : IDENTIFIER OPENBRACKETS IMM CLOSEDBRACKETS;
assignment : EQUALS OPENCURL IMM (COMMA IMM)* CLOSECURL;
mem : AT IMM;
comment : '#' ~EOL*;

WHITESPACE : (' ') -> skip ;

// remember to append \n to input
EOL : …
Run Code Online (Sandbox Code Playgroud)

java antlr abstract-syntax-tree antlr4

5
推荐指数
1
解决办法
361
查看次数

使用 eslint no-restricted-syntax 防止 screen.findByX 不等待?

这篇中等文章向我展示了如何防止await前面的属性:

"no-restricted-syntax": [
  "error",
  {
    "message": "promise.then is unnecessary when using async/await",
    "selector": "AwaitExpression[argument.callee.property.name=\" then\"]"
  }
]
Run Code Online (Sandbox Code Playgroud)

但我想要相反,我想限制这些:

expect(screen.findByRole(...))....;
screen.findByRole(...);
Run Code Online (Sandbox Code Playgroud)

但允许这些:

expect(await screen.findByRole(...))....;
await screen.findByRole(...);
Run Code Online (Sandbox Code Playgroud)

我在测试文件的覆盖下尝试了这个:

expect(screen.findByRole(...))....;
screen.findByRole(...);
Run Code Online (Sandbox Code Playgroud)

但现在每一行都显示该错误。我也尝试将其放在*前面,希望它允许任何内容(*除非是后面跟着我禁止的语法表达式),但没有骰子。

我怎样才能做到这一点?

javascript abstract-syntax-tree eslint

5
推荐指数
1
解决办法
197
查看次数

用 R 转换抽象语法树

例如,给定一个算术表达式,x + y*z我想将其转换为add(x, multiply(y, z)).

在这里发现了一个有用的功能

> getAST <- function(ee) purrr::map_if(as.list(ee), is.call, getAST)
> getAST(quote(x + y*z)) 
[[1]]
`+`

[[2]]
x

[[3]]
[[3]][[1]]
`*`

[[3]][[2]]
y

[[3]][[3]]
z
Run Code Online (Sandbox Code Playgroud)

可以使用它rapply(result, as.character, how = "list")来获取字符而不是符号。

如何从这个 AST 中得到add(x, multiply(y, z))(结果)?当有一些括号时,这会变得更加复杂:

> getAST(quote((x + y) * z)) 
[[1]]
`*`

[[2]]
[[2]][[1]]
`(`

[[2]][[2]]
[[2]][[2]][[1]]
`+`

[[2]][[2]][[2]]
x

[[2]][[2]][[3]]
y



[[3]]
z
Run Code Online (Sandbox Code Playgroud)

我不要求答案必须使用该getAST功能。这只是一种可行的方法。

当然,在我的实际用例中,表达式更长。


这是没有括号时的情况的解决方案(我认为):

getAST <- function(ee) purrr::map_if(as.list(ee), is.call, getAST)

ast …
Run Code Online (Sandbox Code Playgroud)

r arithmetic-expressions symbolic-math abstract-syntax-tree

5
推荐指数
1
解决办法
86
查看次数

Boost :: spirit :: qi定义了计算器的nullaries

我正在尝试为数学表达式编写一个解析器,其中命名变量是boost::spirit(版本1_51_0)中的nullaries,我完全是新的.我定义typedef boost::function<double()> Value,我的规则将被声明如下:qi::rule<Iterator, Value()> expression, term, others, ...;

我用这个宏定义了nullaries上的二元运算符

#define BINARY_FUNCTOR(name, op)                        \
struct name                                             \
{                                                       \
  name(Value x, Value y): x_(x), y_(y) {}               \
  double operator()() { return x_() op y_(); }          \
  Value x_, y_;                                         \
}; 
Run Code Online (Sandbox Code Playgroud)

并且有ADD,SUB等从我所看到的例子,我期望的规则,这样的定义:

expression = term
             >> *( (lit('+') >> term[ADD(_val, _1)])
                 | (lit('-') >> term[SUB(_val, _1)])
                 );
Run Code Online (Sandbox Code Playgroud)

但这似乎不是正确的语法,因为我得到一个错误

boost/spirit/home/support/action_dispatch.hpp:162: error: no match for call to ‘(const<unnamed>::SUB) (boost::function<double ()()>&, boost::spirit::context<boost::fusion::cons<boost::function<double ()()>&, boost::fusion::nil>, boost::fusion::vector0<void> …
Run Code Online (Sandbox Code Playgroud)

c++ boost abstract-syntax-tree boost-spirit boost-spirit-qi

4
推荐指数
1
解决办法
406
查看次数

如何解析C++来创建AST?

我正在尝试解析C++代码,并创建一个AST.我想要做的是提取一些简单的反射信息(类名,成员变量及其类型等).我不需要编译代码,也不需要生成二进制文件.我正在寻找最简单的方法来做到这一点.理想情况下,我想在一个静态库中使用一个小的解析器,没有依赖关系.

我一直在环顾四周,似乎Bison解析器可以为我做这个.我试图找到一个开源解析器,但所有谷歌都会给我带来的是Bison的C++包装器,而不是C++的野牛解析器.通过为C++编写的其他所有解析器提供结果,输入"C++解析器"也会失败.

是否有一个开源项目可以满足我的需求?

c++ parsing abstract-syntax-tree

4
推荐指数
1
解决办法
914
查看次数

Clang AST访问者,避免遍历包含文件

您好,我正在尝试实现AST Clang访问者,这是我的代码。

class ExampleVisitor : public RecursiveASTVisitor<ExampleVisitor> {
private:
    ASTContext *astContext; // used for getting additional AST info

public:
    virtual bool VisitVarDecl(VarDecl *var) 
    {
        numVariables++;
        string varName = var->getQualifiedNameAsString();
        string varType = var->getType().getAsString();
        cout << "Found variable declaration: " << varName << " of type " << varType << "\n";
        APIs << varType << ", ";
        return true;
    }

    virtual bool VisitFunctionDecl(FunctionDecl *func)
    {
        numFunctions++;
        string funcName = func->getNameInfo().getName().getAsString();
        string funcType = func->getResultType().getAsString();
        cout << "Found function declaration: " << …
Run Code Online (Sandbox Code Playgroud)

c++ clang abstract-syntax-tree llvm-clang

4
推荐指数
1
解决办法
913
查看次数

有什么像cata但你可以匹配内部结构?

我有这种语言AST

data ExprF r = Const Int
              | Var   String
              | Lambda String r
              | EList [r]
              | Apply r r
 deriving ( Show, Eq, Ord, Functor, Foldable )
Run Code Online (Sandbox Code Playgroud)

我想将它转换为字符串

toString = cata $ \case
  Const x -> show x
  Var x -> x
  EList x -> unwords x
  Lambda x y -> unwords [x, "=>", y]
  Apply x y -> unwords [x, "(", y, ")"]
Run Code Online (Sandbox Code Playgroud)

但是当使用lambda时,Apply我需要括号

(x => x)(1)
Run Code Online (Sandbox Code Playgroud)

但我无法将内部结构与cata相匹配

toString :: Fix ExprF -> String
toString …
Run Code Online (Sandbox Code Playgroud)

recursion haskell abstract-syntax-tree catamorphism recursion-schemes

4
推荐指数
1
解决办法
151
查看次数