我目前正在考虑如何最好地获取使用 Antlr 生成的 AST 并将其转换为我可以在我的程序中使用的有用对象。
我的语法(除了学习)的目的是创建一种可执行(运行时解释)语言。
例如,我将如何获取属性子树并实例化特定的 Attribute 类。例如
以下代码以我的语言显示:
Print(message:"Hello stackoverflow")
Run Code Online (Sandbox Code Playgroud)
将产生以下 AST:
我目前的想法是工厂类可以读取树,提取名称(message)和类型(STRING)值(“ Hello stackoverflow”)。现在,知道了类型,我可以实例化正确的类(例如 StringAttribute 类)并传入所需的属性数据 -name和value.
相同的方法可用于定义工厂,提取定义名称 ( Print),实例化 Print 类,然后传入从属性工厂生成的属性。
使用更复杂的程序,事情确实变得更复杂了:
Program(args:[1,2,3,4,5])
{
If(isTrue:IsInArray(array:{Program.args} value:5))
{
Then {
Print(message:"5 is in the array")
} Else {
Print(message:"More complex " + "message")
}
}
}
Run Code Online (Sandbox Code Playgroud)
非常欢迎任何/所有帮助或想法。非常感谢。
我以前的相关问题(可能有用):
acceptASTNode的方法有什么作用(javadoc 没有太大帮助...)以及何时visit(Expression node)调用该方法?这是我需要如何使用它的示例代码:
final List<Expression> listi = new ArrayList<Expression>();
String stringi = opi.generate(entryContract, true_false_maybe);
// stringi representes an expression, for example "g!=h".
parser.setSource(stringi.toCharArray());
unit = (CompilationUnit) parser.createAST(null);
ASTNode astRoot = unit.getRoot();
astRoot.accept(new ASTVisitor() {
public boolean visit(Expression node) {
listi.add(node);
return true;
}
});
Run Code Online (Sandbox Code Playgroud)
谢谢
给定一个ast可以自行评估的节点,但对于ast.literal_eval例如列表理解来说不够文字
src = '[i**2 for i in range(10)]'
a = ast.parse(src)
Run Code Online (Sandbox Code Playgroud)
现在a.body[0]是一个ast.Expr和a.body[0].value一个ast.ListComp。我想获得eval(src)会产生的列表,但只给出了ast.Expr节点。
我正在使用xtext为特定语言生成编辑器.当我使用编辑器作为我的新语言时,它具有所有可爱的xtext功能,如代码完成和着色等.我希望能够做的是在我的编辑器中可视化文本的结构.
我知道xtext有一个内部AST和一个解析树(我知道他们称之为"节点模型") - 有没有可视化这棵树的方法?
我写了一个测试程序(parse_ast.c)来解析ac源文件(tt.c)来看看libclang是如何工作的,输出是AST的层次结构:
这是测试文件:
/* tt.c */ // line 1
#include <unistd.h>
#include <stdio.h>
typedef ssize_t (*write_fn_t)(int, const void *, size_t);
void indirect_write(write_fn_t write_fn) { // line 7
(*write_fn)(1, "indirect call\n", 14);
}
void direct_write() { // line 11
write(1, "direct call\n", 12); // line 12 mising in the ast?
}
int main() { // line 15
direct_write();
indirect_write(write); // line 17 missing in the ast?
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出显示如下:
...
...
inclusion directive at tt.c (2, 1) to (2, 20)
inclusion …Run Code Online (Sandbox Code Playgroud) 我想扫描clang的AST.我开始使用一个教程中提供的一些示例代码.
我目前的代码是
#include <iostream>
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/Casting.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/FileSystemOptions.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Basic/FileManager.h"
#include "clang/Frontend/Utils.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/Version.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Frontend/FrontendOptions.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/Builtins.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Sema/Sema.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/Type.h"
#include "clang/AST/Decl.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/Ownership.h"
#include "clang/AST/DeclGroup.h"
#include "clang/Parse/Parser.h"
#include "clang/Parse/ParseAST.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Rewrite/Core/Rewriter.h"
#include "clang/Rewrite/Frontend/Rewriters.h"
using namespace clang;
using namespace std;
// By implementing RecursiveASTVisitor, …Run Code Online (Sandbox Code Playgroud) 将解析树(即具体语法树)简化为抽象语法树的一般策略是什么?
例如,我有以下语法规则:
statement_list : statement
| statement_list statement
Run Code Online (Sandbox Code Playgroud)
如果保留为解析树,它将生成看起来像扇形输出
program
statement_list
statement_list
statement
definition
p_type
assignment
statement
definition
statement
assign
assignment
Run Code Online (Sandbox Code Playgroud)
如果我连接每个节点的子节点(因为语句列表在解析后没有固有含义),我可以实现以下内容
program
definition
p_type
assignment
definition
assign
assignment
Run Code Online (Sandbox Code Playgroud)
这很好用 - 但是,我没有意识到这样做的任何"规则".是否有特定的语法规则我应该简化?这是一种感觉问题,还是一个更机械化的过程?
compiler-construction grammar parsing abstract-syntax-tree concrete-syntax-tree
我正在尝试了解有关OCaml扩展点的更多信息,并且我无法跟踪AST中记录类型的表示.
我在这篇博客文章中窃取了以下示例:
http://whitequark.org/blog/2014/04/16/a-guide-to-extension-points-in-ocaml/
使用源文件(foo.ml):
let _ = [%getenv "USER"]
Run Code Online (Sandbox Code Playgroud)
并输出ocamlc -dparsetree fool.ml:
[
structure_item (test.ml[1,0+0]..[1,0+24])
Pstr_eval
expression (test.ml[1,0+8]..[1,0+24])
Pexp_extension "getenv"
[
structure_item (test.ml[1,0+17]..[1,0+23])
Pstr_eval
expression (test.ml[1,0+17]..[1,0+23])
Pexp_constant Const_string("USER",None)
]
]
Run Code Online (Sandbox Code Playgroud)
从asttypes.mli和parsetree.mli我可以遵循该行的解析树模式匹配
Pexp_constant Const_string("USER",None)
Run Code Online (Sandbox Code Playgroud)
但是,当解析树表示记录类型时,我无法再跟踪发生的情况.似乎记录字段的表示顺序与它们在类型定义中出现的顺序不同,并且解析树中不需要(或显示)所有字段.
来自parsetree.mli:
type expression = {
pexp_desc: expression_desc;
pexp_loc: Location.t;
pexp_attributes: attributes;
}
Run Code Online (Sandbox Code Playgroud)
解析树输出似乎只显示位置和有效负载,但我可能读错了.
如何正确读取记录类型的AST?对于类型表达式应该是:
(* record type declaration and pexp_loc field *)
expression (test.ml[1,0+8]..[1,0+24])
(* pexp_desc field *)
Pexp_extension "getenv"
[
...
]
Run Code Online (Sandbox Code Playgroud) 使用这样的代码:
var remarkAbstract = require("remark");
var remark = remarkAbstract();
let remark = remarkAbstract();
var ast = remark.process(input);
Run Code Online (Sandbox Code Playgroud)
但它返回输出,如:
AssertionError: VFile {
contents: '# header\n\n20 December 2012\n\n\n\ncontent1\n\ncontent2\n\n## header2\n',
messages: =
Run Code Online (Sandbox Code Playgroud)
我想获得AST树这样
ast模块的文档解释了如何使用NodeTransformer类替换AST中的节点,但没有解释如何将新节点插入树中.
例如,给定此模块:
import foo
import bar
class Baz(object):
def spam(self):
pass
Run Code Online (Sandbox Code Playgroud)
我想添加另一个导入,并设置一个类变量Baz.
如何创建这些节点并将其插入AST?