diff --git a/docs/Design.md b/docs/Design.md index 343a693..c469581 100644 --- a/docs/Design.md +++ b/docs/Design.md @@ -1,4 +1,10 @@ # python裂解器设计思路——ZYM +## 开发步骤 +1. 编写底层工具,并测试(函数调用相关的简单测试)。 +2. 在不考虑函数调用的情况下,以链为单位编写、调试自动机 +3. 测试函数相关的底层工具 +4. 增加考虑有函数调用时的情况,以链为单位编写、调试自动机 + ## 模块划分 - `libs`、`generated`、`resources`目录:`libs`目录存放第三方库,其中int2048是我的上个大作业,用以提供大整数运算支持;json是提供json解析支持;clipp是提供命令行参数解析支持。ANTLR框架存放于`generated`、`resources`目录中。 - `test`目录:存放测试相关,有一个进程级测试调度核心及相关配置文件、数据点,通过ctest_config接入CTest框架使得CTest可以调用进程级测试调度核心 @@ -9,10 +15,11 @@ ### 控制流 控制流:在数值(包括None)返回值的基础上,新增一个控制类型的范围值,不添加任何不必要的封装直接存入`std::any`,用控制类型这个类型本身标明身份。 -### 函数调用 +### 函数的定义与调用 ### 变量的生效范围与作用域 ## 关键细节 ### 元组 -### 左值和右值 \ No newline at end of file +### 左值和右值 +### 函数传参 \ No newline at end of file diff --git a/docs/MyFAQ.md b/docs/MyFAQ.md index bf00565..52eebad 100644 --- a/docs/MyFAQ.md +++ b/docs/MyFAQ.md @@ -1 +1,3 @@ -- 代码树的accept函数没有定义,因此是不是在写Visitor的“具体Visit函数”时,访问子节点时也要直接调用“具体Visit函数”? \ No newline at end of file +- 代码树的accept函数有定义 +- 没有代码块级作用域,变量注销只发生在函数级作用域退出时 +- 全局作用域无需global即可访问,因此,局部变量覆盖全局变量的唯一方式是通过函数参数列表覆盖。 \ No newline at end of file diff --git a/docs/grammar.md b/docs/grammar.md index 226ab12..719c9a0 100644 --- a/docs/grammar.md +++ b/docs/grammar.md @@ -130,11 +130,7 @@ not #### 8.3. 赋值表达式 -- 语法与具体行为均可以参照 C++,并无特殊差异 - 给一个变量赋值的意义是将这个变量指向右值,右值不管类型 -- **与标准 Python 不同,全局变量的生效范围是全部范围**(不用 global 关键字即可访问) -- 局部变量的生效范围是在当前语句块(被缩进和取消缩进包起来的部分),具体局部变量和全局变量划分规则和 C++ 一样 -- **只有函数的定义会产生新的作用域**,作用域的产生请参考 Python - 如 `a=1,a=”123”,a=1.1` 这三条语句依次执行,再输出 `a`,结果是 `1.1`,允许变量遮蔽 - 可以给多变量赋值,如 `a,b=1,2` 意思是 `a=1,b=2` 依次执行,此处或与标准 Python **不同** - 增量赋值即为普通算术运算的简化表达,具体行为参考 C++ @@ -237,3 +233,11 @@ func(parameters) - `bool`: 将 `int` 或 `float` 或 `str` 转成 `bool`。对于 `str`,如果是 `""` 则为 `False`,否则为 `True`。 - 转型类函数都只有一个参数。 + +### 12. 作用域 + +作用域相关规则: +- **与标准 Python 不同,全局变量的生效范围是全部范围**(不用 global 关键字即可访问) +- **只有函数的调用会产生新的作用域**,作用域的产生请参考 Python +- 没有代码块级作用域,变量注销只发生在函数级作用域退出时 +- 全局作用域无需global即可访问,因此,局部变量覆盖全局变量的唯一方式是通过函数参数列表覆盖。 diff --git a/include/Evalvisitor.h b/include/Evalvisitor.h index 425dfc0..3504df4 100644 --- a/include/Evalvisitor.h +++ b/include/Evalvisitor.h @@ -3,9 +3,7 @@ #define PYTHON_INTERPRETER_EVALVISITOR_H #include -#include #include -#include #include "Python3ParserBaseVisitor.h" #include "int2048/int2048.h" @@ -53,26 +51,4 @@ class EvalVisitor : public Python3ParserBaseVisitor { std::any visitArglist(Python3Parser::ArglistContext *ctx) override; std::any visitArgument(Python3Parser::ArgumentContext *ctx) override; }; -class InterpretException : public std::exception { - public: - InterpretException() {} - InterpretException(const char *message) : m_message(message) {} - - const char *what() const noexcept override { return m_message; } - - ~InterpretException() noexcept override {} - - private: - const char *m_message; -}; - -class FatalError : public std::exception { - public: - FatalError(const char *message) : m_message(message) {} - - const char *what() const noexcept override { return m_message; } - - private: - const char *m_message; -}; #endif // PYTHON_INTERPRETER_EVALVISITOR_H diff --git a/include/names.h b/include/names.h index 8f17398..08e55c5 100644 --- a/include/names.h +++ b/include/names.h @@ -6,7 +6,17 @@ #include #include +#include "utils.h" + class NameScopeClass { ; }; +struct FunctionItem +{ + ; +}; +struct FucntionContainer +{ + ; +}; #endif \ No newline at end of file diff --git a/include/utils.h b/include/utils.h index e69de29..5995fb2 100644 --- a/include/utils.h +++ b/include/utils.h @@ -0,0 +1,39 @@ +#ifndef UTILS_H +#define UTILS_H +#include +#include +#include +#include +class InterpretException : public std::exception { + public: + InterpretException() {} + InterpretException(const char *message) : m_message(message) {} + + const char *what() const noexcept override { return m_message; } + + ~InterpretException() noexcept override {} + + private: + const char *m_message; +}; + +class FatalError : public std::exception { + public: + FatalError(const char *message) : m_message(message) {} + + const char *what() const noexcept override { return m_message; } + + private: + const char *m_message; +}; +enum FlowControlStatusType { BREAK, CONTINUE, RETURN }; +struct FlowType { + FlowControlStatusType Status; + // TODO: return lists + std::vector ReturnValueLists; + FlowType() {} + FlowType(FlowControlStatusType Status) : Status(Status) {} + FlowType(FlowControlStatusType Status, std::vector ReturnValueLists) + : Status(Status), ReturnValueLists(ReturnValueLists) {} +}; +#endif \ No newline at end of file diff --git a/src/Evalvisitor.cpp b/src/Evalvisitor.cpp index 1642405..39b6b8e 100644 --- a/src/Evalvisitor.cpp +++ b/src/Evalvisitor.cpp @@ -3,10 +3,14 @@ #include #include +#include "Python3ParserBaseVisitor.h" #include "int2048/int2048.h" #include "names.h" #include "utils.h" +NameScopeClass GlobalScope, StackScope; +FucntionContainer Functions; + std::any EvalVisitor::visitFile_input(Python3Parser::File_inputContext *ctx) { return visitChildren(ctx); } @@ -29,7 +33,6 @@ std::any EvalVisitor::visitTfpdef(Python3Parser::TfpdefContext *ctx) { } std::any EvalVisitor::visitStmt(Python3Parser::StmtContext *ctx) { - std::cerr << "visitStmt\n" << std::endl; return visitChildren(ctx); } @@ -54,15 +57,16 @@ std::any EvalVisitor::visitFlow_stmt(Python3Parser::Flow_stmtContext *ctx) { } std::any EvalVisitor::visitBreak_stmt(Python3Parser::Break_stmtContext *ctx) { - return visitChildren(ctx); + return FlowType(BREAK); } std::any EvalVisitor::visitContinue_stmt( Python3Parser::Continue_stmtContext *ctx) { - return visitChildren(ctx); + return FlowType(CONTINUE); } std::any EvalVisitor::visitReturn_stmt(Python3Parser::Return_stmtContext *ctx) { + throw FatalError("Not implemented in function visitReturn_stmt"); return visitChildren(ctx); } diff --git a/src/names.cpp b/src/names.cpp index 623ae4f..a2f9e3d 100644 --- a/src/names.cpp +++ b/src/names.cpp @@ -1 +1,3 @@ -#include "names.h" \ No newline at end of file +#include "names.h" + +#include "utils.h" \ No newline at end of file diff --git a/src/utils.cpp b/src/utils.cpp index e69de29..cab9269 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -0,0 +1 @@ +#include "utils.h" \ No newline at end of file