Commit 4eae2dbe authored by Kai Ma's avatar Kai Ma

[Lab1] Publish

parents
project(CMINUSF)
cmake_minimum_required( VERSION 3.4 )
set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -std=c99")
set(CMAKE_BUILD_TYPE "Debug")
set(CMAKE_C_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb")
set(CMAKE_C_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
set(CMAKE_CXX_STANDARD 17)
find_package(FLEX REQUIRED)
find_package(BISON REQUIRED)
find_package(LLVM REQUIRED CONFIG)
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
llvm_map_components_to_libnames(
llvm_libs
support
core
)
INCLUDE_DIRECTORIES(
include
${LLVM_INCLUDE_DIRS}
)
add_definitions(${LLVM_DEFINITIONS})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
include_directories(${PROJECT_SOURCE_DIR})
include_directories(${PROJECT_BINARY_DIR})
add_subdirectory(src)
add_subdirectory(tests)
This diff is collapsed.
# Flex matching -- How the Input Is Matched
This document is from `The flex Manual`. For better experience, we recommend you to read the original documents. `The flex Manual` can be read with `info flex` in terminal.
```shell
$ info flex
# choose Matching node
```
However, the following is enough for you to finish labs.
Note: if there is any discrepancy, please refer to `The flex Manual`.
**************************
When the generated scanner is run, it analyzes its input looking for strings which match any of its patterns. If it finds more than one match, it takes the one matching the most text (for trailing context rules, this includes the length of the trailing part, even though it will then be returned to the input). If it finds two or more matches of the same length, the rule listed first in the `flex` input file is chosen.
Once the match is determined, the text corresponding to the match (called the "token") is made available in the global character pointer `yytext`, and its length in the global integer `yyleng`. The "action" corresponding to the matched pattern is then executed, and then the remaining input is scanned for another match.
If no match is found, then the "default rule" is executed: the next character in the input is considered matched and copied to the standard output. Thus, the simplest valid `flex` input is:
```c
%%
```
which generates a scanner that simply copies its input (one character at a time) to its output.
Note that `yytext` can be defined in two different ways: either as a character _pointer_ or as a character _array_. You can control which definition `flex` uses by including one of the special directives `%pointer` or `%array` in the first (definitions) section of your flex input. The default is `%pointer`, unless you use the `-l` lex compatibility option, in which case `yytext` will be an array. The advantage of using `%pointer` is substantially faster scanning and no buffer overflow when matching very large tokens (unless you run out of dynamic memory). The disadvantage is that you are restricted in how your actions can modify `yytext`, and calls to the `unput()` function destroys the present contents of `yytext`, which can be a considerable porting headache when moving between different `lex` versions.
The advantage of `%array` is that you can then modify `yytext` to your heart‘s content, and calls to `unput()` do not destroy `yytext`. Furthermore, existing `lex` programs sometimes access `yytext` externally using declarations of the form:
```c
extern char yytext[];
```
This definition is erroneous when used with `%pointer`, but correct for `%array`.
The `%array` declaration defines `yytext` to be an array of `YYLMAX` characters, which defaults to a fairly large value. You can change the size by simply #define'ing `YYLMAX` to a different value in the first section of your `flex` input. As mentioned above, with `%pointer` yytext grows dynamically to accommodate large tokens. While this means your `%pointer` scanner can accommodate very large tokens (such as matching entire blocks of comments), bear in mind that each time the scanner must resize `yytext` it also must rescan the entire token from the beginning, so matching such tokens can prove slow. `yytext` presently does _not_ dynamically grow if a call to `unput()` results in too much text being pushed back; instead, a run-time error results.
Also note that you cannot use `%array` with C++ scanner classes
This diff is collapsed.
This diff is collapsed.
# Lab1 实验文档
## 0. 实验目标
本次实验需要同学们从无到有完成一个完整的 Cminus-f 解析器,包括基于 `flex` 的词法分析器和基于 `bison` 的语法分析器。
本次实验提供了若干文档,请根据实验进度和个人需要认真阅读。
- [实验要求](./README.md)(本文档)
- [实验基础知识](./Basics.md)(进行试验前请首先仔细阅读)
- [Flex matching](./Flex-matching.md)
- [Flex regular expressions](./Flex-regular-expressions.md)
- [拓展阅读](./Parser-FurtherReadings.md)(选读)
在提交实验前,请务必仔细阅读本文档,确保已经完成了所有实验要求、自己的代码可以通过所有测试。
## 1. 词法分析器
本部分需要各位同学根据`Cminus-f`的词法补全`src/parser/lexical_analyzer.l`文件,完成词法分析器。在`lexical_analyzer.l`文件中,你只需补全模式和动作即可,能够输出识别出的`token``text` ,`line(刚出现的行数)``pos_start(该行开始位置)``pos_end(结束的位置,不包含)`。比如:
文本输入:
```c
int a;
```
则识别结果应为:
```shell
Token Text Line Column (Start,End)
280 int 0 (1,4)
284 a 0 (5,6)
270 ; 0 (6,7)
```
必须维护正确的:
* `token`
* `text`
选择维护的(方便你debug,测试):
* `line`
* `pos_start`
* `pos_end`
具体的需识别token请参考[基础知识](./Basics.md)
提示:
1. 在编写本部分前,需要首先修改 `.y` 文件。具体怎么做请参见[基础知识](./Basics.md)
2. 在进入实验下一部分前,你可以使用我们提供的 `lexer` 程序进行调试。参见本文档 3.2 节。
3. token编号是自动生成的,`make` 后,可在 `build/syntax_analyzer.h` 中找到。每次修改token后,都应该重新 `make` 后再进行对照。
**特别说明对于部分token,我们只需要进行过滤,即只需被识别,但是不应该被输出到分析结果中。因为这些token对程序运行不起到任何作用。根据 token 定义顺序不同,输出的 token 编号也可能不同,是正常现象。**
## 2. 语法分析器
本部分需要同学们完成 `src/parser/syntax_analyzer.y`。与词法分析器相同,你只需要根据代码中的提示和[基础知识](./Basics.md)中给出的文法填写相应的规则即可。
如果实现正确,该语法分析器可以从 Cminus-f 代码分析得到一颗语法树。例如输入
```c
int main(void) {
return 0;
}
```
可以得到如下语法树
```
>--+ program
| >--+ declaration-list
| | >--+ declaration
| | | >--+ fun-declaration
| | | | >--+ type-specifier
| | | | | >--* int
| | | | >--* main
| | | | >--* (
| | | | >--+ params
| | | | | >--* void
| | | | >--* )
| | | | >--+ compound-stmt
| | | | | >--* {
| | | | | >--+ local-declarations
| | | | | | >--* epsilon
| | | | | >--+ statement-list
| | | | | | >--+ statement-list
| | | | | | | >--* epsilon
| | | | | | >--+ statement
| | | | | | | >--+ return-stmt
| | | | | | | | >--* return
| | | | | | | | >--+ expression
| | | | | | | | | >--+ simple-expression
| | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | >--+ term
| | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | >--+ integer
| | | | | | | | | | | | | | >--* 0
| | | | | | | | >--* ;
| | | | | >--* }
```
**这一部分必须严格遵守我们给出的语法,输出必须与标准程序输出完全一致。**
## 2.1 思考题
本部分不计入评分,出题的本意在于想要帮助同学们加深对实验细节的理解,欢迎有兴趣和余力的同学在报告中写下你的思考答案,或者在issue中分享出你的看法。
1. [基础知识](./Basics.md)中的计算器例子的文法中存在左递归,为什么 `bison` 可以处理?(提示:不用研究 `bison` 内部运作机制,在下面知识介绍中有提到 `bison` 的一种属性,请结合课内知识思考)
2. 请在代码层面上简述下 `yylval` 是怎么完成协同工作的。(提示:无需研究原理,只分析维护了什么数据结构,该数据结构是怎么和`$1``$2`等联系起来?)
3. 在计算器例子中,除 0 时会发生什么?如果把 `yylval` 修改为整形(`int`, `long` 等),这时候又会发生什么?
4. 能否修改计算器例子的文法,使得它支持除数0规避功能?(提示:这道题很难!尚未有同学给出正确答案。)
## 3. 实验要求
### 3.1 目录结构
与本次实验有关的文件如下。
```
.
├── CMakeLists.txt
├── Documentations
│   └── 1-parser 本次实验的所有文档
├── Reports
│   └── 1-parser
│   └── README.md 在这里写实验报告 <-- 修改
├── include
│   └── syntax_tree.h
├── shell.nix
├── src
│   ├── CMakeLists.txt
│   ├── common
│   │   ├── CMakeLists.txt
│   │   └── syntax_tree.c 语法树的构造
│   └── parser
│   ├── CMakeLists.txt
│   ├── lexical_analyzer.l 词法分析器 <-- 修改
│   └── syntax_analyzer.y 语法分析器 <-- 修改
└── tests
├── CMakeLists.txt
└── parser
│   ├── CMakeLists.txt
│   ├── easy 简单的测试
│   ├── normal 中等复杂度的测试
│   ├── hard 复杂的测试
│   ├── lexer.c 用于词法分析的调试程序
│   ├── parser.c 语法分析
│   ├── syntree_*_std 标准程序输出结果
│   └── test_syntax.sh 用于进行批量测试的脚本
```
### 3.2 编译、运行和验证
项目构建使用 `cmake` 进行。
* 编译
```sh
$ cd 2021fall-Compiler_CMinus
$ mkdir build
$ cd build
$ cmake ..
$ make
```
如果构建成功,会在该目录下看到 `lexer``parser` 两个可执行文件。
* `lexer`用于词法分析,产生token stream;对于词法分析结果,我们不做考察
* `parser`用于语法分析,产生语法树。
* 运行
```sh
$ cd 2020fall-Compiler_CMinus
# 词法测试
$ ./build/lexer ./tests/parser/easy/local-decl.cminus
Token Text Line Column (Start,End)
280 int 0 (0,3)
284 main 0 (4,8)
272 ( 0 (8,9)
282 void 0 (9,13)
273 ) 0 (13,14)
...
# 语法测试
$ ./build/parser ./tests/parser/easy/local-decl.cminus
>--+ program
| >--+ declaration-list
| | >--+ declaration
...
```
* 验证
可以使用 `diff` 与标准输出进行比较。
```sh
$ cd 2020fall-Compiler_CMinus
$ export PATH=$(realpath ./build)
$ cd tests/parser
$ mkdir output.easy
$ parser easy/array.cminus > output.easy/array.cminus
$ diff output.easy/array.cminus syntree_easy_std/array.syntax_tree
[输出为空,代表没有区别,该测试通过]
```
我们提供了 `test_syntax.sh` 脚本进行快速批量测试。该脚本的第一个参数是 `easy` `normal` `hard` 等难度,并且有第二个可选参数,用于进行批量 `diff` 比较。脚本运行后会产生名如 `syntree_easy` 的文件夹。
```sh
$ ./test_syntax.sh easy
[info] Analyzing FAIL_id.cminus
error at line 1 column 6: syntax error
...
[info] Analyzing local-decl.cminus
$ ./test_syntax.sh easy yes
...
[info] Comparing...
[info] No difference! Congratulations!
```
### 3.3 提交要求和评分标准
* 提交要求
本实验的提交要求分为两部分:实验部分的文件和报告,git提交的规范性。
* 实验部分
* 需要完善 `src/parser/lexical_analyzer.l``src/parser/syntax_analyzer.y`
* 需要在 `Reports/1-parser/README.md` 中撰写实验报告。
* 实验报告内容包括
* 实验要求、实验难点、实验设计、实验结果验证、实验反馈
* 实验评估
* 除已提供的 easy, normal, hard 数据集之外,助教会使用额外的测试数据。
* git 提交规范
* 不破坏目录结构(实验报告所需图片放在目录中)
* 不上传临时文件(凡是可以自动生成的都不要上传,如 `build` 目录、测试时自动生成的输出、`.DS_Store` 等)
* git log 言之有物
* 迟交规定
* Soft Deadline:2021-10-03 23:59:59 (UTC+8)
* Hard Deadline:2021-10-10 23:59:59 (UTC+8)
* 补交请邮件提醒 TA:
* 邮箱:`ksqsf@mail.ustc.edu.cn` 抄送 `gpzlx1@mail.ustc.edu.cn` 抄送 `xzwj@mail.ustc.edu.cn`
* 邮件主题:lab1迟交-学号
* 内容:迟交原因、最后版本commitID、迟交时间
* 迟交分数
* x 为相对 Soft Deadline 迟交天数,grade 满分 10
```
final_grade = grade, x = 0
final_grade = grade * (0.9)^x, 0 < x <= 7
final_grade = 0, x > 7
```
* 关于抄袭和雷同
经过助教和老师判定属于作业抄袭或雷同情况,所有参与方一律零分,不接受任何解释和反驳。
如有任何问题,欢迎提issue进行批判指正。
# 实验说明
请 fork 此 repo 到自己的仓库下,随后在自己的仓库中完成实验,请确保自己的 repo 为 Private。
## 目前已布置的实验
* [lab1](./Documentations/1-parser/)
+ DDL:2021-10-03 23:59:59 (UTC+8)
## FAQ: How to merge upstream remote branches
In brief, you need another alias for upstream repository (we assume you are now in your local copy of forked repository on Gitlab):
```shell
$ git remote add upstream http://222.195.68.197/staff/2021fall-compiler_cminus.git
```
Then try to merge remote commits to your local repository:
```shell
$ git pull upstream master
```
Then synchronize changes to your forked remote repository:
```shell
$ git push origin master
```
# lab1 实验报告
学号 姓名
## 实验要求
## 实验难点
## 实验设计
## 实验结果验证
请提供部分自行设计的测试
## 实验反馈
#ifndef _SYNTAX_TREE_HPP_
#define _SYNTAX_TREE_HPP_
extern "C" {
#include "syntax_tree.h"
extern syntax_tree *parse(const char *input);
}
#include <vector>
#include <memory>
#include <string>
enum CminusType {
TYPE_INT,
TYPE_FLOAT,
TYPE_VOID
};
enum RelOp {
// <=
OP_LE,
// <
OP_LT,
// >
OP_GT,
// >=
OP_GE,
// ==
OP_EQ,
// !=
OP_NEQ
};
enum AddOp {
// +
OP_PLUS,
// -
OP_MINUS
};
enum MulOp {
// *
OP_MUL,
// /
OP_DIV
};
class AST;
struct ASTNode;
struct ASTProgram;
struct ASTDeclaration;
struct ASTNum;
struct ASTVarDeclaration;
struct ASTFunDeclaration;
struct ASTParam;
struct ASTCompoundStmt;
struct ASTStatement;
struct ASTExpressionStmt;
struct ASTSelectionStmt;
struct ASTIterationStmt;
struct ASTReturnStmt;
struct ASTFactor;
struct ASTExpression;
struct ASTVar;
struct ASTAssignExpression;
struct ASTSimpleExpression;
struct ASTAdditiveExpression;
struct ASTTerm ;
struct ASTCall;
class ASTVisitor;
class AST {
public:
AST() = delete;
AST(syntax_tree *);
AST(AST &&tree) {
root = tree.root;
tree.root = nullptr;
};
ASTProgram* get_root() { return root.get(); }
void run_visitor(ASTVisitor& visitor);
private:
ASTNode* transform_node_iter(syntax_tree_node *);
std::shared_ptr<ASTProgram> root = nullptr;
};
struct ASTNode {
virtual void accept(ASTVisitor &) = 0;
};
struct ASTProgram : ASTNode {
virtual void accept(ASTVisitor &) override final;
std::vector<std::shared_ptr<ASTDeclaration>>
declarations;
};
struct ASTDeclaration: ASTNode {
virtual void accept(ASTVisitor &) override;
CminusType type;
std::string id;
};
struct ASTFactor: ASTNode {
virtual void accept(ASTVisitor &) override;
};
struct ASTNum: ASTFactor {
virtual void accept(ASTVisitor &) override final;
CminusType type;
union {
int i_val;
float f_val;
};
};
struct ASTVarDeclaration: ASTDeclaration {
virtual void accept(ASTVisitor &) override final;
CminusType type;
std::shared_ptr<ASTNum> num;
};
struct ASTFunDeclaration: ASTDeclaration {
virtual void accept(ASTVisitor &) override final;
std::vector<std::shared_ptr<ASTParam>> params;
std::shared_ptr<ASTCompoundStmt> compound_stmt;
};
struct ASTParam: ASTNode {
virtual void accept(ASTVisitor &) override final;
CminusType type;
std::string id;
// true if it is array param
bool isarray;
};
struct ASTStatement : ASTNode {
virtual void accept(ASTVisitor &) override;
};
struct ASTCompoundStmt: ASTStatement {
virtual void accept(ASTVisitor&) override final;
std::vector<std::shared_ptr<ASTVarDeclaration>> local_declarations;
std::vector<std::shared_ptr<ASTStatement>> statement_list;
};
struct ASTExpressionStmt: ASTStatement {
virtual void accept(ASTVisitor &) override final;
std::shared_ptr<ASTExpression> expression;
};
struct ASTSelectionStmt: ASTStatement {
virtual void accept(ASTVisitor &) override final;
std::shared_ptr<ASTExpression> expression;
std::shared_ptr<ASTStatement> if_statement;
// should be nullptr if no else structure exists
std::shared_ptr<ASTStatement> else_statement;
};
struct ASTIterationStmt: ASTStatement {
virtual void accept(ASTVisitor &) override final;
std::shared_ptr<ASTExpression> expression;
std::shared_ptr<ASTStatement> statement;
};
struct ASTReturnStmt: ASTStatement {
virtual void accept(ASTVisitor &) override final;
// should be nullptr if return void
std::shared_ptr<ASTExpression> expression;
};
struct ASTExpression: ASTFactor {
virtual void accept(ASTVisitor &) override;
};
struct ASTAssignExpression: ASTExpression {
virtual void accept(ASTVisitor &) override final;
std::shared_ptr<ASTVar> var;
std::shared_ptr<ASTExpression> expression;
};
struct ASTSimpleExpression: ASTExpression {
virtual void accept(ASTVisitor &) override final;
std::shared_ptr<ASTAdditiveExpression> additive_expression_l;
std::shared_ptr<ASTAdditiveExpression> additive_expression_r;
RelOp op;
};
struct ASTVar: ASTFactor {
virtual void accept(ASTVisitor &) override final;
std::string id;
// nullptr if var is of int type
std::shared_ptr<ASTExpression> expression;
};
struct ASTAdditiveExpression: ASTNode {
virtual void accept(ASTVisitor &) override final;
std::shared_ptr<ASTAdditiveExpression> additive_expression;
AddOp op;
std::shared_ptr<ASTTerm> term;
};
struct ASTTerm : ASTNode {
virtual void accept(ASTVisitor &) override final;
std::shared_ptr<ASTTerm> term;
MulOp op;
std::shared_ptr<ASTFactor> factor;
};
struct ASTCall: ASTFactor {
virtual void accept(ASTVisitor &) override final;
std::string id;
std::vector<std::shared_ptr<ASTExpression>> args;
};
class ASTVisitor {
public:
virtual void visit(ASTProgram &) = 0;
virtual void visit(ASTNum &) = 0;
virtual void visit(ASTVarDeclaration &) = 0;
virtual void visit(ASTFunDeclaration &) = 0;
virtual void visit(ASTParam &) = 0;
virtual void visit(ASTCompoundStmt &) = 0;
virtual void visit(ASTExpressionStmt &) = 0;
virtual void visit(ASTSelectionStmt &) = 0;
virtual void visit(ASTIterationStmt &) = 0;
virtual void visit(ASTReturnStmt &) = 0;
virtual void visit(ASTAssignExpression &) = 0;
virtual void visit(ASTSimpleExpression &) = 0;
virtual void visit(ASTAdditiveExpression &) = 0;
virtual void visit(ASTVar &) = 0;
virtual void visit(ASTTerm &) = 0;
virtual void visit(ASTCall &) = 0;
};
class ASTPrinter : public ASTVisitor {
public:
virtual void visit(ASTProgram &) override final;
virtual void visit(ASTNum &) override final;
virtual void visit(ASTVarDeclaration &) override final;
virtual void visit(ASTFunDeclaration &) override final;
virtual void visit(ASTParam &) override final;
virtual void visit(ASTCompoundStmt &) override final;
virtual void visit(ASTExpressionStmt &) override final;
virtual void visit(ASTSelectionStmt &) override final;
virtual void visit(ASTIterationStmt &) override final;
virtual void visit(ASTReturnStmt &) override final;
virtual void visit(ASTAssignExpression &) override final;
virtual void visit(ASTSimpleExpression &) override final;
virtual void visit(ASTAdditiveExpression &) override final;
virtual void visit(ASTVar &) override final;
virtual void visit(ASTTerm &) override final;
virtual void visit(ASTCall &) override final;
void add_depth() { depth += 2; }
void remove_depth() { depth -= 2; }
private:
int depth = 0;
};
#endif
#ifndef LOGGING_HPP
#define LOGGING_HPP
#include <iostream>
#include <sstream>
#include <cstdlib>
enum LogLevel
{
DEBUG = 0,
INFO,
WARNING,
ERROR
};
struct LocationInfo
{
LocationInfo(std::string file, int line, const char *func) : file_(file), line_(line), func_(func) {}
~LocationInfo() = default;
std::string file_;
int line_;
const char *func_;
};
class LogStream;
class LogWriter;
class LogWriter
{
public:
LogWriter(LocationInfo location, LogLevel loglevel)
: location_(location), log_level_(loglevel)
{
char *logv = std::getenv("LOGV");
if (logv)
{
std::string string_logv = logv;
env_log_level = std::stoi(logv);
}
else
{
env_log_level = 4;
}
};
void operator<(const LogStream &stream);
private:
void output_log(const std::ostringstream &g);
LocationInfo location_;
LogLevel log_level_;
int env_log_level;
};
class LogStream
{
public:
LogStream() { sstream_ = new std::stringstream(); }
~LogStream() = default;
template <typename T>
LogStream &operator<<(const T &val) noexcept
{
(*sstream_) << val;
return *this;
}
friend class LogWriter;
private:
std::stringstream *sstream_;
};
std::string level2string(LogLevel level);
std::string get_short_name(const char *file_path);
#define __FILESHORTNAME__ get_short_name(__FILE__)
#define LOG_IF(level) \
LogWriter(LocationInfo(__FILESHORTNAME__, __LINE__, __FUNCTION__), level) < LogStream()
#define LOG(level) LOG_##level
#define LOG_DEBUG LOG_IF(DEBUG)
#define LOG_INFO LOG_IF(INFO)
#define LOG_WARNING LOG_IF(WARNING)
#define LOG_ERROR LOG_IF(ERROR)
#endif
#ifndef __SYNTAXTREE_H__
#define __SYNTAXTREE_H__
#include <stdio.h>
#define SYNTAX_TREE_NODE_NAME_MAX 30
struct _syntax_tree_node {
struct _syntax_tree_node * parent;
struct _syntax_tree_node * children[10];
int children_num;
char name[SYNTAX_TREE_NODE_NAME_MAX];
};
typedef struct _syntax_tree_node syntax_tree_node;
syntax_tree_node * new_anon_syntax_tree_node();
syntax_tree_node * new_syntax_tree_node(const char * name);
int syntax_tree_add_child(syntax_tree_node * parent, syntax_tree_node * child);
void del_syntax_tree_node(syntax_tree_node * node, int recursive);
struct _syntax_tree {
syntax_tree_node * root;
};
typedef struct _syntax_tree syntax_tree;
syntax_tree* new_syntax_tree();
void del_syntax_tree(syntax_tree * tree);
void print_syntax_tree(FILE * fout, syntax_tree * tree);
#endif /* SyntaxTree.h */
# Use `nix-shell` to quickly create a dev shell.
{ pkgs ? import <nixpkgs> {} }:
with pkgs; mkShell {
buildInputs = [ flex bison llvmPackages_10.llvm llvmPackages_10.clang ];
shellHook = ''
_rootdir="$(realpath .)"
_builddir="$_rootdir/build"
export PATH="$_builddir:$PATH"
rebuild(){
(cd $_builddir; make -j)
}
'';
}
add_subdirectory(parser)
add_subdirectory(common)
\ No newline at end of file
add_library(common STATIC
syntax_tree.c
ast.cpp
logging.cpp
)
target_link_libraries(common)
This diff is collapsed.
#include "logging.hpp"
void LogWriter::operator<(const LogStream &stream) {
std::ostringstream msg;
msg << stream.sstream_->rdbuf();
output_log(msg);
}
void LogWriter::output_log(const std::ostringstream &msg) {
if (log_level_ >= env_log_level)
std::cout << "[" << level2string(log_level_) << "] "
<< "(" << location_.file_
<< ":" << location_.line_
<< "L "<< location_.func_<<")"
<< msg.str() << std::endl;
}
std::string level2string(LogLevel level) {
switch (level)
{
case DEBUG:
return "DEBUG";
case INFO:
return "INFO";
case WARNING:
return "WARNING";
case ERROR:
return "ERROR";
default:
return "";
}
}
std::string get_short_name(const char * file_path) {
std::string short_file_path = file_path;
int index = short_file_path.find_last_of('/');
return short_file_path.substr(index+1);
}
#include <stdlib.h>
#include <string.h>
#include "syntax_tree.h"
syntax_tree_node * new_syntax_tree_node(const char * name)
{
syntax_tree_node * new_node = (syntax_tree_node *)malloc(sizeof(syntax_tree_node));
if (name)
strncpy(new_node->name, name, SYNTAX_TREE_NODE_NAME_MAX);
else
new_node->name[0] = '\0';
new_node->children_num = 0;
return new_node;
}
int syntax_tree_add_child(syntax_tree_node * parent, syntax_tree_node * child)
{
if (!parent || !child) return -1;
parent->children[parent->children_num++] = child;
return parent->children_num;
}
void del_syntax_tree_node(syntax_tree_node * node, int recursive)
{
if (!node) return;
int i;
if (recursive) {
for (i = 0; i < node->children_num; i++) {
del_syntax_tree_node(node->children[i], 1);
}
}
free(node);
}
syntax_tree * new_syntax_tree()
{
return (syntax_tree *)malloc(sizeof(syntax_tree));
}
void del_syntax_tree(syntax_tree * tree)
{
if (!tree) return;
if (tree->root) {
del_syntax_tree_node(tree->root, 1);
}
free(tree);
}
void print_syntax_tree_node(FILE * fout, syntax_tree_node * node, int level)
{
// assume fout valid now
// check if "node" empty pointer
if (!node) return;
// print myself
int i;
for (i = 0; i < level; i++) {
fprintf(fout, "| ");
}
fprintf(fout, ">--%s %s\n", (node->children_num ? "+" : "*"), node->name);
for (i = 0; i < node->children_num; i++) {
print_syntax_tree_node(fout, node->children[i], level + 1);
}
}
void print_syntax_tree(FILE * fout, syntax_tree * tree)
{
if (!fout) return;
print_syntax_tree_node(fout, tree->root, 0);
}
flex_target(lex lexical_analyzer.l ${CMAKE_CURRENT_BINARY_DIR}/lexical_analyzer.c)
bison_target(syntax syntax_analyzer.y
${CMAKE_CURRENT_BINARY_DIR}/syntax_analyzer.c
DEFINES_FILE ${PROJECT_BINARY_DIR}/syntax_analyzer.h)
add_flex_bison_dependency(lex syntax)
add_library(syntax STATIC
${BISON_syntax_OUTPUTS}
${FLEX_lex_OUTPUTS}
)
%option noyywrap
%{
/*****************声明和选项设置 begin*****************/
#include <stdio.h>
#include <stdlib.h>
#include "syntax_tree.h"
#include "syntax_analyzer.h"
int lines;
int pos_start;
int pos_end;
void pass_node(char *text){
yylval.node = new_syntax_tree_node(text);
}
/*****************声明和选项设置 end*****************/
%}
%%
/* to do for students */
/* two cases for you, pass_node will send flex's token to bison */
\+ {pos_start = pos_end; pos_end += 1; pass_node(yytext); return ADD;}
. { pos_start = pos_end; pos_end++; return ERROR; }
/****请在此补全所有flex的模式与动作 end******/
%%
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "syntax_tree.h"
// external functions from lex
extern int yylex();
extern int yyparse();
extern int yyrestart();
extern FILE * yyin;
// external variables from lexical_analyzer module
extern int lines;
extern char * yytext;
extern int pos_end;
extern int pos_start;
// Global syntax tree
syntax_tree *gt;
// Error reporting
void yyerror(const char *s);
// Helper functions written for you with love
syntax_tree_node *node(const char *node_name, int children_num, ...);
%}
/* TODO: Complete this definition.
Hint: See pass_node(), node(), and syntax_tree.h.
Use forward declaring. */
%union {}
/* TODO: Your tokens here. */
%token <node> ERROR
%token <node> ADD
%type <node> program
%start program
%%
/* TODO: Your rules here. */
/* Example:
program: declaration-list {$$ = node( "program", 1, $1); gt->root = $$;}
;
*/
program : ;
%%
/// The error reporting function.
void yyerror(const char * s)
{
// TO STUDENTS: This is just an example.
// You can customize it as you like.
fprintf(stderr, "error at line %d column %d: %s\n", lines, pos_start, s);
}
/// Parse input from file `input_path`, and prints the parsing results
/// to stdout. If input_path is NULL, read from stdin.
///
/// This function initializes essential states before running yyparse().
syntax_tree *parse(const char *input_path)
{
if (input_path != NULL) {
if (!(yyin = fopen(input_path, "r"))) {
fprintf(stderr, "[ERR] Open input file %s failed.\n", input_path);
exit(1);
}
} else {
yyin = stdin;
}
lines = pos_start = pos_end = 1;
gt = new_syntax_tree();
yyrestart(yyin);
yyparse();
return gt;
}
/// A helper function to quickly construct a tree node.
///
/// e.g. $$ = node("program", 1, $1);
syntax_tree_node *node(const char *name, int children_num, ...)
{
syntax_tree_node *p = new_syntax_tree_node(name);
syntax_tree_node *child;
if (children_num == 0) {
child = new_syntax_tree_node("epsilon");
syntax_tree_add_child(p, child);
} else {
va_list ap;
va_start(ap, children_num);
for (int i = 0; i < children_num; ++i) {
child = va_arg(ap, syntax_tree_node *);
syntax_tree_add_child(p, child);
}
va_end(ap);
}
return p;
}
add_subdirectory(parser)
add_executable(test_ast test_ast.cpp)
add_executable(test_logging test_logging.cpp)
target_link_libraries(test_logging common)
target_link_libraries(test_ast syntax common)
syntree_easy/
syntree_normal/
syntree_hard/
syntree_lunatic/
include_directories(${PROJECT_BINARY_DIR})
add_executable(parser parser.c)
target_link_libraries(parser syntax common)
add_executable(lexer lexer.c)
target_link_libraries(lexer syntax common)
#!/bin/sh
rm -rf syntree_easy syntree_normal syntree_hard syntree_lunatic
/* unclosed comment
\ No newline at end of file
// cminus dont support comment like that
int main(void){
return 0;
}
\ No newline at end of file
/* unclosed function */
int main(void)
{
\ No newline at end of file
int a1;
int f1(void) {}
int f2(void) {}
/*Basic num part*/
int main(void){
a = 0;
x = 0.0;
x = 1.;
x = .1;
a = 1+1;
a = a-1;
x = x*1;
x = a/x;
return 0;
}
\ No newline at end of file
int a;
int f(void) {}
int g(void) {}
/*
I konw it's weird, even stupid, to code C like this. w(゚Д゚)w
HOWEVER, we have to use some tricky cases to test your answer.
*/
float GVAR;
void NeverEverDeclareLikeThis;
int GARRAY[2333];
void MyFuncA(int floatNum, float intNum, void voidNums[]){
int IKnowYouAreVoid;
return MyFuncB(IKnowYouAreVoid);
}
float MyFuncB(void){
int IAmVoid[0];
return MyFuncA(.0, 0, IAmVoid);
}
int main(void){
int a; int b; int c;
a = b = c = (85 == 84 + 0.4);
if(a = b){
GARRAY[ ( MyFuncB() ) ] = GARRAY[c = 1.*.1 == 1.1];
}else if (MyFuncC(NotDeclared)){
}else;
return 0.;
}
\ No newline at end of file
/* associativity and precedence */
int main(void)
{
a = b = c = 1 + 1 / 2 * 1 * (1 + 1 + 1 - 1 / 1) + 3 + 4 * 3;
}
int gcd (int u, int v) { /* calculate the gcd of u and v */
if (v == 0) return u;
else return gcd(v, u - u / v * v); /* v,u-u/v*v is equals to u mod v*/
}
int main(void) {
int x; int y; int temp;
x = 72;
y = 18;
if (x<y) {
temp = x;
x = y;
y = temp;
}
gcd(x,y);
return 0;
}
void move(int x, int y)
{
putint(x); putch(32); putint(y); putch(44); putch(32);
}
void hanoi(int n, int one, int two, int three)
{
if (n == 1)
move(one, three);
else {
hanoi(n - 1, one, three, two);
move(one, three);
hanoi(n - 1, two, one, three);
}
}
int main(void )
{
int n;
n = getint();
while (n > 0) {
hanoi(getint(), 1, 2, 3);
putch(10);
n = n - 1;
}
return 0;
}
/* else should be bound to the closest if */
int main(void)
{
if (1) {} else if (2) {} else {}
return 0;
}
/* this is the sample program in C- in the book "Compiler Construction" */
/* A program to perform selection sort on a 10 element array. */
int x[10];
int minloc ( int a[], int low, int high )
{ int i; int x; int k;
k = low;
x = a[low];
i = low + 1;
while (i < high)
{ if (a[i] < x)
{ x = a[i];
k = i; }
i = i + 1;
}
return k;
}
void sort( int a[], int low, int high)
{ int i; int k;
i = low;
while ( i < high-1)
{ int t;
k = minloc(a, i, high);
t = a[k];
a[k] = a[i];
a[i] = t;
i = i + 1;
}
}
void main(void)
{ int i;
i = 0;
while ( i < 10)
{ x[i] = input();
i = i + 1; }
sort(x, 0, 10);
i = 0;
while (i < 10)
{ output(x[i]);
i = i + 1; }
}
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<syntax_analyzer.h>
///
extern int lines;
extern int pos_start;
extern int pos_end;
///
extern FILE *yyin;
extern char *yytext;
extern int yylex();
// Mac-only hack.
YYSTYPE yylval;
///
int main(int argc, const char **argv) {
if (argc != 2) {
printf("usage: lexer input_file\n");
return 0;
}
const char *input_file = argv[1];
yyin = fopen(input_file, "r");
if (!yyin) {
fprintf(stderr, "cannot open file: %s\n", input_file);
return 1;
}
int token;
printf("%5s\t%10s\t%s\t%s\n", "Token", "Text", "Line", "Column (Start,End)");
while ((token = yylex())) {
printf("%-5d\t%10s\t%d\t(%d,%d)\n",
token, yytext,
lines, pos_start, pos_end);
}
return 0;
}
int main(void)
{
a=1;
1=a;
}
int main(void){
int a;
a = 1;
int b;
return 0;
}
\ No newline at end of file
int main(void) {
int array[1];
array[1] = 0;
return 0;
}
float foo(float a, float b[]) {
return 1;
}
int main(void) {
return 0;
}
/*Basic selection part*/
int main(void){
int a; int b;
a = 1;
b = 1;
if(a != b){
if(a == b);
else{
a = b;
}
}
return 0;
}
\ No newline at end of file
int main(void) {
int i; float j;
void v;
return 0;
}
/*
int main() {
int arr[100];
int i;
int sum;
i = 0;
sum = 0;
while (getint()) {
arr[i] = getint();
i = i + 1;
}*/
int main(void) {
int arr[100];
int i;
int sum;
i = 0;
sum = 0;
while (getint()) {
arr[i] = getint();
i = i + 1;
}
while (i) {
i = i - 1;
sum = sum + arr[i];
}
return sum - 79;
}
#include "syntax_tree.h"
extern syntax_tree *parse(const char*);
int main(int argc, char *argv[])
{
syntax_tree *tree = NULL;
const char *input = NULL;
if (argc >= 3) {
printf("usage: %s\n", argv[0]);
printf("usage: %s <cminus_file>\n", argv[0]);
return 1;
}
if (argc == 2) {
input = argv[1];
}
// Call the syntax analyzer.
tree = parse(input);
print_syntax_tree(stdout, tree);
del_syntax_tree(tree);
return 0;
}
>--+ program
| >--+ declaration-list
| | >--+ declaration
| | | >--+ fun-declaration
| | | | >--+ type-specifier
| | | | | >--* int
| | | | >--* main
| | | | >--* (
| | | | >--+ params
| | | | | >--* void
| | | | >--* )
| | | | >--+ compound-stmt
| | | | | >--* {
| | | | | >--+ local-declarations
| | | | | | >--* epsilon
| | | | | >--+ statement-list
| | | | | | >--+ statement-list
| | | | | | | >--+ statement-list
| | | | | | | | >--+ statement-list
| | | | | | | | | >--+ statement-list
| | | | | | | | | | >--+ statement-list
| | | | | | | | | | | >--+ statement-list
| | | | | | | | | | | | >--+ statement-list
| | | | | | | | | | | | | >--+ statement-list
| | | | | | | | | | | | | | >--+ statement-list
| | | | | | | | | | | | | | | >--* epsilon
| | | | | | | | | | | | | | >--+ statement
| | | | | | | | | | | | | | | >--+ expression-stmt
| | | | | | | | | | | | | | | | >--+ expression
| | | | | | | | | | | | | | | | | >--+ var
| | | | | | | | | | | | | | | | | | >--* a
| | | | | | | | | | | | | | | | | >--* =
| | | | | | | | | | | | | | | | | >--+ expression
| | | | | | | | | | | | | | | | | | >--+ simple-expression
| | | | | | | | | | | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | | | | | | | | >--+ integer
| | | | | | | | | | | | | | | | | | | | | | | >--* 0
| | | | | | | | | | | | | | | | >--* ;
| | | | | | | | | | | | | >--+ statement
| | | | | | | | | | | | | | >--+ expression-stmt
| | | | | | | | | | | | | | | >--+ expression
| | | | | | | | | | | | | | | | >--+ var
| | | | | | | | | | | | | | | | | >--* x
| | | | | | | | | | | | | | | | >--* =
| | | | | | | | | | | | | | | | >--+ expression
| | | | | | | | | | | | | | | | | >--+ simple-expression
| | | | | | | | | | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | | | | | | | >--+ float
| | | | | | | | | | | | | | | | | | | | | | >--* 0.0
| | | | | | | | | | | | | | | >--* ;
| | | | | | | | | | | | >--+ statement
| | | | | | | | | | | | | >--+ expression-stmt
| | | | | | | | | | | | | | >--+ expression
| | | | | | | | | | | | | | | >--+ var
| | | | | | | | | | | | | | | | >--* x
| | | | | | | | | | | | | | | >--* =
| | | | | | | | | | | | | | | >--+ expression
| | | | | | | | | | | | | | | | >--+ simple-expression
| | | | | | | | | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | | | | | | >--+ float
| | | | | | | | | | | | | | | | | | | | | >--* 1.
| | | | | | | | | | | | | | >--* ;
| | | | | | | | | | | >--+ statement
| | | | | | | | | | | | >--+ expression-stmt
| | | | | | | | | | | | | >--+ expression
| | | | | | | | | | | | | | >--+ var
| | | | | | | | | | | | | | | >--* x
| | | | | | | | | | | | | | >--* =
| | | | | | | | | | | | | | >--+ expression
| | | | | | | | | | | | | | | >--+ simple-expression
| | | | | | | | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | | | | | >--+ float
| | | | | | | | | | | | | | | | | | | | >--* .1
| | | | | | | | | | | | | >--* ;
| | | | | | | | | | >--+ statement
| | | | | | | | | | | >--+ expression-stmt
| | | | | | | | | | | | >--+ expression
| | | | | | | | | | | | | >--+ var
| | | | | | | | | | | | | | >--* a
| | | | | | | | | | | | | >--* =
| | | | | | | | | | | | | >--+ expression
| | | | | | | | | | | | | | >--+ simple-expression
| | | | | | | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | | | | | >--+ integer
| | | | | | | | | | | | | | | | | | | | >--* 1
| | | | | | | | | | | | | | | | >--+ addop
| | | | | | | | | | | | | | | | | >--* +
| | | | | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | | | | >--+ integer
| | | | | | | | | | | | | | | | | | | >--* 1
| | | | | | | | | | | | >--* ;
| | | | | | | | | >--+ statement
| | | | | | | | | | >--+ expression-stmt
| | | | | | | | | | | >--+ expression
| | | | | | | | | | | | >--+ var
| | | | | | | | | | | | | >--* a
| | | | | | | | | | | | >--* =
| | | | | | | | | | | | >--+ expression
| | | | | | | | | | | | | >--+ simple-expression
| | | | | | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | | | | >--+ var
| | | | | | | | | | | | | | | | | | | >--* a
| | | | | | | | | | | | | | | >--+ addop
| | | | | | | | | | | | | | | | >--* -
| | | | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | | | >--+ integer
| | | | | | | | | | | | | | | | | | >--* 1
| | | | | | | | | | | >--* ;
| | | | | | | | >--+ statement
| | | | | | | | | >--+ expression-stmt
| | | | | | | | | | >--+ expression
| | | | | | | | | | | >--+ var
| | | | | | | | | | | | >--* x
| | | | | | | | | | | >--* =
| | | | | | | | | | | >--+ expression
| | | | | | | | | | | | >--+ simple-expression
| | | | | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | | | >--+ var
| | | | | | | | | | | | | | | | | | >--* x
| | | | | | | | | | | | | | | >--+ mulop
| | | | | | | | | | | | | | | | >--* *
| | | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | | >--+ integer
| | | | | | | | | | | | | | | | | >--* 1
| | | | | | | | | | >--* ;
| | | | | | | >--+ statement
| | | | | | | | >--+ expression-stmt
| | | | | | | | | >--+ expression
| | | | | | | | | | >--+ var
| | | | | | | | | | | >--* x
| | | | | | | | | | >--* =
| | | | | | | | | | >--+ expression
| | | | | | | | | | | >--+ simple-expression
| | | | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | | >--+ var
| | | | | | | | | | | | | | | | | >--* a
| | | | | | | | | | | | | | >--+ mulop
| | | | | | | | | | | | | | | >--* /
| | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | >--+ var
| | | | | | | | | | | | | | | | >--* x
| | | | | | | | | >--* ;
| | | | | | >--+ statement
| | | | | | | >--+ return-stmt
| | | | | | | | >--* return
| | | | | | | | >--+ expression
| | | | | | | | | >--+ simple-expression
| | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | >--+ term
| | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | >--+ integer
| | | | | | | | | | | | | | >--* 0
| | | | | | | | >--* ;
| | | | | >--* }
>--+ program
| >--+ declaration-list
| | >--+ declaration-list
| | | >--+ declaration-list
| | | | >--+ declaration
| | | | | >--+ var-declaration
| | | | | | >--+ type-specifier
| | | | | | | >--* int
| | | | | | >--* a
| | | | | | >--* ;
| | | >--+ declaration
| | | | >--+ fun-declaration
| | | | | >--+ type-specifier
| | | | | | >--* int
| | | | | >--* f
| | | | | >--* (
| | | | | >--+ params
| | | | | | >--* void
| | | | | >--* )
| | | | | >--+ compound-stmt
| | | | | | >--* {
| | | | | | >--+ local-declarations
| | | | | | | >--* epsilon
| | | | | | >--+ statement-list
| | | | | | | >--* epsilon
| | | | | | >--* }
| | >--+ declaration
| | | >--+ fun-declaration
| | | | >--+ type-specifier
| | | | | >--* int
| | | | >--* g
| | | | >--* (
| | | | >--+ params
| | | | | >--* void
| | | | >--* )
| | | | >--+ compound-stmt
| | | | | >--* {
| | | | | >--+ local-declarations
| | | | | | >--* epsilon
| | | | | >--+ statement-list
| | | | | | >--* epsilon
| | | | | >--* }
This diff is collapsed.
>--+ program
| >--+ declaration-list
| | >--+ declaration
| | | >--+ fun-declaration
| | | | >--+ type-specifier
| | | | | >--* int
| | | | >--* main
| | | | >--* (
| | | | >--+ params
| | | | | >--* void
| | | | >--* )
| | | | >--+ compound-stmt
| | | | | >--* {
| | | | | >--+ local-declarations
| | | | | | >--* epsilon
| | | | | >--+ statement-list
| | | | | | >--+ statement-list
| | | | | | | >--* epsilon
| | | | | | >--+ statement
| | | | | | | >--+ expression-stmt
| | | | | | | | >--+ expression
| | | | | | | | | >--+ var
| | | | | | | | | | >--* a
| | | | | | | | | >--* =
| | | | | | | | | >--+ expression
| | | | | | | | | | >--+ var
| | | | | | | | | | | >--* b
| | | | | | | | | | >--* =
| | | | | | | | | | >--+ expression
| | | | | | | | | | | >--+ var
| | | | | | | | | | | | >--* c
| | | | | | | | | | | >--* =
| | | | | | | | | | | >--+ expression
| | | | | | | | | | | | >--+ simple-expression
| | | | | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | | | | | >--+ integer
| | | | | | | | | | | | | | | | | | | | >--* 1
| | | | | | | | | | | | | | | | >--+ addop
| | | | | | | | | | | | | | | | | >--* +
| | | | | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | | | | | | | >--+ integer
| | | | | | | | | | | | | | | | | | | | | | >--* 1
| | | | | | | | | | | | | | | | | | | >--+ mulop
| | | | | | | | | | | | | | | | | | | | >--* /
| | | | | | | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | | | | | | >--+ integer
| | | | | | | | | | | | | | | | | | | | | >--* 2
| | | | | | | | | | | | | | | | | | >--+ mulop
| | | | | | | | | | | | | | | | | | | >--* *
| | | | | | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | | | | | >--+ integer
| | | | | | | | | | | | | | | | | | | | >--* 1
| | | | | | | | | | | | | | | | | >--+ mulop
| | | | | | | | | | | | | | | | | | >--* *
| | | | | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | | | | >--* (
| | | | | | | | | | | | | | | | | | >--+ expression
| | | | | | | | | | | | | | | | | | | >--+ simple-expression
| | | | | | | | | | | | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | | | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | | | | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | | | | | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | | | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | | | | | | | | | | | | >--+ integer
| | | | | | | | | | | | | | | | | | | | | | | | | | | >--* 1
| | | | | | | | | | | | | | | | | | | | | | | >--+ addop
| | | | | | | | | | | | | | | | | | | | | | | | >--* +
| | | | | | | | | | | | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | | | | | | | | | | | >--+ integer
| | | | | | | | | | | | | | | | | | | | | | | | | | >--* 1
| | | | | | | | | | | | | | | | | | | | | | >--+ addop
| | | | | | | | | | | | | | | | | | | | | | | >--* +
| | | | | | | | | | | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | | | | | | | | | | >--+ integer
| | | | | | | | | | | | | | | | | | | | | | | | | >--* 1
| | | | | | | | | | | | | | | | | | | | | >--+ addop
| | | | | | | | | | | | | | | | | | | | | | >--* -
| | | | | | | | | | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | | | | | | | | | | >--+ integer
| | | | | | | | | | | | | | | | | | | | | | | | | >--* 1
| | | | | | | | | | | | | | | | | | | | | | >--+ mulop
| | | | | | | | | | | | | | | | | | | | | | | >--* /
| | | | | | | | | | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | | | | | | | | | >--+ integer
| | | | | | | | | | | | | | | | | | | | | | | | >--* 1
| | | | | | | | | | | | | | | | | | >--* )
| | | | | | | | | | | | | | | >--+ addop
| | | | | | | | | | | | | | | | >--* +
| | | | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | | | >--+ integer
| | | | | | | | | | | | | | | | | | >--* 3
| | | | | | | | | | | | | | >--+ addop
| | | | | | | | | | | | | | | >--* +
| | | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | | | >--+ integer
| | | | | | | | | | | | | | | | | | >--* 4
| | | | | | | | | | | | | | | >--+ mulop
| | | | | | | | | | | | | | | | >--* *
| | | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | | >--+ integer
| | | | | | | | | | | | | | | | | >--* 3
| | | | | | | | >--* ;
| | | | | >--* }
This diff is collapsed.
This diff is collapsed.
>--+ program
| >--+ declaration-list
| | >--+ declaration
| | | >--+ fun-declaration
| | | | >--+ type-specifier
| | | | | >--* int
| | | | >--* main
| | | | >--* (
| | | | >--+ params
| | | | | >--* void
| | | | >--* )
| | | | >--+ compound-stmt
| | | | | >--* {
| | | | | >--+ local-declarations
| | | | | | >--* epsilon
| | | | | >--+ statement-list
| | | | | | >--+ statement-list
| | | | | | | >--+ statement-list
| | | | | | | | >--* epsilon
| | | | | | | >--+ statement
| | | | | | | | >--+ selection-stmt
| | | | | | | | | >--* if
| | | | | | | | | >--* (
| | | | | | | | | >--+ expression
| | | | | | | | | | >--+ simple-expression
| | | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | >--+ integer
| | | | | | | | | | | | | | | >--* 1
| | | | | | | | | >--* )
| | | | | | | | | >--+ statement
| | | | | | | | | | >--+ compound-stmt
| | | | | | | | | | | >--* {
| | | | | | | | | | | >--+ local-declarations
| | | | | | | | | | | | >--* epsilon
| | | | | | | | | | | >--+ statement-list
| | | | | | | | | | | | >--* epsilon
| | | | | | | | | | | >--* }
| | | | | | | | | >--* else
| | | | | | | | | >--+ statement
| | | | | | | | | | >--+ selection-stmt
| | | | | | | | | | | >--* if
| | | | | | | | | | | >--* (
| | | | | | | | | | | >--+ expression
| | | | | | | | | | | | >--+ simple-expression
| | | | | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | | >--+ integer
| | | | | | | | | | | | | | | | | >--* 2
| | | | | | | | | | | >--* )
| | | | | | | | | | | >--+ statement
| | | | | | | | | | | | >--+ compound-stmt
| | | | | | | | | | | | | >--* {
| | | | | | | | | | | | | >--+ local-declarations
| | | | | | | | | | | | | | >--* epsilon
| | | | | | | | | | | | | >--+ statement-list
| | | | | | | | | | | | | | >--* epsilon
| | | | | | | | | | | | | >--* }
| | | | | | | | | | | >--* else
| | | | | | | | | | | >--+ statement
| | | | | | | | | | | | >--+ compound-stmt
| | | | | | | | | | | | | >--* {
| | | | | | | | | | | | | >--+ local-declarations
| | | | | | | | | | | | | | >--* epsilon
| | | | | | | | | | | | | >--+ statement-list
| | | | | | | | | | | | | | >--* epsilon
| | | | | | | | | | | | | >--* }
| | | | | | >--+ statement
| | | | | | | >--+ return-stmt
| | | | | | | | >--* return
| | | | | | | | >--+ expression
| | | | | | | | | >--+ simple-expression
| | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | >--+ term
| | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | >--+ integer
| | | | | | | | | | | | | | >--* 0
| | | | | | | | >--* ;
| | | | | >--* }
This diff is collapsed.
>--+ program
| >--+ declaration-list
| | >--+ declaration
| | | >--+ fun-declaration
| | | | >--+ type-specifier
| | | | | >--* int
| | | | >--* main
| | | | >--* (
| | | | >--+ params
| | | | | >--* void
| | | | >--* )
| | | | >--+ compound-stmt
| | | | | >--* {
| | | | | >--+ local-declarations
| | | | | | >--+ local-declarations
| | | | | | | >--* epsilon
| | | | | | >--+ var-declaration
| | | | | | | >--+ type-specifier
| | | | | | | | >--* int
| | | | | | | >--* array
| | | | | | | >--* [
| | | | | | | >--* 1
| | | | | | | >--* ]
| | | | | | | >--* ;
| | | | | >--+ statement-list
| | | | | | >--+ statement-list
| | | | | | | >--+ statement-list
| | | | | | | | >--* epsilon
| | | | | | | >--+ statement
| | | | | | | | >--+ expression-stmt
| | | | | | | | | >--+ expression
| | | | | | | | | | >--+ var
| | | | | | | | | | | >--* array
| | | | | | | | | | | >--* [
| | | | | | | | | | | >--+ expression
| | | | | | | | | | | | >--+ simple-expression
| | | | | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | | >--+ integer
| | | | | | | | | | | | | | | | | >--* 1
| | | | | | | | | | | >--* ]
| | | | | | | | | | >--* =
| | | | | | | | | | >--+ expression
| | | | | | | | | | | >--+ simple-expression
| | | | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | >--+ integer
| | | | | | | | | | | | | | | | >--* 0
| | | | | | | | | >--* ;
| | | | | | >--+ statement
| | | | | | | >--+ return-stmt
| | | | | | | | >--* return
| | | | | | | | >--+ expression
| | | | | | | | | >--+ simple-expression
| | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | >--+ term
| | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | >--+ integer
| | | | | | | | | | | | | | >--* 0
| | | | | | | | >--* ;
| | | | | >--* }
>--+ program
| >--+ declaration-list
| | >--+ declaration-list
| | | >--+ declaration
| | | | >--+ fun-declaration
| | | | | >--+ type-specifier
| | | | | | >--* float
| | | | | >--* foo
| | | | | >--* (
| | | | | >--+ params
| | | | | | >--+ param-list
| | | | | | | >--+ param-list
| | | | | | | | >--+ param
| | | | | | | | | >--+ type-specifier
| | | | | | | | | | >--* float
| | | | | | | | | >--* a
| | | | | | | >--* ,
| | | | | | | >--+ param
| | | | | | | | >--+ type-specifier
| | | | | | | | | >--* float
| | | | | | | | >--* b
| | | | | | | | >--* [
| | | | | | | | >--* ]
| | | | | >--* )
| | | | | >--+ compound-stmt
| | | | | | >--* {
| | | | | | >--+ local-declarations
| | | | | | | >--* epsilon
| | | | | | >--+ statement-list
| | | | | | | >--+ statement-list
| | | | | | | | >--* epsilon
| | | | | | | >--+ statement
| | | | | | | | >--+ return-stmt
| | | | | | | | | >--* return
| | | | | | | | | >--+ expression
| | | | | | | | | | >--+ simple-expression
| | | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | >--+ integer
| | | | | | | | | | | | | | | >--* 1
| | | | | | | | | >--* ;
| | | | | | >--* }
| | >--+ declaration
| | | >--+ fun-declaration
| | | | >--+ type-specifier
| | | | | >--* int
| | | | >--* main
| | | | >--* (
| | | | >--+ params
| | | | | >--* void
| | | | >--* )
| | | | >--+ compound-stmt
| | | | | >--* {
| | | | | >--+ local-declarations
| | | | | | >--* epsilon
| | | | | >--+ statement-list
| | | | | | >--+ statement-list
| | | | | | | >--* epsilon
| | | | | | >--+ statement
| | | | | | | >--+ return-stmt
| | | | | | | | >--* return
| | | | | | | | >--+ expression
| | | | | | | | | >--+ simple-expression
| | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | >--+ term
| | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | >--+ integer
| | | | | | | | | | | | | | >--* 0
| | | | | | | | >--* ;
| | | | | >--* }
>--+ program
| >--+ declaration-list
| | >--+ declaration
| | | >--+ fun-declaration
| | | | >--+ type-specifier
| | | | | >--* int
| | | | >--* main
| | | | >--* (
| | | | >--+ params
| | | | | >--* void
| | | | >--* )
| | | | >--+ compound-stmt
| | | | | >--* {
| | | | | >--+ local-declarations
| | | | | | >--+ local-declarations
| | | | | | | >--+ local-declarations
| | | | | | | | >--* epsilon
| | | | | | | >--+ var-declaration
| | | | | | | | >--+ type-specifier
| | | | | | | | | >--* int
| | | | | | | | >--* a
| | | | | | | | >--* ;
| | | | | | >--+ var-declaration
| | | | | | | >--+ type-specifier
| | | | | | | | >--* int
| | | | | | | >--* b
| | | | | | | >--* ;
| | | | | >--+ statement-list
| | | | | | >--+ statement-list
| | | | | | | >--+ statement-list
| | | | | | | | >--+ statement-list
| | | | | | | | | >--+ statement-list
| | | | | | | | | | >--* epsilon
| | | | | | | | | >--+ statement
| | | | | | | | | | >--+ expression-stmt
| | | | | | | | | | | >--+ expression
| | | | | | | | | | | | >--+ var
| | | | | | | | | | | | | >--* a
| | | | | | | | | | | | >--* =
| | | | | | | | | | | | >--+ expression
| | | | | | | | | | | | | >--+ simple-expression
| | | | | | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | | | >--+ integer
| | | | | | | | | | | | | | | | | | >--* 1
| | | | | | | | | | | >--* ;
| | | | | | | | >--+ statement
| | | | | | | | | >--+ expression-stmt
| | | | | | | | | | >--+ expression
| | | | | | | | | | | >--+ var
| | | | | | | | | | | | >--* b
| | | | | | | | | | | >--* =
| | | | | | | | | | | >--+ expression
| | | | | | | | | | | | >--+ simple-expression
| | | | | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | | >--+ integer
| | | | | | | | | | | | | | | | | >--* 1
| | | | | | | | | | >--* ;
| | | | | | | >--+ statement
| | | | | | | | >--+ selection-stmt
| | | | | | | | | >--* if
| | | | | | | | | >--* (
| | | | | | | | | >--+ expression
| | | | | | | | | | >--+ simple-expression
| | | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | >--+ var
| | | | | | | | | | | | | | | >--* a
| | | | | | | | | | | >--+ relop
| | | | | | | | | | | | >--* !=
| | | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | >--+ var
| | | | | | | | | | | | | | | >--* b
| | | | | | | | | >--* )
| | | | | | | | | >--+ statement
| | | | | | | | | | >--+ compound-stmt
| | | | | | | | | | | >--* {
| | | | | | | | | | | >--+ local-declarations
| | | | | | | | | | | | >--* epsilon
| | | | | | | | | | | >--+ statement-list
| | | | | | | | | | | | >--+ statement-list
| | | | | | | | | | | | | >--* epsilon
| | | | | | | | | | | | >--+ statement
| | | | | | | | | | | | | >--+ selection-stmt
| | | | | | | | | | | | | | >--* if
| | | | | | | | | | | | | | >--* (
| | | | | | | | | | | | | | >--+ expression
| | | | | | | | | | | | | | | >--+ simple-expression
| | | | | | | | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | | | | | >--+ var
| | | | | | | | | | | | | | | | | | | | >--* a
| | | | | | | | | | | | | | | | >--+ relop
| | | | | | | | | | | | | | | | | >--* ==
| | | | | | | | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | | | | | >--+ var
| | | | | | | | | | | | | | | | | | | | >--* b
| | | | | | | | | | | | | | >--* )
| | | | | | | | | | | | | | >--+ statement
| | | | | | | | | | | | | | | >--+ expression-stmt
| | | | | | | | | | | | | | | | >--* ;
| | | | | | | | | | | | | | >--* else
| | | | | | | | | | | | | | >--+ statement
| | | | | | | | | | | | | | | >--+ compound-stmt
| | | | | | | | | | | | | | | | >--* {
| | | | | | | | | | | | | | | | >--+ local-declarations
| | | | | | | | | | | | | | | | | >--* epsilon
| | | | | | | | | | | | | | | | >--+ statement-list
| | | | | | | | | | | | | | | | | >--+ statement-list
| | | | | | | | | | | | | | | | | | >--* epsilon
| | | | | | | | | | | | | | | | | >--+ statement
| | | | | | | | | | | | | | | | | | >--+ expression-stmt
| | | | | | | | | | | | | | | | | | | >--+ expression
| | | | | | | | | | | | | | | | | | | | >--+ var
| | | | | | | | | | | | | | | | | | | | | >--* a
| | | | | | | | | | | | | | | | | | | | >--* =
| | | | | | | | | | | | | | | | | | | | >--+ expression
| | | | | | | | | | | | | | | | | | | | | >--+ simple-expression
| | | | | | | | | | | | | | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | | | | | | | | | | | | | >--+ term
| | | | | | | | | | | | | | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | | | | | | | | | | | | | >--+ var
| | | | | | | | | | | | | | | | | | | | | | | | | | >--* b
| | | | | | | | | | | | | | | | | | | >--* ;
| | | | | | | | | | | | | | | | >--* }
| | | | | | | | | | | >--* }
| | | | | | >--+ statement
| | | | | | | >--+ return-stmt
| | | | | | | | >--* return
| | | | | | | | >--+ expression
| | | | | | | | | >--+ simple-expression
| | | | | | | | | | >--+ additive-expression
| | | | | | | | | | | >--+ term
| | | | | | | | | | | | >--+ factor
| | | | | | | | | | | | | >--+ integer
| | | | | | | | | | | | | | >--* 0
| | | | | | | | >--* ;
| | | | | >--* }
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment