LLVM clang flex bison

最近在研究android recovery实现原理的时候,脚本语言edify的解析原理updater-script不是很清楚,只知道大概的意思,定义一些规则,支持的方法以及属性,但是无法将具体的实现串连起来。

通过在网上查阅资料,发现是通过现有的flex bison框架来实现,记录一下。

官方文档关于edify的一些主要特性说明

  • 整个脚本文件文件是单个表达式

  • 所有表达式是字符串

  • 字符串文字用双引号引起来。 \ n,\ t,\“和\,以及\ , x4a之类的十六进制转义字符都可以支持。
    仅由字母,数字,冒号,下划线,斜杠和句点组成的字符串文字不需要用双引号引起来。

  • 如下单词作为关键字保留,

if then else endif
如果没有被双引号包起来,则有特殊含义;在双引号里面,则只是普通的字符串

  • 当使用boolean类型的时候,空字符串是false,所有其它字符串是true
  • 所有函数实际上都是宏(在Lisp的意义上); 函数主体可以控制要评估的参数(如果有)。 这意味着方法可以充当控制结构。
  • 运算符(例如“ &&”和“ ||”)只是内置函数的语法糖,因此它们也可以充当控制结构
  • “;” 是二进制运算符; 评估它意味着首先评估左侧,然后评估右侧。 它也可以出现在任何表达式之后。
  • 注释以“#”开头,并一直到行尾。
expr.cpp

bootable/recovery/edify/expr.cpp
文件里面定义了支持的关键字,

void RegisterBuiltins() {
    RegisterFunction("ifelse", IfElseFn);
    RegisterFunction("abort", AbortFn);
    RegisterFunction("assert", AssertFn);
    RegisterFunction("concat", ConcatFn);
    RegisterFunction("is_substring", SubstringFn);
    RegisterFunction("stdout", StdoutFn);
    RegisterFunction("sleep", SleepFn);

    RegisterFunction("less_than_int", LessThanIntFn);
    RegisterFunction("greater_than_int", GreaterThanIntFn);
}
parser.yy

bootable/recovery/edify/parser.yy 定义了解析脚本文件的流程,对外提供ParseString接口

int ParseString(const std::string& str, std::unique_ptr<Expr>* root, int* error_count) {
  yy_switch_to_buffer(yy_scan_string(str.c_str()));
  return yyparse(root, error_count);
}
#### lexer.ll

bootable/recovery/edify/lexer.ll 对脚本文件进行脚本语法解析

以下内容来源于维基百科

flex 和 bison

Lex是1975年由Mike Lesk和当时尚在AT&T实习的Eric Schmidt共同完成的(Schmidt做的更多),是一个词法分析器的生成程序,可以单独使用也可以与Johnson的yacc协同工作。lex很有名气,但是无奈效率太低加上有bug。大概在1987年,Lawrence Berkeley实验室的Vern Paxson用C重新写了Lex,并命名为FLex(the Fast Lexical Analyzer Generator),基于伯克利许可证。flex现在是SourceForge的一个项目,依然基于伯克利许可,
Flex 是起初unix版lex的free (but non-GNU) implementation,用于c/c ++ 的词法扫描生成器。

bison的前身是yacc。yacc是由贝尔实验室的S.C.Johnson基于Knuth大神的LR语法分析理论,于1975~1978年写成。大约1985年,UC Berkeley 的研究生Bob Corbett使用改进的内部算法实现了伯克利yacc,来自FSF的Richard Stallman改写了伯克利yacc并将其用于GNU项目,添加了很多特性,形成了今天的GNU Bison。bison现在作为FSF的项目被维护,基于GNU公共许可证发布,Bison是兼容yacc的free的语法生成器。

早期Unix的Lex/YACC,发展为FLex/Bison,新版本的程序是向上兼容的(即兼容老版本),现常用Flex和Bison。

LLVM 和 clang

LLVM 包括了两个概念:一个广义的 LLVM 和一个狭义的 LLVM 。

  • 广义的 LLVM 指的是一个完整的 LLVM编译器框架系统,包括了前端、优化器、后端、众多的库函数以及很多的模块;
  • 狭义的 LLVM 则是聚焦于编译器后端功能的一系列模块和库,包括代码优化、代码生成、JIT 等。

Clang-LLVM

整体的编译器架构就是 LLVM 架构;Clang 大致可以对应到编译器的前端,主要处理一些和具体机器无关的针对语言的分析操作;编译器的优化器和后端部分就是之前提到的 LLVM 后端,即狭义的 LLVM。

此外,由于 LLVM 的命名最早源自于底层虚拟机(Low Level Virtual Machine) 的首字母缩写,但这个项目的范围并不局限于创建一个虚拟机,这个缩写导致了大量的疑惑。LLVM 成长之后已成为众多编译工具及低级工具技术的统称,使得这个名字变得更不贴切,所以开发者决定放弃这个缩写的涵义,现在 LLVM 已独立成为一个品牌,适用于 LLVM 下的所有项目,包括 LLVM 中介码、LLVM 除错工具、LLVM C++ 标准库等。

自己动手实现一个编程语言

https://github.com/lsegal/my_toy_compiler

https://github.com/shines77/wgtcc

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值