设为首页
收藏本站
切换到窄版
登录
立即注册
找回密码
搜索
搜索
本版
帖子
用户
快捷导航
论坛
BBS
C语言
C++
NET
JAVA
PHP
易语言
数据库
IE盒子
»
论坛
›
IE盒子
›
C++
›
C++代码与AST compiler
返回列表
发帖
查看:
104
|
回复:
0
C++代码与AST compiler
[复制链接]
亦辰不变
亦辰不变
当前离线
积分
15
3
主题
10
帖子
15
积分
新手上路
新手上路, 积分 15, 距离下一级还需 35 积分
新手上路, 积分 15, 距离下一级还需 35 积分
积分
15
发消息
发表于 2023-1-17 10:03:42
|
显示全部楼层
|
阅读模式
C++代码与AST compiler
Compiler3_语法制导翻译&AST
语法制导翻译(Syntax Directed Translation)的任务
解析输入的字符串时,在特定位置执行指定的动作。
基本思想
抽象语法树
分析树与抽象语法树
分析树:
编码了句子的推导过程
但是包含很多不必要的信息,节点占用存储空间
需要知道那些信息是重要的
对于表达式而言,只需要知道运算符和运算数
优先级,结合性等已经在语法分析部分处理掉了
对于语句,函数等其他构造而言也一样
比如,编译器不关心赋值符号是=还是:=
具体语法和抽象语法
:
·
具体语法
是语法分析器使用的语法
必须适合于语法分析,如各种分隔符,消除左递归,提取公因子等
·
抽象语法
是用来表达语法结构的内部表示
现代编译器一般采用抽象语法作为前端(词法/语法分析器)和后端(代码生成)的接口
· 早期的编译器有的不采用抽象语法树数据结构
直接在语法制导翻译中生成代码
· 现代编译器一般都采用抽象语法树作为语法分析器的输出
更好的系统的支持
简化编译器的设计
抽象语法树的自动生成
在语法动作中,加入生成语法树的代码片段
片段一般是语法树的构造函数
在产生式规约的时候,会自底向上构造整棵数
从叶子到根
抽象语法树是编译器前端和后端的接口
程序一旦被转换成抽象语法树,则源代码即被丢弃
后续阶段只处理抽象语法树
所以抽象语法树必须编码足够多的源代码信息
例如,语法结构所在位置(文件、行号、列号等)
觉得自动生成方面LL比LR好,自顶向下更符合人类认知,代表生成器:antlr
Cppinsights: C++的见解——用编译器的眼睛查看源代码
Contents
· What
· Why
· Building
· Usage
· Get Involved
· Support
What
C++见解是一种基于CLAN的工具,它可以进行源到源转换。它的目标是让事情变得可见,而这些事情通常是故意发生在幕后的。它是关于编译器为我们所做的神奇的事情。
以这段代码为例:
class Base {
};
class Derived : public Base {
};
int main() {
Derived d;
Base& b = d;
}
没什么特别的,当然是编译的。下面是编译器的视图:
class Base {
/* public: inline constexpr Base() noexcept; */
/* public: inline ~Base(); */
/* public: inline constexpr Base(const Base &); */
/* public: inline constexpr Base(Base &&); */
};
class Derived : public Base {
/* public: inline constexpr Derived() noexcept; */
/* public: inline constexpr Derived(const Derived &); */
/* public: inline constexpr Derived(Derived &&); */
};
int main(){
Derived d;
Base& b = static_cast<Base&>(d);
}
您可以看到编译器提供的所有函数。还有从Derived到Base的向下转换。
我并不是说所有的事情都是对的。这只是我认为足够好的见解的初始版本,可以将其交给公众。请记住,这完全是基于clang及其对AST的理解。
Why
C++见解是一种基于CLAN的工具,它可以进行源到源转换。它的目标是让人们看到那些通常是故意发生在幕后的事情。它是关于编译器为我们所做的神奇的事情。或者查看编译器的类。
不久前,我开始研究一些新的东西,我们用C++ 11,C++ 14和C++ 17得到。像lambdas、range-basedfor-loops和结构化绑定之类的惊人功能。我把它放在一个谈话中。你可以在网上找到幻灯片和视频。
然而,所有的研究和我的一些训练和教学让我开始思考,如果我们能用编译器的眼睛看的话。当然,对于clang至少有一个AST-dump。使用编译器编译器这样的工具,我们可以看到编译器从C++源代码段生成的代码。然而,我们看到的是汇编程序。AST和Compiler Explorer输出都不是我编写代码的语言,因此我最熟悉。另外,当教学生C++显示AST并解释它在那里时,对我来说并不十分令人满意。
我开始编写一个clang-based工具,能够将range-basedfor-loop转换为compiler-internal版本。然后,我对结构化绑定和lambdas做了同样的处理。最后,我按照最初的计划做了很多事情。它显示了调用运算符的位置,以及编译器执行强制转换的位置。C++的见解能够推断出auto或decltype后面的类型。目标是生成可编译的代码。然而,并非所有地方都能做到这一点。
不过,还有工作要做。
我并不是说所有的事情都是对的。这只是C++的见解的最初版本,我认为它足够好,可以将它交给公众。此外,请记住,它是完全基于CLAN和我的理解C++和AST。
例如,您可以看到lamda、range-basedfor-loop或auto的转换。当然,您可以转换任何其他C++片段。
看到你自己,C++的见解是在线可获得的:http://cppinsights.io公司.
Building
C++的洞察力可以在clang-source树或外部构建。
在Windows上构建
See Readme_Windows.md
在Arch Linux上构建
要使用extra/clang生成,请使用以下额外的标志:-DINSIGHTS_USE_SYSTEM_INCLUDES=off -DCLANG_LINK_CLANG_DYLIB=on -DLLVM_LINK_LLVM_DYLIB=on
关于INSIGHTS_USE_SYSTEM_INCLUDES需要关闭的解释,请参见https://github.com/andreasfertig/cppinsights/issues/186。
extra/clang和extra/llvm提供/usr/lib/{libclangAST.so,libLLVM*.a,libLLVM.so}。libclangAST.so需要libLLVM.so,如果libLLVM*.a(而不是libLLVM.so)链接,则会发生冲突。见https://bugs.archlinux.org/task/60512
外面的建筑叮当作响
需要在搜索路径中安装clang。
git clone https://github.com/andreasfertig/cppinsights.git
mkdir build && cd build
cmake -G&#34;Ninja&#34; ../cppinsights
ninja
生成的二进制文件(insights)可以在build-folder中找到。
建筑内部叮当作响
对于在clang-source树中构建它,假设您已经准备好了source-tree:
cd llvm/tools/clang/tools/extra
git clone https://github.com/andreasfertig/cppinsights.git
echo &#34;add_subdirectory(cppinsights)&#34; >> CMakeLists.txt
然后像平常一样发出叮当声。
cmake options
有几个选项可以通过cmake启用:
Option
Description
Default
INSIGHTS_STRIP
构建后剥离细节
ON
INSIGHTS_STATIC
使用静态链接
OFF
INSIGHTS_COVERAGE
启用代码覆盖率
OFF
INSIGHTS_USE_LIBCPP
使用libc++进行测试
OFF
DEBUG
Enable debug
OFF
与Ceevelop一起使用
git clone https://github.com/andreasfertig/cppinsights.git
mkdir build_eclipse
cd build_eclipse
cmake -G&#34;Eclipse CDT4 - Unix Makefiles&#34; ../cppinsights/
然后在cedevelopimport->General->Existing Project into Workspace。选择build_eclipse。享受与Cevelop编辑。
Usage
使用C++的见解相当简单:
insights <YOUR_CPP_FILE> -- -std=c++17
当涉及到系统包括路径时,事情变得复杂起来。二进制中有路径hard-coded,似乎来自编译器C++的见解。来帮助你完成检查脚本/getinclude.py. 它尝试从编译器收集系统包含路径。如果没有使用g++的选项,也可以将另一个编译器作为第一个参数传递。
下面是一个例子:
./scripts/getinclude.py
-isystem/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1 -isystem/usr/local/include -isystem/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/7.3.0/include -isystem/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include -isystem/usr/include
该脚本可以与C++的见解一起使用:
insights <YOUR_CPP_FILE> -- -std=c++17 `./scripts/getinclude.py`
还有一个GITHUB项目,它设置了一个docker容器,其中包含了最新的C++透视版:C++见解-Docker。
Compatibility
目前,支持clang的最新稳定版本以及当前的开发分支。
ToDo&#39;s
See TODO.
Get Involved
· 通过提交GitHub问题来报告错误/问题。
· 使用拉取请求提交稿件。
参考文献了解
https://www.kirito.info/compiler3-syntax-directed-translation-and-ast/
https://www.5axxw.com/wiki/content/bp9kmi
回复
使用道具
举报
返回列表
发帖
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
立即注册
本版积分规则
发表回复
回帖后跳转到最后一页
浏览过的版块
NET
快速回复
返回顶部
返回列表