alda一个有趣的软件
考核标准:课程实验 75% 10-12次实验 + 一次选做实验(5分) 期末测试 25% 开卷和平时题型百分之八十相同
antlr + LLVM
推荐书:...... LLVM Cookbook
DonaldE.Knuth(1938~)算法分析之父计算机排版系统Tex的创始人 30天写了一 个编译器
理解计算机系统结构:第一次作业:Crash Course Computer Science 计算机科学速成 课 p1-p9 作业提交就随便写点东西就行。
LTA 机器证明语言 TikZ Graphviz 画图语言 LaTex 排版语言
IR : Intermediate Representation 中间表示
前端(分析阶段):分析源语言程序,搜集所有必要的信息
后端(综合阶段):利用收集到的信息,生成目标语言程序
Clang 编译器比gcc更加现代好用
2023.3.1
clang c发k的音 lang 发烂
clang f.c -of
生成中间代码clang -emit-llvm -S(人类易于阅读) f.c -o f-opt1.ll -o1(编译时开启一级优化)
中间代码:br:branch if分支
不开优化:严格按照br执行
开了优化:int a = 2, int b = 3 if(b > a){} ------> 其实编译器可以看出3一定大于 2,所以不需要if的br,直接执行{}内的东西就行了
编译器的大部分时间是优化
clang-Xclang -ast-dump naming.c
ast:抽象语法树
2023.3.1/3.8
词法分析:antlr4
词法单元的规约
三种类别
●词法分析器生成器 ANTLR
●手写词法分析器
●自动化词法分析器:手写生成词法分析器的工具本身
3、输入:词法单元的规约输出:词法分析器 lexer词法分析程序
.g4 ---> ANTLR4 --->SimpleExprLexer.java SimpleExpr.token
语法:
grammar SimpleExpr; 给语法起一个名字,需与文件名一致
@hearder{package simpleexpr;} (生成的文件存到simpleexpr这个包)
prog : stat* EOF; (结束符)(0或任意多语句构成语法)
stat : expr ';'| ID '=' expr ';' | 'if' expr ';' ;(语句是怎么构成的)(表达式加分号或者赋值语句或者if语句)
expr : expr ('+' | '-' | '*'| '/' ) expr
| '(' expr ')'
| ID
| INT
| FLOAT ;(表达式是两个表达式加减乘除构成或者表达式外有括号或者ID或者整数)(想要表达加减乘除优先级不一样就把* 和 / 放在 + 和 -的上一行)
SEMI : ‘;’(给字面量生成名字,插件generate,可以直接插入,d按时有时候会有类似assign被取成equal的情况)(自动生成插入的位置很关键,优先级需要考虑,if与ID)
词法单元:
表示文法:小写;表示词法:大写;
ID : [a-zA-Z_ ][a-zA-Z0-9_ ] * ; (放在中括号【】中表示可以是azAZ或_中的一种)(以数字字母下划线结尾)
INT : ‘0’ | [1-9][0-9]* ;
WS : [ \t\r\n]+ -> skip ; (+表示一个或多个)(?表示0次或者1次)(skip表示丢掉,不交给编译器分析)
(提取ID和INT后的成分)
fragment DIGIT : [0-9] (fragment表示仅仅作为辅助规则)
fragment LETTER : [a-zA-Z]
ID : (LETTER | '_') (LETTER | DIGIT | '_')* ;
INT : '0' | [1-9] DIGIT* ;
FLOAT : INT '.' DIGIT* | '.'DIGIT+ ;(小数点前有数字则小数点后有没有数字不重要,小数点前没有数字则小数点后面必须有数字)(3.1415没有被识别为INT是因为ANTLR优先匹配最长匹配,先看整体再看局部,再看优先级匹配)
WS : [ \t\r\n]+ -> skip ;
SL_COMMENT (单行注释): ‘//’ .*?(任意多个字符)‘\n’-> skip;
SL_COMMENT (单行注释): ‘//’~[\n]*‘\n’-> skip;
.* 贪婪匹配,能匹配尽可能多就尽可能多
.*? 非贪婪匹配:匹配最短的
~[] 除某些字符之外的其他字符
DOC——COMMENT : ‘/**’ .*? ‘*/’ -> skip;
优先级必须比ML_COMMENT高,否则会被识别为多行注释
如果有一条规则是特例,那必须放到通例的前面
if没有被识别为ID是因为字面量词法单元和符号化词法单元(ID)优先级更高
ML_COMMENT (多行注释) : ‘/*’ .*? ‘*/’ -> skip;
测试test:
ANTLR Preview
右击prog,选择test-prog
用编程的方式测试、使用ANTLR 4生成的xxxLexer.java:
antlr/grammar-v4仓库中有一些官方的关于词法的文档
2023.3.8
SimpleExprRules.g4
lexer grammar SimpleExprRules:
将语法的部分与词法的部分解耦合
如果词法需要用到,则import SimpleExprRules
手写词法分析器
语言和集合:字母表上定义语言
字母表:有限的符号集合,Σ
串:符号构成的有穷集合, ε表示空串,
语言:给定字母表上一个任意的可数的串的集合,可以通过集合操作构造新的语言
连接:类似笛卡尔积
Kleene闭包:广义的并,类似.g4中的* L*
正闭包:类似+ L+
id:L(L ∪ D)*
正则表达式是语法,正则语言是语义,每个正则表达式对应一个正则语言
正则表达式:
定义:
空
a
(a)
r|s,rs,r*
优先级:() * 连接 |
对应的正则语言:
{空串}
{a}
括号可以去掉,语言一样
|对应并,拼接对应拼接,闭包对应语言上的闭包
例子
匹配三的倍数:
手写词法分析器:
整体框架:
LA(0) : WS(空白符), EOF, ID, INT
LA(1) : IF ELSE ID INT
LA(2) : EQ, NE<>, LT<, GT<=, GE>=
arbitrary LA: