- 编程语言
- 编译器
- 开发工具
【免费下载链接】grammars-v4
Grammars written for ANTLR v4; expectation that the grammars are free of actions.
本文基于 grammars-v4 仓库中asm/asmMASM目录下的 MASM(Microsoft Macro Assembler)语法文件及其配套示例,系统讲解这份 ANTLR4 语法如何建模 MASM 汇编源文件、其核心语法规则设计与词法实现,并结合仓库中的真实示例程序说明解析器的运行方式、构建与测试方法。读完本文,你将掌握该语法支持的语言子集、行级与表达式级解析结构,以及如何在本仓库环境中编译验证它。
一、项目背景:为 MASM 汇编语言编写 ANTLR4 语法
asm/asmMASM是 grammars-v4 仓库中为 MASM(Microsoft Macro Assembler)文件编写的 ANTLR4 语法模块。其 README 明确说明:该语法面向 MASM 汇编源文件,当前尚未完全覆盖全部 MASM 特性("This grammar is not currently complete"),并欢迎社区以 Pull Request 方式完善。这一状态决定了阅读本语法时,应以"已支持子集"而非"完整实现"的视角看待其能力边界。
从目录结构看,该模块包含:
- asmMASM.g4:唯一的语法源文件(词法规则 + 语法规则合并在同一文件中);
- examples/:三个示例程序
hello.asm、helloworld.asm、powers.asm,另有根目录下的 helloworld2.asm; - 8086-opcodes.txt 与 8086-registers.txt:分别记录了语法中枚举的 8086 指令助记符与寄存器名列表;
- desc.xml:声明语法要求的 ANTLR 版本(
^4.10)与可生成的目标语言; - pom.xml:Maven 构建与自动化测试配置。
二、语法总体结构:从prog到line的行式模型
MASM 源文件本质上是"逐行书写"的文本,因此语法入口prog将整个文件建模为一组以行尾符(EOL)分隔的行:
prog : line* EOF ; line : (lbl | endlbl)? (assemblerdirective | masmdirectives | instruction)? EOL ;从源码结构看(见 asmMASM.g4),每条line由三个可选部分构成:
- 可选的标签:
lbl(普通标签,冒号可选)或endlbl(END伪指令,可带程序名); - 可选的核心内容,三者取其一:
assemblerdirective:经典汇编器伪指令(ORG、EQU、DB/DW等);masmdirectives:以点号开头的 MASM 专有指令(.386、.model、.data、.code等);instruction:一条真正的机器指令;
- 行尾符
EOL([\r\n]+),保证每一行都被显式终结。
三、指令与伪指令的语法规则
3.1 汇编器伪指令assemblerdirective
assemblerdirective规则聚合了多种经典 MASM 伪指令(asmMASM.g4):
assemblerdirective : org | if_ | endif_ | equ | db | dw | dm | ds | include | includelib | invoke | option | put | assign | segment | endsegment | group | label_ | assume | extern_ | public_ | type_ expressionlist+ ;各分支的细粒度规则(同文件 L95-L197)定义了它们的参数形态:
| 伪指令 | 规则形态 | 说明 |
|---|---|---|
ORG | ORG expression | 设置位置计数器 |
EQU | EQU expression | 常量等值定义 |
DB/DW/DM/DS | 后跟expressionlist | 数据定义伪指令 |
INCLUDE/INCLUDELIB | 后跟expressionlist | 引入头文件 / 导入库 |
INVOKE | INVOKE expressionlist | 调用带参数的过程 |
OPTION | OPTION expressionlist | 汇编器选项 |
ASSIGN | name ASSIGN expression(=) | 赋值 |
SEGMENT/ENDS | 段定义与段结束,SEGMENT后可带align | 段结构 |
GROUP | name GROUP name (, name)* | 段分组 |
ASSUME | ASSUME register_ ':' name (, ...)* | 段寄存器假设 |
EXTERN/PUBLIC | 后跟表达式 | 外部符号 / 公开符号 |
LABEL | name LABEL type_ | 类型化标签 |
IF/ENDIF | 条件汇编 | 条件伪指令 |
其中type_目前只支持四种数据类型(asmMASM.g4):
type_ : BYTE | SBYTE | WORD | DWORD ;而SEGMENT后的align除了支持BYTE/WORD/DWORD/PARA/PAGE关键字外,还允许ALIGN '(' number ')'这种带括号参数的写法(asmMASM.g4),说明语法在设计上预留了参数化对齐能力。
3.2 MASM 点号指令masmdirective
MASM 的现代指令(处理器选择、模型声明、段声明等)以点号开头,语法用一条词法规则统一捕获:
masmdirective : MASMDIRECTIVE expressionlist? ; MASMDIRECTIVE : '.' [A-Z0-9]+ ;结合options { caseInsensitive = true; }(asmMASM.g4),.386、.model、.data、.code、.stack等均可被MASMDIRECTIVE识别,后面可跟可选的参数表达式列表。这正是示例helloworld.asm中.model flat, stdcall、.data、.code的解析依据。
3.3 指令行instruction与重复前缀
instruction : rep? opcode expressionlist? ; rep : REP ;REP词法规则涵盖REP/REPE/REPNE/REPNZ/REPZ五种形式(asmMASM.g4),可作为指令前缀;其后是opcode(即OPCODE词法枚举)与可选的操作数表达式列表。
四、表达式系统:从expression到argument的层级
语法为操作数表达式设计了完整的优先级层级(asmMASM.g4):
expression : multiplyingExpression (SIGN multiplyingExpression)* // 加减 ; multiplyingExpression : argument (('*' | '/') argument)* // 乘除 ; argument : number | dollar // $ | ques // ? | register_ // 寄存器 | (name ':')? name // 段前缀:名字 | string | '(' expression ')' // 括号 | '[' expression ']' // 方括号寻址 | NOT expression // 逻辑非 | OFFSET expression // 取偏移 | gross // 借用作名字的助记符 | dup // DUP 重复 ;argument支持的操作数形态非常丰富:
number:允许带符号(SIGN? NUMBER),其中NUMBER词法为[0-9A-F]+ 'H'?,即同时接受十进制与带H后缀的十六进制字面量;dollar($)与ques(?,未初始化数据占位符);- 寄存器引用
register_; name ':' name形式的段前缀限定名(如es:di);- 单引号或双引号字符串
string(STRING1/STRING2); - 圆括号子表达式、方括号内存寻址;
NOT、OFFSET一元运算;dup:number DUP expression,用于数据重复声明;gross:允许把指令助记符当作名字使用(见下文)。
五、关键设计亮点:gross规则与大小写不敏感
5.1 助记符可作标识符的gross规则
MASM 语法允许RET这类助记符充当标签名,也允许PUT这类伪指令关键字充当名字。语法在注释中明确记录了这一点(asmMASM.g4),并为此设计了gross规则:
gross : opcode | grossrawassemblerdirective ; grossrawassemblerdirective : PUT | IF | ENDIF | ORG | EQU ;label规则(name | gross)正是通过引入gross让这些保留字仍可作为标签名,从而贴近真实 MASM 的容错习惯。
5.2 大小写不敏感与注释处理
语法顶层开启了caseInsensitive = true,因此MOV、mov、Mov均被同一规则匹配。词法层面,注释以分号;起始并被-> skip跳过,空白(空格与制表符)同样跳过,行尾EOL保留作为行的终结符(asmMASM.g4)。
5.3 指令集与寄存器枚举
OPCODE词法规则(asmMASM.g4)以枚举方式列出全部支持的指令助记符(AAA、AAD、AAM、ADD、CALL、MOV、PUSH、POP、各类 Jcc 条件跳转、LOOP 系列、字符串指令 MOVSB/STOSB 等),与仓库中 8086-opcodes.txt 记录的清单一致;REGISTER枚举(asmMASM.g4)覆盖 8 位(AH/AL/BH/BL/CH/CL/DH/DL)、16 位(AX/BX/CX/DX)及段/指针寄存器(CS/DS/ES/SS/SP/BP/IP/DI/SI),与 8086-registers.txt 完全对应。由于指令集以枚举形式硬编码,新增指令需同步修改OPCODE规则,这既是当前"未完整覆盖 MASM"的主要原因,也是社区贡献 PR 的主要切入点。
六、实战示例:仓库自带的四个 MASM 程序
6.1 hello.asm:纯 Win32 API 调用
examples/hello.asm 头部注释给出了完整的汇编/链接命令:
Assemble with "ml hello.asm /c" Link with "link hello kernel32.lib /subsystem:console /entry:go"该程序不使用 C 库,直接调用 kernel32.dll 的GetStdHandle、WriteConsoleA、ExitProcess,需要导入库 kernel32.lib。文件同时展示了语法支持的多种要素:.386P/.model flat(点号指令)、extern/public伪指令、byte/dword数据定义、?未初始化占位符、offset操作符以及end行。
6.2 helloworld.asm:INVOKE 与 INCLUDE 用法
examples/helloworld.asm 展示了 MASM 高级宏风格:option casemap: none、include/includelib、invoke MessageBox, ...调用约定以及end start指定入口。语法中INVOKE expressionlist与INCLUDE/INCLUDELIB规则正是为这类代码设计。
6.3 powers.asm:循环打印 2 的幂
examples/powers.asm 依赖 Microsoft 兼容 C 库(libc.lib),由mainCRTStartup调用_main。程序用esi/edi保存状态,jnz L1循环 32 次调用_printf打印 2^0 到 2^31,演示了mov、push/pop、call、add、dec、jnz、ret等指令与标签L1、format:的解析。
6.4 helloworld2.asm:PROC/ENDP 与 .while 结构
根目录下的 helloworld2.asm 更进一步,包含WinMain PROC, .../ENDP过程定义、LOCAL msg:MSG、addr操作符以及.while TRUE/.break .if (ax == 0)/.endw宏结构。需要说明的是,PROC、ENDP、.while等结构目前并未在语法规则中显式建模,这类代码能否完整解析取决于MASMDIRECTIVE与gross等规则的匹配效果——这也印证了 README 中"语法尚不完整"的声明。
七、构建与自动化测试
模块采用 Maven 管理(pom.xml),关键配置如下:
- 语法生成:
antlr4-maven-plugin以asmMASM.g4为唯一输入,开启visitor与listener两种访问器生成; - 自动化测试:
antlr4test-maven-plugin将prog作为入口规则、asmMASM作为语法名,自动解析 examples/ 目录下的全部示例文件,作为语法的回归验证; - 版本与目标语言:desc.xml 声明语法基于 ANTLR
^4.10,可生成 CSharp、Cpp、Dart、Go、Java、JavaScript、PHP、Python3、TypeScript、Antlr4ng 共 10 种目标语言。
八、已知边界与后续扩展方向
综合 README 声明与源码结构,可以总结出该语法的当前边界:
- 指令集不全:
OPCODE采用硬编码枚举,仅覆盖 8086 指令子集,更现代的指令(如 32/64 位扩展指令)需扩展枚举; - 类型系统有限:
type_仅支持BYTE/SBYTE/WORD/DWORD; - 宏与高级结构欠缺:
PROC/ENDP、.while/.if等 MASM 宏结构未显式建模; - 表达式优先级:当前表达式层级支持加减乘除、括号、方括号寻址、
NOT/OFFSET,但缺少SHL/SHR、AND/OR/XOR等按位运算层级。
由于仓库是只读镜像,开发者若需完善语法,可在本地 fork 后修改asmMASM.g4,并保持prog入口与示例文件的可解析性,通过antlr4test-maven-plugin持续回归验证——这正是该项目"PR 欢迎"的协作模式所期望的贡献流程。
九、小结
asm/asmMASM提供了一份结构清晰、面向 MASM 汇编语言核心子集的 ANTLR4 语法:行式模型prog → line契合汇编文本形态,assemblerdirective/masmdirective/instruction三路分支覆盖经典伪指令、点号指令与机器指令,表达式层级与gross规则体现了对真实 MASM 语义(助记符可作标识符、大小写不敏感)的建模取舍,四个示例程序则为解析器提供了可运行的验证语料。对于需要在工具链中解析 MASM 源码、或希望为汇编语言构建 ANTLR 语法的开发者,这是一份兼具参考价值与扩展空间的实现样板。
- 编程语言
- 编译器
- 开发工具
【免费下载链接】grammars-v4
Grammars written for ANTLR v4; expectation that the grammars are free of actions.
相关推荐
grammars-v4 中的 ABB RAPID 工业机器人语言 ANTLR4 语法:结构、解析与实战示例
grammars v4 中的 ABB RAPID 工业机器人语言 ANTLR4 语法:结构、解析与实战示例 导读 本文以开源仓库 grammars v4 中 a
编程语言编译器开发工具ANTLR4语法文件结构深度解析
ANTLR4语法文件结构深度解析 ANTLR4作为一款强大的语法分析器生成工具,其核心在于语法文件的编写。本文将全面解析ANTLR4语法文件的结构组成,帮助开发
开发工具编程语言编译器如何在MASM汇编中使用COMM指令:从零开始的完整指南
如何在MASM汇编中使用COMM指令:从零开始的完整指南 在MASM汇编语言中,COMM指令是实现模块化编程的重要工具,它允许开发者创建可在多个模块间共享的未初
文档/教程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考