From aa0c66780c17c17e94884ea8df0e02bc7bd14dca Mon Sep 17 00:00:00 2001 From: chentianya Date: Wed, 26 Aug 2026 17:53:25 +0800 Subject: [PATCH] =?UTF-8?q?=E6=AD=A5=E9=AA=A41=EF=BC=9AVAR=5FTEMP=20?= =?UTF-8?q?=E8=AF=8D=E6=B3=95+=E8=AF=AD=E6=B3=95=E6=94=AF=E6=8C=81?= =?UTF-8?q?=EF=BC=88token/=E5=85=B3=E9=94=AE=E5=AD=97/VarSection::Temp/?= =?UTF-8?q?=E4=BF=9D=E7=95=99=E5=AD=97=E6=94=BE=E8=A1=8C=EF=BC=89+=20?= =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- compiler/include/compiler/Lexer.h | 1 + compiler/include/compiler/Parser.h | 4 ++-- compiler/src/Lexer.cpp | 1 + compiler/src/Parser.cpp | 8 +++++--- tests/src/lexer_test.cpp | 11 +++++++++++ tests/src/parser_test.cpp | 31 ++++++++++++++++++++++++++++++ 6 files changed, 51 insertions(+), 5 deletions(-) diff --git a/compiler/include/compiler/Lexer.h b/compiler/include/compiler/Lexer.h index d19462a..7246bfb 100644 --- a/compiler/include/compiler/Lexer.h +++ b/compiler/include/compiler/Lexer.h @@ -35,6 +35,7 @@ namespace compiler { VAR_OUTPUT, ///< 输出变量段起始 VAR_GLOBAL, ///< 全局变量段起始 VAR_EXTERNAL, ///< 外部变量段起始 + VAR_TEMP, ///< 临时变量段起始(VAR_TEMP) END_VAR, ///< 变量段结束 BOOL, ///< 布尔类型 BYTE, ///< 位串类型(8 位) diff --git a/compiler/include/compiler/Parser.h b/compiler/include/compiler/Parser.h index e1cf3c3..a0027d6 100644 --- a/compiler/include/compiler/Parser.h +++ b/compiler/include/compiler/Parser.h @@ -53,9 +53,9 @@ namespace compiler { /** * @brief 变量段种类。 * @details 枚举值:Local=VAR、Input=VAR_INPUT、Output=VAR_OUTPUT、 - * Global=VAR_GLOBAL、External=VAR_EXTERNAL。 + * Global=VAR_GLOBAL、External=VAR_EXTERNAL、Temp=VAR_TEMP。 */ - enum class VarSection { Local, Input, Output, Global, External }; + enum class VarSection { Local, Input, Output, Global, External, Temp }; /** * @brief 一段 VAR_* … END_VAR:段种类 + 声明列表。 diff --git a/compiler/src/Lexer.cpp b/compiler/src/Lexer.cpp index 6b01023..d96e682 100644 --- a/compiler/src/Lexer.cpp +++ b/compiler/src/Lexer.cpp @@ -60,6 +60,7 @@ namespace { {"var_output", Tok::VAR_OUTPUT}, {"var_global", Tok::VAR_GLOBAL}, {"var_external", Tok::VAR_EXTERNAL}, + {"var_temp", Tok::VAR_TEMP}, {"end_var", Tok::END_VAR}, // 类型(V2:19 种 IEC 类型) {"bool", Tok::BOOL}, diff --git a/compiler/src/Parser.cpp b/compiler/src/Parser.cpp index d918be2..4000056 100644 --- a/compiler/src/Parser.cpp +++ b/compiler/src/Parser.cpp @@ -64,7 +64,7 @@ namespace { * 用户标识符(详见 Doc/compiler/语法.md)。 */ const char* const kForbidden[] = { - "var_in_out", "var_temp", "ref", "class", "any", + "var_in_out", "ref", "class", "any", "pointer", "interface", "method", }; @@ -306,8 +306,8 @@ namespace { } /** - * @brief 当前 token 是否为五种变量段关键字之一 - * @return true 为 VAR / VAR_INPUT / VAR_OUTPUT / VAR_GLOBAL / VAR_EXTERNAL + * @brief 当前 token 是否为六种变量段关键字之一 + * @return true 为 VAR / VAR_INPUT / VAR_OUTPUT / VAR_GLOBAL / VAR_EXTERNAL / VAR_TEMP */ bool is_var_section() const { switch (type()) { @@ -316,6 +316,7 @@ namespace { case Tok::VAR_OUTPUT: case Tok::VAR_GLOBAL: case Tok::VAR_EXTERNAL: + case Tok::VAR_TEMP: return true; default: return false; @@ -358,6 +359,7 @@ namespace { case Tok::VAR_OUTPUT: b->section = VarSection::Output; break; case Tok::VAR_GLOBAL: b->section = VarSection::Global; break; case Tok::VAR_EXTERNAL: b->section = VarSection::External; break; + case Tok::VAR_TEMP: b->section = VarSection::Temp; break; default: return fail("expected variable section"); } diff --git a/tests/src/lexer_test.cpp b/tests/src/lexer_test.cpp index 2e0cca5..175ed92 100644 --- a/tests/src/lexer_test.cpp +++ b/tests/src/lexer_test.cpp @@ -197,7 +197,18 @@ static bool test_line1() { return true; } +static bool test_var_temp_kw() { + using namespace compiler; + std::vector ts; + std::string err; + CHECK(lex("t.st", "VAR_TEMP", &ts, &err)); + CHECK(!ts.empty()); + CHECK(ts[0].type == Tok::VAR_TEMP); + return true; +} + int main() { + if (!test_var_temp_kw()) return 1; if (!test_basic()) return 1; if (!test_case()) return 1; if (!test_symbols()) return 1; diff --git a/tests/src/parser_test.cpp b/tests/src/parser_test.cpp index 52954e8..612b752 100644 --- a/tests/src/parser_test.cpp +++ b/tests/src/parser_test.cpp @@ -289,7 +289,38 @@ static bool test_negative() { return true; } +// ---- VAR_TEMP 段:解析为 VarSection::Temp ---- + +static bool test_var_temp() { + using namespace compiler; + Unit u; + std::string err; + CHECK(parse_pous("t.st", + "FUNCTION_BLOCK Foo\n" + "VAR_INPUT\n in : BOOL;\nEND_VAR\n" + "VAR_OUTPUT\n out : BOOL;\nEND_VAR\n" + "VAR\n state : BOOL;\nEND_VAR\n" + "VAR_TEMP\n tmp : INT;\nEND_VAR\n" + " out := tmp > 0;\n" + "END_FUNCTION_BLOCK", + &u, &err)); + CHECK(u.pous.size() == 1); + const POU& p = u.pous[0]; + CHECK(p.kind == PouKind::FunctionBlock); + CHECK(p.blocks.size() == 4); + CHECK(p.blocks[0].section == VarSection::Input); + CHECK(p.blocks[1].section == VarSection::Output); + CHECK(p.blocks[2].section == VarSection::Local); + CHECK(p.blocks[3].section == VarSection::Temp); + CHECK(p.blocks[3].vars.size() == 1); + CHECK(p.blocks[3].vars[0].name == "tmp"); + CHECK(p.blocks[3].vars[0].type.kind == TypeKind::Scalar); + CHECK(p.blocks[3].vars[0].type.name == "int"); + return true; +} + int main() { + if (!test_var_temp()) return 1; if (!test_gvl_file()) return 1; if (!test_fb()) return 1; if (!test_program()) return 1;