它们是由编译过程的不同阶段产生的吗?或者它们只是同一个东西的不同名称?
compiler-construction compiler-theory terminology abstract-syntax-tree parse-tree
我在编译器设计书中找到了这两个术语,我想知道每个术语代表什么,以及它们是如何不同的.
我在互联网上搜索,发现解析树也称为具体语法树(CST).
我想从一个令牌列表中构造一个AST.我正在编写脚本语言,我已经完成了词法分析部分,但我不知道如何创建AST.所以问题是,我该怎么做这样的事情:
WORD, int
WORD, x
SYMBOL, =
NUMBER, 5
SYMBOL, ;
Run Code Online (Sandbox Code Playgroud)
并将其转换为抽象语法树?最好,我想在没有像ANTLR之类的库那样的情况下这样做,我宁愿自己尝试从头开始.但是,如果这是一项非常复杂的任务,我不介意使用库:)谢谢
我目前正在构建一个用PHP编写的PHP解析器,因为在我之前的问题中没有出现现有的解析器.该分析器本身运作得相当好.
现在很明显,解析器本身没什么用(除了静态分析).我想将转换应用于AST,然后将其编译回源代码.应用转换不是一个问题,普通的访客模式应该这样做.
我目前的问题是如何将AST编译回源代码.我看到基本上有两种可能性:
现在我想专注于1.因为2.似乎很难完成(但如果你有相关的提示,我想听听它们).
但我不确定哪种设计模式可用于编译代码.我看到实现这一点的最简单方法是->compile向所有节点添加一个方法.我在这里看到的缺点是,更改生成的输出的格式非常困难.人们需要更改节点本身才能做到这一点.因此,我正在寻找一个不同的解决方案.
我听说访客模式也可以用于此,但我无法想象它应该如何工作.据我了解访问者模式,你有一些NodeTraverser在所有节点上递归迭代并调用一个->visit方法Visitor.对于节点操作来说这听起来非常有前景,其中该Visitor->visit方法可以简单地更改它传递的Node,但我不知道它如何用于编译.一个显而易见的想法是将节点树从叶子迭代到根,并用源代码替换访问的节点.但这在某种程度上似乎不是一个非常干净的解决方案?
我正在阅读有关AST(抽象语法树)的内容,但我看到的所有示例都使用了以下表达式:
a + b * c
Run Code Online (Sandbox Code Playgroud)
哪个可以用类似lispy的语法表示为:
(+ a (* b c) )
Run Code Online (Sandbox Code Playgroud)
这相当于:
+
/ \
a *
/ \
b c
Run Code Online (Sandbox Code Playgroud)
我的问题是OOPL中一个类的AST会是什么样子?
我天真的尝试是为了这个Java代码:
class Person {
String name;
int age;
public String toString() {
return "name";
}
}
Run Code Online (Sandbox Code Playgroud)
方法是:
;Hand written
(classDeclaration Person
(varDeclaration String name)
(varDeclaration int age )
(funcDeclaration String toString
(return "name")
)
)
Run Code Online (Sandbox Code Playgroud)
但我不太确定我对真正的AST代表有多近或多远.
这取决于我选择的语言.需要多少细节?这些"xyzDeclaraction"是否需要或可能如下:
(Person (String name) (int age))
Run Code Online (Sandbox Code Playgroud)
在哪里可以看到实际编程语言的"真实"表示以了解更多信息.
java compiler-construction programming-languages abstract-syntax-tree
为了更好地理解C++语言和语法的一些细节,我希望能够编写一个小的C++程序,并查看编译器从中生成的AST.
看起来clang过去有这个功能(-emit-asm),但它已经删除了.
今天有一个简单的方法吗?
我正在学习编写一种编程语言的解释器,我读过有关抽象语法树的文章.我知道它们是什么,但我看不出它们的用途.
为什么AST有用?
摘要问题描述:
我看到它的方式,unparsing意味着从AST创建一个令牌流,当再次解析时产生一个相等的AST.
所以 parse(unparse(AST)) = AST持有.
这等于找到一个有效的解析树,它将生成相同的AST.
因此,解析者必须通过所有语法约束所包含的遍历节点找到有效的"路径".这基本上意味着找到AST节点到语法生成规则的有效分配.这通常是一个约束满足问题(CSP),可以通过回溯 O(exp(n))来解决,如解析.
幸运的是,对于解析,这可以使用GLR(或更好地限制语法)在O(n³)中完成.因为AST结构非常接近语法生成规则结构,所以我真的很惊讶看到运行时比解析更糟糕的实现:XText使用ANTLR进行解析和回溯以进行解析.
问题
例1:
Area returns AnyObject -> Pedestrian | Highway
Highway returns AnyObject -> "Foo" Car
Pedestrian returns AnyObject -> "Bar" Bike
Car returns Vehicle -> anyObjectInstance.name="Car"
Bike returns Vehicle -> anyObjectInstance.name="Bike"
Run Code Online (Sandbox Code Playgroud)
所以,如果我有一个AST包含
AnyObject -> AnyObject -> Vehicle [name="Car"] 我知道root可以是Area,我可以解决它
Area -> Highway -> Car
Run Code Online (Sandbox Code Playgroud)
因此(公路|行人)决定取决于子树决策.当一片叶子乍一看是几种类型中的一种时,问题会变得更糟,但必须是特定的一种,以便稍后形成有效路径. …
parsing antlr abstract-syntax-tree xtext constraint-satisfaction
在查看可能的工具后,我需要分析Objective-C静态代码,主要是AST,我发现LLVM中的Clang工具可以转储AST,所以我使用终端使用这个命令测试它:
clang -cc1 -ast-dump ~/SomeTest.m
Run Code Online (Sandbox Code Playgroud)
但我收到这个错误:
In file included from /Users/myusername/SomeTest.m:9:
/Users/myusername/SomeTest.h:9:9: fatal error: 'UIKit/UIKit.h' file not found
#import <UIKit/UIKit.h>
^
typedef __int128_t __int128_t;
typedef __uint128_t __uint128_t;
typedef SEL *SEL;
typedef id id;
typedef Class *Class;
struct __va_list_tag {
unsigned int gp_offset;
unsigned int fp_offset;
void *overflow_arg_area;
void *reg_save_area;
};
typedef struct __va_list_tag __va_list_tag;
typedef __va_list_tag __builtin_va_list[1];
@interface just4testViewController@end
@implementation just4testViewController
- (void) dealloc (CompoundStmt 0x7f86b183b110 </Users/myusername/SomeTest.m:14:1, line:16:1>)
- (void) didReceiveMemoryWarning (CompoundStmt 0x7f86b183b2a0 </Users/myusername/SomeTest.m:19:1, line:24:1>)
- (void) viewDidUnload (CompoundStmt 0x7f86b183b430 …Run Code Online (Sandbox Code Playgroud) parsing code-analysis objective-c clang abstract-syntax-tree
parsing ×3
antlr ×2
java ×2
parse-tree ×2
terminology ×2
c++ ×1
clang ×1
interpreter ×1
lexer ×1
objective-c ×1
php ×1
pygments ×1
xtext ×1