我知道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
我一直在与 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 声明有任何想法吗?
谢谢你!
我使用 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) 我正在使用 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) 这篇中等文章向我展示了如何防止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)
但现在每一行都显示该错误。我也尝试将其放在*前面,希望它允许任何内容(*除非是后面跟着我禁止的语法表达式),但没有骰子。
我怎样才能做到这一点?
例如,给定一个算术表达式,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) 我正在尝试为数学表达式编写一个解析器,其中命名变量是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++代码,并创建一个AST.我想要做的是提取一些简单的反射信息(类名,成员变量及其类型等).我不需要编译代码,也不需要生成二进制文件.我正在寻找最简单的方法来做到这一点.理想情况下,我想在一个静态库中使用一个小的解析器,没有依赖关系.
我一直在环顾四周,似乎Bison解析器可以为我做这个.我试图找到一个开源解析器,但所有谷歌都会给我带来的是Bison的C++包装器,而不是C++的野牛解析器.通过为C++编写的其他所有解析器提供结果,输入"C++解析器"也会失败.
是否有一个开源项目可以满足我的需求?
您好,我正在尝试实现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) 我有这种语言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
c++ ×3
go ×2
java ×2
antlr ×1
antlr4 ×1
boost ×1
boost-spirit ×1
catamorphism ×1
clang ×1
eslint ×1
go-toolchain ×1
haskell ×1
iota ×1
javaparser ×1
javascript ×1
llvm-clang ×1
parsing ×1
r ×1
recursion ×1