Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
2
2022fall-Compiler_CMinus
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
6
Merge Requests
6
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
李晓奇
2022fall-Compiler_CMinus
Commits
78e208f5
You need to sign in or sign up before continuing.
Commit
78e208f5
authored
Oct 28, 2022
by
李晓奇
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of 202.38.79.174:compiler_staff/2022fall-compiler_cminus
parents
5b1dfa22
49c4e204
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
109 additions
and
85 deletions
+109
-85
Documentations/common/cminusf.md
Documentations/common/cminusf.md
+95
-78
Reports/3-ir-gen/report.md
Reports/3-ir-gen/report.md
+6
-0
src/cminusfc/cminusfc.cpp
src/cminusfc/cminusfc.cpp
+8
-7
No files found.
Documentations/common/cminusf.md
View file @
78e208f5
...
@@ -34,14 +34,15 @@
...
@@ -34,14 +34,15 @@
30.
$
`\text{args} \rightarrow \text{arg-list}\ |\ \text{empty}`
$
30.
$
`\text{args} \rightarrow \text{arg-list}\ |\ \text{empty}`
$
31.
$
`\text{arg-list} \rightarrow \text{arg-list}\ \textbf{,}\ \text{expression}\ |\ \text{expression}`
$
31.
$
`\text{arg-list} \rightarrow \text{arg-list}\ \textbf{,}\ \text{expression}\ |\ \text{expression}`
$
## cminus-f 的语义
## cminus-f 的语义
在上述语法规则中,我们定义了
`cminus-f`
语言的语法,接着,我们对照语法规则,给出相关的语义和解释。
在上述语法规则中,我们定义了
`cminus-f`
语言的语法,接着,我们对照语法规则,给出相关的语义和解释。
在阅读前,需要理解
`cminus-f`
主要源自于 C 语言,因此它的行为都会接近 C 语言。
在阅读前,需要理解
`cminus-f`
主要源自于 C 语言,因此它的行为都会接近 C 语言。
1.
$
`\text{program} \rightarrow \text{declaration-list}`
$
1.
$
`\text{program} \rightarrow \text{declaration-list}`
$
2.
$
`\text{declaration-list} \rightarrow \text{declaration-list}\ \text{declaration}\ |\ \text{declaration}`
$
2.
$
`\text{declaration-list} \rightarrow \text{declaration-list}\ \text{declaration}\ |\ \text{declaration}`
$
3.
$
`\text{declaration} \rightarrow \text{var-declaration}\ |\ \text{fun-declaration}`
$
3.
$
`\text{declaration} \rightarrow \text{var-declaration}\ |\ \text{fun-declaration}`
$
一个
`程序`
由一系列
`声明`
组成,声明包括了
`函数声明`
与
`变量声明`
,它们可以以任意顺序排列。
一个
`程序`
由一系列
`声明`
组成,声明包括了
`函数声明`
与
`变量声明`
,它们可以以任意顺序排列。
...
@@ -55,6 +56,7 @@
...
@@ -55,6 +56,7 @@
因为没有原型这个概念,
`cminus-f`
不区分函数的声明和定义。
因为没有原型这个概念,
`cminus-f`
不区分函数的声明和定义。
4.
$
`\text{var-declaration}\ \rightarrow \text{type-specifier}\ \textbf{ID}\ \textbf{;}\ |\ \text{type-specifier}\ \textbf{ID}\ \textbf{[}\ \textbf{INTEGER}\ \textbf{]}\ \textbf{;}`
$
4.
$
`\text{var-declaration}\ \rightarrow \text{type-specifier}\ \textbf{ID}\ \textbf{;}\ |\ \text{type-specifier}\ \textbf{ID}\ \textbf{[}\ \textbf{INTEGER}\ \textbf{]}\ \textbf{;}`
$
5.
$
`\text{type-specifier} \rightarrow \textbf{int}\ |\ \textbf{float}\ |\ \textbf{void}`
$
5.
$
`\text{type-specifier} \rightarrow \textbf{int}\ |\ \textbf{float}\ |\ \textbf{void}`
$
`cminus-f`
的基础类型只有整型(
`int`
)、浮点型(
`float`
)和
`void`
。而在变量声明中,只有整型和浮点型可以使用,
`void`
仅用于函数声明。
`cminus-f`
的基础类型只有整型(
`int`
)、浮点型(
`float`
)和
`void`
。而在变量声明中,只有整型和浮点型可以使用,
`void`
仅用于函数声明。
...
@@ -66,8 +68,11 @@
...
@@ -66,8 +68,11 @@
一次只能声明一个变量。
一次只能声明一个变量。
6.
$
`\text{fun-declaration} \rightarrow \text{type-specifier}\ \textbf{ID}\ \textbf{(}\ \text{params}\ \textbf{)}\ \text{compound-stmt}`
$
6.
$
`\text{fun-declaration} \rightarrow \text{type-specifier}\ \textbf{ID}\ \textbf{(}\ \text{params}\ \textbf{)}\ \text{compound-stmt}`
$
7.
$
`\text{params} \rightarrow \text{param-list}\ |\ \textbf{void}`
$
7.
$
`\text{params} \rightarrow \text{param-list}\ |\ \textbf{void}`
$
8.
$
`\text{param-list} \rightarrow \text{param-list}\ ,\ \text{param}\ |\ \text{param}`
$
8.
$
`\text{param-list} \rightarrow \text{param-list}\ ,\ \text{param}\ |\ \text{param}`
$
9.
$
`\text{param} \rightarrow \text{type-specifier}\ \textbf{ID}\ |\ \text{type-specifier}\ \textbf{ID}\ \textbf{[]}`
$
9.
$
`\text{param} \rightarrow \text{type-specifier}\ \textbf{ID}\ |\ \text{type-specifier}\ \textbf{ID}\ \textbf{[]}`
$
`函数声明`
包含了返回类型,标识符,由逗号分隔的
`形参`
列表,还有一个
`复合语句`
。
`函数声明`
包含了返回类型,标识符,由逗号分隔的
`形参`
列表,还有一个
`复合语句`
。
...
@@ -93,11 +98,13 @@
...
@@ -93,11 +98,13 @@
`局部声明`
拥有和
`复合语句`
中的
`语句列表`
一样的作用域,且其优先级高于任何同名的全局声明(常见的静态作用域)
`局部声明`
拥有和
`复合语句`
中的
`语句列表`
一样的作用域,且其优先级高于任何同名的全局声明(常见的静态作用域)
11.
$
`\text{local-declarations} \rightarrow \text{local-declarations var-declaration}\ |\ \text{empty}`
$
11.
$
`\text{local-declarations} \rightarrow \text{local-declarations var-declaration}\ |\ \text{empty}`
$
12.
$
`\text{statement-list} \rightarrow \text{statement-list}\ \text{statement}\ |\ \text{empty}`
$
12.
$
`\text{statement-list} \rightarrow \text{statement-list}\ \text{statement}\ |\ \text{empty}`
$
`局部声明`
和
`语句列表`
都可以为空(empty表示空字符串,即$
`\varepsilon`
$)
`局部声明`
和
`语句列表`
都可以为空(empty表示空字符串,即$
`\varepsilon`
$)
13.
$
`\begin{aligned}\text{statement} \rightarrow\ &\text{expression-stmt}\\ &|\ \text{compound-stmt}\\ &|\ \text{selection-stmt}\\ &|\ \text{iteration-stmt}\\ &|\ \text{return-stmt}\end{aligned}`
$
13.
$
`\begin{aligned}\text{statement} \rightarrow\ &\text{expression-stmt}\\ &|\ \text{compound-stmt}\\ &|\ \text{selection-stmt}\\ &|\ \text{iteration-stmt}\\ &|\ \text{return-stmt}\end{aligned}`
$
14.
$
`\text{expression-stmt} \rightarrow \text{expression}\ \textbf{;}\ |\ \textbf{;}`
$
14.
$
`\text{expression-stmt} \rightarrow \text{expression}\ \textbf{;}\ |\ \textbf{;}`
$
`表达式语句`
由一个可选的
`表达式`
(即可以没有
`表达式`
)和一个分号组成
`表达式语句`
由一个可选的
`表达式`
(即可以没有
`表达式`
)和一个分号组成
...
@@ -123,6 +130,7 @@
...
@@ -123,6 +130,7 @@
`return`
会将程序的控制转移给当前函数的调用者,而$
`\textbf{main}`
$函数的
`return`
会使得程序终止
`return`
会将程序的控制转移给当前函数的调用者,而$
`\textbf{main}`
$函数的
`return`
会使得程序终止
18.
$
`\text{expression} \rightarrow \text{var}\ \textbf{=}\ \text{expression}\ |\ \text{simple-expression}`
$
18.
$
`\text{expression} \rightarrow \text{var}\ \textbf{=}\ \text{expression}\ |\ \text{simple-expression}`
$
19.
$
`\text{var} \rightarrow \textbf{ID}\ |\ \textbf{ID}\ \textbf{[}\ \text{expression} \textbf{]}`
$
19.
$
`\text{var} \rightarrow \textbf{ID}\ |\ \textbf{ID}\ \textbf{[}\ \text{expression} \textbf{]}`
$
一个
`表达式`
可以是一个变量引用(即
`var`
)接着一个赋值符号(=)以及一个表达式,也可以是一个
`简单表达式`
。
一个
`表达式`
可以是一个变量引用(即
`var`
)接着一个赋值符号(=)以及一个表达式,也可以是一个
`简单表达式`
。
...
@@ -138,10 +146,15 @@
...
@@ -138,10 +146,15 @@
在
`C`
中,赋值对象(即
`var`
)必须是左值,而左值可以通过多种方式获得。
`cminus-f`
中,唯一的左值就是通过
`var`
的语法得到的,因此
`cminus-f`
通过语法限制了
`var`
为左值,而不是像
`C`
中一样通过类型检查,这也是为什么
`cminus-f`
中不允许进行指针算数。
在
`C`
中,赋值对象(即
`var`
)必须是左值,而左值可以通过多种方式获得。
`cminus-f`
中,唯一的左值就是通过
`var`
的语法得到的,因此
`cminus-f`
通过语法限制了
`var`
为左值,而不是像
`C`
中一样通过类型检查,这也是为什么
`cminus-f`
中不允许进行指针算数。
20.
$
`\text{simple-expression} \rightarrow \text{additive-expression}\ \text{relop}\ \text{additive-expression}\ |\ \text{additive-expression}`
$
20.
$
`\text{simple-expression} \rightarrow \text{additive-expression}\ \text{relop}\ \text{additive-expression}\ |\ \text{additive-expression}`
$
21.
$
`\text{relop}\ \rightarrow \textbf{<=}\ |\ \textbf{<}\ |\ \textbf{>}\ |\ \textbf{>=}\ |\ \textbf{==}\ |\ \textbf{!=}`
$
21.
$
`\text{relop}\ \rightarrow \textbf{<=}\ |\ \textbf{<}\ |\ \textbf{>}\ |\ \textbf{>=}\ |\ \textbf{==}\ |\ \textbf{!=}`
$
22.
$
`\text{additive-expression} \rightarrow \text{additive-expression}\ \text{addop}\ \text{term}\ |\ \text{term}`
$
22.
$
`\text{additive-expression} \rightarrow \text{additive-expression}\ \text{addop}\ \text{term}\ |\ \text{term}`
$
23.
$
`\text{addop} \rightarrow \textbf{+}\ |\ \textbf{-}`
$
23.
$
`\text{addop} \rightarrow \textbf{+}\ |\ \textbf{-}`
$
24.
$
`\text{term} \rightarrow \text{term}\ \text{mulop}\ \text{factor}\ |\ \text{factor}`
$
24.
$
`\text{term} \rightarrow \text{term}\ \text{mulop}\ \text{factor}\ |\ \text{factor}`
$
25.
$
`\text{mulop} \rightarrow \textbf{*}\ |\ \textbf{/}`
$
25.
$
`\text{mulop} \rightarrow \textbf{*}\ |\ \textbf{/}`
$
一个
`简单表达式`
是一个
`加法表达式`
或者两个
`加法表达式`
的关系运算。当它是
`加法表达式`
时,它的值就是
`加法表达式`
的值。而当它是关系运算时,如果关系运算结果为真则值为整型值 1,反之则值为整型值 0。
一个
`简单表达式`
是一个
`加法表达式`
或者两个
`加法表达式`
的关系运算。当它是
`加法表达式`
时,它的值就是
`加法表达式`
的值。而当它是关系运算时,如果关系运算结果为真则值为整型值 1,反之则值为整型值 0。
...
@@ -155,9 +168,13 @@
...
@@ -155,9 +168,13 @@
`因数`
可以是一个括号包围的
`表达式`
(此时它的值是
`表达式`
的值),或者是一个
`变量`
(此时它的值是
`变量`
的值),或者是一个
`函数调用`
(此时它的值是
`函数调用`
的返回值),或者是一个
`数字字面量`
(此时它的值为该字面量的值)。当
`因数`
是数组变量时,除非此时它被用作一个
`函数调用`
中的数组参数,否则它必须要带有下标。
`因数`
可以是一个括号包围的
`表达式`
(此时它的值是
`表达式`
的值),或者是一个
`变量`
(此时它的值是
`变量`
的值),或者是一个
`函数调用`
(此时它的值是
`函数调用`
的返回值),或者是一个
`数字字面量`
(此时它的值为该字面量的值)。当
`因数`
是数组变量时,除非此时它被用作一个
`函数调用`
中的数组参数,否则它必须要带有下标。
27.
$
`\text{integer} \rightarrow \textbf{INTEGER}`
$
27.
$
`\text{integer} \rightarrow \textbf{INTEGER}`
$
28.
$
`\text{float} \rightarrow \textbf{FLOATPOINT}`
$
28.
$
`\text{float} \rightarrow \textbf{FLOATPOINT}`
$
29.
$
`\text{call} \rightarrow \textbf{ID}\ \textbf{(}\ \text{args} \textbf{)}`
$
29.
$
`\text{call} \rightarrow \textbf{ID}\ \textbf{(}\ \text{args} \textbf{)}`
$
30.
$
`\text{args} \rightarrow \text{arg-list}\ |\ \text{empty}`
$
30.
$
`\text{args} \rightarrow \text{arg-list}\ |\ \text{empty}`
$
31.
$
`\text{arg-list} \rightarrow \text{arg-list}\ \textbf{,}\ \text{expression}\ |\ \text{expression}`
$
31.
$
`\text{arg-list} \rightarrow \text{arg-list}\ \textbf{,}\ \text{expression}\ |\ \text{expression}`
$
`函数调用`
由一个函数的
`标识符`
与一组括号包围的
`实参`
组成。
`实参`
可以为空,也可以是由逗号分隔的的
`表达式`
组成的列表,这些表达式代表着函数调用时,传给
`形参`
的值。
`函数调用时`
的
`实参`
数量和类型必须与
`函数声明`
中的
`形参`
一致,必要时需要进行类型转换。
`函数调用`
由一个函数的
`标识符`
与一组括号包围的
`实参`
组成。
`实参`
可以为空,也可以是由逗号分隔的的
`表达式`
组成的列表,这些表达式代表着函数调用时,传给
`形参`
的值。
`函数调用时`
的
`实参`
数量和类型必须与
`函数声明`
中的
`形参`
一致,必要时需要进行类型转换。
...
@@ -176,10 +193,10 @@ void neg_idx_except(void) {...}
...
@@ -176,10 +193,10 @@ void neg_idx_except(void) {...}
*
`outputFloat`
函数接受一个浮点参数,然后将它的值打印到标准输出,并输出换行符。
*
`outputFloat`
函数接受一个浮点参数,然后将它的值打印到标准输出,并输出换行符。
*
`neg_idx_except`
函数没有形参,执行后报错并退出
*
`neg_idx_except`
函数没有形参,执行后报错并退出
除此之外,其它规则和 C 中类似,比如同一个作用域下不允许定义重名变量或函数(本次实验中不做要求)
除此之外,其它规则和 C 中类似,比如同一个作用域下不允许定义重名变量或函数(本次实验中不做要求)
## 提醒与补充
## 提醒与补充
1.
本次实验存在五种情况下的类型转换
1.
本次实验存在五种情况下的类型转换
*
赋值时
*
赋值时
*
返回值类型和函数签名中的返回类型不一致时
*
返回值类型和函数签名中的返回类型不一致时
...
...
Reports/3-ir-gen/report.md
View file @
78e208f5
...
@@ -135,6 +135,12 @@ PB20111654 李晓奇
...
@@ -135,6 +135,12 @@ PB20111654 李晓奇
后来发这里其实并没有问题,如果有返回值,在if或者else内部就返回了,并不会跳出去被默认返回扰乱。
后来发这里其实并没有问题,如果有返回值,在if或者else内部就返回了,并不会跳出去被默认返回扰乱。
-
最后一个测试文件能够正常执行,但是输出有错,
发现一个好的debug方法:
利用裁剪定位问题,即注释掉一部分,分别利用clang、cminusfc生成可执行文件,查看输出是否一致。
## 实验设计
## 实验设计
请写明为了顺利完成本次实验,加入了哪些亮点设计,并对这些设计进行解释。
请写明为了顺利完成本次实验,加入了哪些亮点设计,并对这些设计进行解释。
...
...
src/cminusfc/cminusfc.cpp
View file @
78e208f5
...
@@ -104,17 +104,18 @@ int main(int argc, char **argv) {
...
@@ -104,17 +104,18 @@ int main(int argc, char **argv) {
output_stream
.
close
();
output_stream
.
close
();
if
(
!
emit
)
{
if
(
!
emit
)
{
std
::
string
lib_path
=
argv
[
0
];
std
::
string
lib_path
=
argv
[
0
];
lib_path
.
erase
(
lib_path
.
rfind
(
'/'
))
+=
"/libcminus_io.a"
;
auto
idx
=
lib_path
.
rfind
(
'/'
);
auto
command_string
=
"clang -O0 -w "
s
+
target_path
+
".ll -o "
+
target_path
+
" "
+
lib_path
;
if
(
idx
!=
std
::
string
::
npos
)
std
::
cout
<<
command_string
<<
std
::
endl
;
lib_path
.
erase
(
lib_path
.
rfind
(
'/'
));
int
re_code0
=
std
::
system
(
command_string
.
c_str
());
auto
cmd_str
=
"clang -O0 -w "
s
+
target_path
+
".ll -o "
+
target_path
+
" -L"
+
lib_path
+
" -lcminus_io"
;
command_string
=
"rm "
s
+
target_path
+
".ll"
;
std
::
cout
<<
cmd_str
<<
std
::
endl
;
int
re_code1
=
std
::
system
(
command_string
.
c_str
());
int
re_code0
=
std
::
system
(
cmd_str
.
c_str
());
cmd_str
=
"rm "
s
+
target_path
+
".ll"
;
int
re_code1
=
std
::
system
(
cmd_str
.
c_str
());
if
(
re_code0
==
0
&&
re_code1
==
0
)
if
(
re_code0
==
0
&&
re_code1
==
0
)
return
0
;
return
0
;
else
else
return
1
;
return
1
;
}
}
return
0
;
return
0
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment