- Parser.h/cpp:POU 外壳(PROGRAM/FUNCTION/FUNCTION_BLOCK)、变量段、语句(赋值/IF/WHILE/FB 调用)、表达式优先级爬升(NOT/AND/OR 短路/比较/算术/函数调用/负号) - Unit 结构:顶层 VAR_GLOBAL 段(GVL 文件形态)+ POU 列表 - 拒绝:VAR_IN_OUT/REF/CLASS/ANY 等保留名、链式比较、FB 字段赋值、顶层非 GVL 段 - THEN/DO 补入关键字表(12.5 修订,同步 12.1 与词法文档) - parser_test:98 断言(line1 三文件 AST、FUNCTION 调用、IF/WHILE/TON、9 类负例),ctest 6/6
92 lines
2.2 KiB
C++
92 lines
2.2 KiB
C++
/**
|
||
* @file Lexer.h
|
||
* @brief ST 子集词法分析
|
||
* @author
|
||
* @date 2026-08-21
|
||
*/
|
||
|
||
#pragma once
|
||
|
||
#include <cstdint>
|
||
#include <string>
|
||
#include <vector>
|
||
|
||
namespace compiler {
|
||
|
||
// token 类型。关键字与 token 集见 Doc/compiler/词法.md。
|
||
enum class Tok {
|
||
// 关键字(25 个,与 12.1 冻结表一致)
|
||
PROGRAM,
|
||
FUNCTION,
|
||
FUNCTION_BLOCK,
|
||
END_PROGRAM,
|
||
END_FUNCTION,
|
||
END_FUNCTION_BLOCK,
|
||
VAR,
|
||
VAR_INPUT,
|
||
VAR_OUTPUT,
|
||
VAR_GLOBAL,
|
||
VAR_EXTERNAL,
|
||
END_VAR,
|
||
BOOL,
|
||
INT,
|
||
TIME,
|
||
IF,
|
||
ELSIF,
|
||
ELSE,
|
||
END_IF,
|
||
WHILE,
|
||
END_WHILE,
|
||
THEN, // 12.5 修订:IF/WHILE 语法需要,补入关键字表
|
||
DO, // 同上
|
||
AND,
|
||
OR,
|
||
NOT,
|
||
TRUE,
|
||
FALSE,
|
||
TON,
|
||
TOF,
|
||
CTU,
|
||
// 字面量
|
||
IDENT, // text = 小写名
|
||
INT_LIT, // int_value
|
||
TIME_LIT, // int_value = 毫秒
|
||
// 符号
|
||
ASSIGN, // :=
|
||
EQ, // =
|
||
NE, // <>
|
||
LT, // <
|
||
LE, // <=
|
||
GT, // >
|
||
GE, // >=
|
||
PLUS, // +
|
||
MINUS, // -
|
||
STAR, // *
|
||
SLASH, // /
|
||
LPAREN, // (
|
||
RPAREN, // )
|
||
COMMA, // ,
|
||
SEMI, // ;
|
||
COLON, // :
|
||
DOT, // .
|
||
END, // 文件结束
|
||
};
|
||
|
||
struct Token {
|
||
Tok type;
|
||
std::string text; // 标识符/关键字的小写文本;字面量原文
|
||
int64_t int_value; // INT_LIT / TIME_LIT(毫秒)
|
||
std::string source_file;
|
||
uint32_t line; // 从 1 起
|
||
uint32_t col; // 从 1 起
|
||
};
|
||
|
||
// 对源文本 lex 成 token 流(含末尾 END)。失败返回 false,
|
||
// err 前缀 "lex error",带文件与行列。
|
||
bool lex(const std::string& source_file, const std::string& content,
|
||
std::vector<Token>* out, std::string* err);
|
||
|
||
// 读文件后 lex(文件不存在 / 读取失败也算 lex error)
|
||
bool lex_file(const std::string& path, std::vector<Token>* out, std::string* err);
|
||
}
|