1. 词法分析器
函数
- skip_one_line: 跳过一行, 会在skip_comment中注释为//的时候调用
- skip_comment: // 和 /**/
- skip_blanks: 跳过空白行, 会在skip_comment处理完注释之后调用, 同时在get_next_token这个核心的词法分析器的接口函数中调用防止获取到的token含有空白字符
- to_next_char: 将parser中的next_char_ptr指向的字符赋给cur_char, 并++next_char_ptr
- to_next_char_if: 和to_next_char类似, 返回类型为bool类型, 当nextchar是我们期望的值的时候调用to_next_char并返回true, 否则直接返回false
- peek_next_char: *parser->next_char_ptr
- peek_cur_char: parser->cur_char
- get_next_token: 给语法分析器调用的函数, 在get_next_token函数中主要由一个伪while循环(之所以是伪while循环, 是因为在while的结尾有return语句), 里面还有continue语句, 主要在遇到了注释, 调用了skip_comment之后continue继续获取Token, 因为注释并不是我们的token, 它是无用的; 在while中有switch case语句, 主要是通过字符判断token的类型, 这是parser->cur_token.type的值
- parser_id: 解析id, 在该函数中, 会调用is_id_or_keyword, 来判断TokenType到底是id还是keyword
- is_id_or_keyword: 会在parser_id中调用
- parse_string: 解析字符串, 注意转义字符的处理, 有switch case
- parse_num: 解析hex, dec, oct类型的token, 在该函数中调用根据前缀(0x, 0)判断, 调用对应的parse_hex, parse_dec, parse_oct, 在这写函数用主要用到C标准库中的strtol和strtod将字符串转为对应禁止的数字, 通过isxdigit和isdigit函数判断是否一个字符是合法的进制字符
- consume_token: 和match_token一样, 这是如果不匹配就会直接退出进程
数据结构
| |
| typedef Parser { |
| const char *fname; |
| const char *source; |
| Token cur_token; |
| Token pre_token; |
| char cur_char; |
| char *next_char_ptr; |
| VM *vm; |
| } Parser; |
- Token, 简而言之就是字符串加上Token的类型
| |
| typedef struct Token { |
| TokenType type; |
| |
| char *ptr; |
| unsigned int length; |
| unsigned int line_no; |
| |
| Value value; |
| |
| } Token; |
- TokenType, 一个包含着Token类型的enum
| |
| typedef enum TokenType { |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| } TokenType; |
| |
| typedef struct VM { |
| Class *string_class; |
| Class *fn_class; |
| Class *num_class; |
| Class *bool_class; |
| Class *thread_class; |
| Class *class_class; |
| Class *list_class; |
| Class *map_class; |
| Class *range_class; |
| |
| Parser *cur_parser; |
| int allocated_bytes; |
| ObjHeader *all_objects; |
| ObjThread *cur_thread; |
| ObjModule *modules; |
| MethodBuffer allMethodNames; |
| } VM; |
| |
| 方法 |
| initVM |
| newVM, 在newVM中会调用initVM, 紧接着就调用buildCore函数, 在buildCore函数中会调用defineClass函数, 定义出内置的ObjectClass, ObjectMetaClass, ClassOfClass类, 并为他们绑定方法(C语言上的函数), 接着executeModule加载执行核心模块 |
注意
- 词法分析器不负责解析时候的报错, 报错是交给编译模块的
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ThreeJs-16智慧城市项目(重磅以及未来发展ai)
· 软件产品开发中常见的10个问题及处理方法
· Vite CVE-2025-30208 安全漏洞
· MQ 如何保证数据一致性?
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(四):结合BotSharp