Skip to content

Commit

Permalink
添加了编译原理h的内容
Browse files Browse the repository at this point in the history
  • Loading branch information
kingzevin committed Jan 22, 2018
1 parent 414d500 commit 047ba4b
Show file tree
Hide file tree
Showing 76 changed files with 1,519 additions and 0 deletions.
Binary file not shown.
Binary file not shown.
Binary file not shown.
29 changes: 29 additions & 0 deletions 大三上/编译原理和技术(H)/lab2-pre.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
lab2-预热实验
0.配置环境
在之前实验的基础上,将llvm的路径llvm-install/bin添加到PATH中.
1.人工翻译
通过观察clang -S -emit-llvm输出的结果,推理并理解llvm IR翻译过程.
首先,每个函数对应一个独立的计数过程.每个label占用一个计数值.
一个函数的开始,参数先占据计数变量,之后其实label占用一个,之后存储return值占用一个,之后局部变量等开始占用.
正如上课所讲,每个基本块(BasicBlock)对应没有分支的,顺序的过程.
具体指令有store load add new br等。每个基本块的结束(除了最后一个基本块)都需要一个br指令标志结束.
对于多个return情况,将多个return值都存储在同一个地方,并跳转到最后一个基本块读取return值并返回.
由此,得到了手工翻译的结果.
2.编写gen_fib.cpp
这一步,要求利用IRBuilder编写一个gen_fib.cpp,来构建LLVM IR并打印.
1.首先,要理解通过IRBuilder进行代码生成的系统框架,理解BasicBuilder.这一点可以通过阅读Kaleidoscope的例子来初步理解;
2.其次要清楚我们所需要用到的指令所对应的API.这一点可以通过文档,和VS的AutoComplete功能来推测.
3.另外还要清楚一些运用API的细节,比如如何获得函数参数,如何获得整形常量,如何store,load,align等等.
4.这次还要编写Makefile或者CMakeLists.txt.我都试了一下,发现Makefile在子程序返回的不是0的时候会误报为error,并且终止make,这里我的解决方式是中间通过echo生成一个.sh文件,运行.sh文件来执行lli,输出返回结果.而至于CMakeLists.txt我修改之后爆出了一长串的错误,精力有限,没有继续.希望下次能好好学一下cmake.

3.遇到的问题:
本次实验,我很早开始,没有拖到ddl,是基于上一次实验超时的改变,很好.不过还是遇到了一些意想不到的问题:
```1.实验环境崩溃.
不知是什么原因,ubuntu虚拟机突然在实验过程中磁盘损坏,通过v2v工具也没能修复.
重装新ubuntu之后没更新完再次崩溃.通过磁盘检测工具发现物理磁盘没有损坏,推测是VMware的问题.
在咨询助教之后决定迁移环境到wsl中.还好私钥已备份.
2.阅读文档能力较差.
实验中找了很久INSTRUCTION对应的函数,对应的描述很少,只能通过猜测.这里收李嘉豪同学的启发,知道了IntellliSence对变成效率的重要性,安装了VSCode,VS等.最后由于迁移到了wsl,通过VS写代码,变成效率得到了很大的提升.提升的地方主要体现在IntelliSence和AutoComplete上.
更好的生产工具,意味着更强的生产力.这是我这次试验最大的收获.
同时,文档阅读能力,阅读习惯需要加强.
```
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Compiler at USTC in 2017 Fall

This is a repository to store project toolkit for Compiler class at USTC in 2017 Fall.

[Course homepage](http://staff.ustc.edu.cn/~yuzhang/compiler)

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*
!expr.g4
!expr_calculator.py
!.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
grammar expr;

Identifier: [a-zA-Z_] [a-zA-Z_0-9]*;
Number: [1-9] [0-9]*;
Plus: '+';
Multiply: '*';
WhiteSpace: [ \t\n\r]+ -> skip;

expr: expr Multiply expr # Mult
| expr Plus expr # Plus
| '(' expr ')' # Brac
| Identifier # Id
| Number # Num
;
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
'''Expression recognizer.
Handles expression described in expr.g4.
Grammar file should be compiled by antlr4 with option '-Dlanguage=Python3' before executing this.
Module 'antlr4' is required.
'''
import antlr4
import exprLexer
import exprParser
import exprListener
from typing import Mapping


class Listener(exprListener.exprListener):
'''Listener doing calculation based on recognized input.
'''

def __init__(self, var_value_source: Mapping[str, int]):
self.var_value_source = var_value_source

def exitMult(self, ctx: exprParser.exprParser.MultContext):
ctx.value = ctx.getChild(0).value * ctx.getChild(2).value

def exitNum(self, ctx: exprParser.exprParser.NumContext):
ctx.value = int(str(ctx.getChild(0)))

def exitId(self, ctx: exprParser.exprParser.IdContext):
ctx.value = self.var_value_source[str(ctx.getChild(0))]

def exitPlus(self, ctx: exprParser.exprParser.PlusContext):
ctx.value = ctx.getChild(0).value + ctx.getChild(2).value

def exitBrac(self, ctx: exprParser.exprParser.BracContext):
ctx.value = ctx.getChild(1).value


class LazyInputDict(dict):
'''A lazy dictionary asking for input when a new item is queried.'''

def __getitem__(self, key):
try:
return dict.__getitem__(self, key)
except KeyError:
self[key] = int(
input('Please enter value for variable \'{}\': '.format(key)))
return dict.__getitem__(self, key)


if __name__ == '__main__':
PARSER = exprParser.exprParser(antlr4.CommonTokenStream(exprLexer.exprLexer(
antlr4.InputStream(input('Please enter a expression: ')))))
PARSER.addParseListener(Listener(LazyInputDict()))
print(PARSER.expr().value)
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
cmake_minimum_required(VERSION 3.5)

add_definitions(-DFULL_IMPL)

list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)

# compiler must be 11 or 14
set(CMAKE_CXX_STANDARD 14)

# set variable pointing to the antlr tool that supports C++
set(ANTLR4CPP_JAR_LOCATION "NOT-FOUND" CACHE STRING "ANTLR v4 JAR file location. Used by antlr4cpp.")

# add external build for antlrcpp
include(ExternalAntlr4Cpp)

# add antrl4cpp artifacts to project environment
include_directories(${ANTLR4CPP_INCLUDE_DIRS})
link_directories(${ANTLR4CPP_LIBS})
message(STATUS "Found antlr4cpp libs: ${ANTLR4CPP_LIBS} and includes: ${ANTLR4CPP_INCLUDE_DIRS} ")

# Call macro to add lexer and grammar to your build dependencies.
antlr4cpp_process_grammar(c1_recognizer c1_recognizer
${CMAKE_CURRENT_SOURCE_DIR}/grammar/C1Lexer.g4
${CMAKE_CURRENT_SOURCE_DIR}/grammar/C1Parser.g4)

include(ExternalProject)
ExternalProject_Add(rapidjson
PREFIX ${CMAKE_BINARY_DIR}/externals/rapidjson
GIT_REPOSITORY https://github.com/Tencent/rapidjson.git
GIT_TAG v1.1.0
GIT_SUBMODULES ""
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
UPDATE_COMMAND ""
INSTALL_COMMAND "")
ExternalProject_Get_Property(rapidjson DOWNLOAD_DIR)
set(rapidjson_include_dirs ${DOWNLOAD_DIR}/rapidjson/include)

# include generated files in project environment
include_directories(${antlr4cpp_include_dirs_c1_recognizer})
include_directories(include)

# add generated grammar to c1_recognizer binary target
add_library(c1recognizer
src/error_listener.cpp
src/error_reporter.cpp
src/syntax_tree.cpp
src/syntax_tree_builder.cpp
src/recognizer.cpp
${antlr4cpp_src_files_c1_recognizer})
add_dependencies(c1recognizer antlr4cpp antlr4cpp_generation_c1_recognizer)
target_link_libraries(c1recognizer antlr4-runtime)

include_directories(${rapidjson_include_dirs})
add_executable(c1r_test test/main.cpp)
add_dependencies(c1r_test c1recognizer rapidjson)
target_link_libraries(c1r_test c1recognizer)

install(
TARGETS c1recognizer
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)

install(DIRECTORY include/c1recognizer DESTINATION include)

install(DIRECTORY ${ANTLR4CPP_LIBS}/ DESTINATION lib)

configure_file(c1recognizer-config.cmake.in c1recognizer-config.cmake @ONLY)

install(FILES ${CMAKE_CURRENT_BINARY_DIR}/c1recognizer-config.cmake DESTINATION cmake)
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# C1 Language Recognizer (Reference Version)

A C1 language recognizer library built on ANTLR v4, which constructs an abstract syntax tree on given source input.

## Build Requirement

* CMake 3.5 or later
* Any GCC compatible C++ compiler, C++ 11 must be supported
* Any java runtime environment (JRE), preferring version for Java 8
* pkg-config
* uuid-dev

If you have the patience to configure those correctly on Windows, using Windows as the expirement platform is okay.
Otherwise please choose one of the easy-to-use Linux distributions. (Note: Windows Subsystem for Linux will work fine)

For example, installing those in Ubuntu with `apt`:

```bash
sudo apt install cmake g++ openjdk-8-jre-headless pkg-config uuid-dev
```

Also, it would take a while to build it for the first time. This is because it needs to build the dependency antlr4cpp.
And parallel building won't work on it; it seems that CMake is the one to be blamed.

Besides these, you're also expected to download an ANTLR complete jar file. This is expected throughout this project.
You may find it from [ANTLR v4 Official Site](http://www.antlr.org/).

## Building

For first time building:
```bash
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Debug -DANTLR4CPP_JAR_LOCATION=/path/to/your/antlr.jar ..
make
cmake ..
make -j
```

After that, each time you have any modification, simply do
```bash
make -j
```

To avoid UI unresponding, you may want to replace `-j` option with `-jN`, where `N` is parallel task number you expecting.

## ANTLRv4 Usage

For the building work, I've setup the whole CMake project that will work easily as described above.

And for the most special, magic and wonderful part of ANTLR, visualization, follow these:

* Rail-road or ADT graphs: Using Visual Studio Code will be the best choice. Have ANTLR plugin installed, you'll gonna
find those options when you right-click on the editor.
* Testing grammars (including parse tree visualization):
> If you'd like to see GUI rather than console-printed parse tree, you'll need to first install JDK on your host
> system (Windows or Linux, DO NOT use WSL here if you don't have sufficient knowledge on configuring X11
> environment, which is needed for the GUI to show up). However if you don't want the GUI version visualized parse
> tree, just ignore this tip.
First of all, you need to ensure `.` and ANTLR v4 JAR file exists in your CLASSPATH.
* In PowerShell, it is `$env:CLASSPATH`.
* In Linux-like shells, it is `$CLASSPATH`.

Then, use ANTLR to generate `.java` source files from grammar files.
```sh
java org.antlr.v4.Tool *.g4
```

After that, compile generated sources.
```sh
javac *.java
```

Then, use the `grun` tool comes with antlr to test your grammars.
```sh
# Testing lexer
java org.antlr.v4.gui.TestRig C1Lexer tokens -tokens ../../test/test_cases/simple.c1
# Testing lexer + parser, GUI version parse tree
java org.antlr.v4.gui.TestRig C1 compilationUnit -gui ../../test/test_cases/simple.c1
# Testing lexer + parser, console printed version parse tree
java org.antlr.v4.gui.TestRig C1 compilationUnit -tree ../../test/test_cases/simple.c1
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

set(C1RECOGNIZER_INCLUDE_DIRS "@CMAKE_INSTALL_PREFIX@/include")
set(C1RECOGNIZER_LIBRARY_DIRS "@CMAKE_INSTALL_PREFIX@/lib")
set(C1RECOGNIZER_LIBS c1recognizer antlr4-runtime)
Loading

0 comments on commit 047ba4b

Please sign in to comment.