- 编程语言
- 编译器
- 开发工具
【免费下载链接】grammars-v4
Grammars written for ANTLR v4; expectation that the grammars are free of actions.
本指南以 grammars-v4 仓库中的 angelscript 模块为核心,系统讲解其为 AngelScript 脚本语言编写的 ANTLR4 文法:从词法规则、语法规则的逐条拆解,到 Maven 构建、测试与命令行解析的完整使用链路。读完本文,你将能读懂这份 400 余行的.g4文件,理解它如何覆盖 AngelScript 的命名空间、类、接口、虚属性、模板、lambda、异常等语言特性,并学会在本仓库环境中直接生成解析器、运行示例、验证语法。
模块概览:一个"无动作"的纯文法实现
angelscript/README.md 用一句话定义了该模块的定位:为 AngelScript 语言编写的一份简洁 ANTLR4 文法("A simple ANTLR4 grammar for angelscript"),并指出其设计依据是 AngelScript 官方文档中的脚本 BNF 参考。这与 grammars-v4 仓库的整体约定一致——根目录即小写语言名,文法追求"free of actions",即不在文法中嵌入目标语言动作代码,保持纯文法可移植性(见仓库根 README.md)。
文法文件本身是模块的绝对主体:angelscript.g4(约 414 行,BSD 许可,2021 年由 Tom Everett 编写)。从源码结构看,它采用单一文件同时定义词法规则与语法规则,入口规则为start_(对应 Maven 测试配置中的 entryPoint),顶层结构由script规则承载:
grammar angelscript; start_ : script EOF ; script : ( import_ | enum_ | typdef | class_ | mixin_ | interface_ | funcdef | virtprop | var_ | func_ | namespace | ';' )+ ;script规则说明:一个 AngelScript 编译单元由若干顶层元素组成——导入语句、枚举、typedef、类、mixin、接口、funcdef、虚属性、全局变量、函数、命名空间,以及允许出现的空分号;。下面依次剖析这些语法面。
构建与目标:desc.xml 与 pom.xml 解读
模块的构建配置与多语言目标在以下两个文件中声明:
- angelscript/desc.xml:声明该文法支持生成的目标为
CSharp;Cpp;Dart;Go;Java;JavaScript;PHP;Python3;TypeScript;Antlr4ng,即仓库 CI 会对这 10 种 ANTLR 目标进行生成与编译验证。 - angelscript/pom.xml:作为 Maven 子模块接入仓库聚合构建(根 pom.xml 的
grammarv4profile 中注册了<module>angelscript</module>)。
pom.xml 中有两个关键插件配置值得注意:
- antlr4-maven-plugin:将
angelscript.g4作为唯一文法源(<include>angelscript.g4</include>),并显式开启visitor与listener两种遍历模式,意味着生成代码同时提供AngelscriptBaseVisitor与AngelscriptBaseListener,方便使用者以任意一种模式遍历解析树。 - antlr4test-maven-plugin:以
start_为入口规则(<entryPoint>start_</entryPoint>)、angelscript为文法名,对examples/目录下的示例文件做解析回归测试。
ANTLR 工具链版本由根 pom 统一管理(pom.xml 中antlr.version为 4.13.2,antlr4test-maven-plugin.version为 1.22),Maven 编译器目标为 Java 11。
词法规则:标识符、字面量、运算符与基础类型
词法层定义在文法文件后半部分,覆盖了 AngelScript 词法要素的完整集合。
标识符与数字/字符串/位字面量
IDENTIFIER : [a-zA-Z_] [a-zA-Z0-9_]* ; NUMBER : [0-9] '.' [0-9]+ ; STRING : '"' ~ '"'* '"' | '\'' ~ '\''* '\'' ; BITS : ('0b' | '0o' | '0d' | '0x' | '0B' | '0O' | '0D' | '0X') [0-9a-z] ; LITERAL : NUMBER | STRING | BITS | 'true' | 'false' | 'null' ;要点说明:
IDENTIFIER遵循 C 风格命名:字母或下划线开头,后接字母、数字或下划线。NUMBER只匹配带小数点的浮点形式([0-9] '.' [0-9]+),这是该文法在词法层的一个简化选择:从规则形式可推断,纯整数(如42)在表达式中并不直接作为 NUMBER 出现,整数常量可经由BITS(带进制前缀)或LITERAL之外的其他路径处理。STRING同时支持双引号与单引号包裹的字符串(~ '"'*表示不含引号的任意字符序列)。BITS支持0b/0o/0d/0x四种前缀(大小写均可),这是 AngelScript 表示二进制、八进制、十进制与十六进制整数字面量的方式;从规则看每个前缀后匹配一个[0-9a-z]字符,属于偏宽松的简化匹配。LITERAL汇总了 NUMBER、STRING、BITS 与true/false/null关键字,作为exprvalue的一个分支参与表达式解析。
运算符族:按优先级组织的五类 token
文法用五个独立 token 族承接运算符,并通过解析规则exprop组合成表达式:
exprop : MATHOP | COMPOP | LOGICOP | BITOP ;| 类别 | Token | 成员 |
|---|---|---|
| 位运算 | BITOP | &、\|、^、<<、>>、>>> |
| 算术 | MATHOP | +、-、*、/、\(整数除法)、**(幂) |
| 比较 | COMPOP | ==、!=、<、<=、>、>=、is、!is |
| 逻辑 | LOGICOP | &&、\|\|、^^、and、or、xor |
| 赋值 | ASSIGNOP | =、+=、-=、*=、/=、\|=、&=、^=、%=、**=、<<=、>>=、>>>= |
其中\对应 AngelScript 的整数除法运算符、**为幂运算、is/!is为类型判断、^^/and/or/xor为逻辑运算,这些都原样保留在词法规则中,体现了文法对语言 BNF 的忠实还原。
此外还有一元前缀运算符EXPRPREOP(-、+、!、++、--、~、@,其中@用于 handle 取址语义)以及函数属性关键字FUNCATTR(override、final、explicit、property)。
基础类型与空白处理
PRIMTYPE : VOID | 'int' | 'int8' | 'int16' | 'int32' | 'int64' | 'uint' | 'uint8' | 'uint16' | 'uint32' | 'uint64' | 'float' | 'double' | 'bool' ; COMMENT : '//' ~ [\r\n]* -> skip ; WS : [ \r\n\t]+ -> skip ;PRIMTYPE覆盖 AngelScript 的 14 种基础类型;VOID被定义为独立 fragment 级 token('void'),既供PRIMTYPE复用,也用于paramlist中表示无参数。COMMENT处理//行注释,WS跳过空白,二者均通过-> skip直接丢弃,不进入 token 流。
语法规则:类型系统与声明结构
类型描述:type_ / scope / datatype / typemod
AngelScript 类型系统在文法中由一组嵌套规则刻画:
type_ : 'const'? scope datatype ('<' type_ (',' type_)* '>')* ('[' ']' | '@' 'const'?)* ; scope : '::'? (IDENTIFIER '::')* (IDENTIFIER ('<' type_ (',' type_)* '>')? '::')? ; datatype : IDENTIFIER | PRIMTYPE | '?' | 'auto' ;datatype可以是自定义标识符、PRIMTYPE、?(未知类型)或auto(自动类型推断);scope表达::分隔的命名空间限定路径,并允许在路径段后携带模板实参(如MyNamespace::List<int>::);type_在最外层叠加const限定、模板参数列表('<' type_ (',' type_)* '>',可多重嵌套)、数组后缀[]与 handle 后缀@(可带const)。
paramlist与typemod则刻画参数列表及引用修饰:
paramlist : '(' ( VOID | type_ typemod IDENTIFIER? ('=' expr)? (',' type_ typemod IDENTIFIER? ('=' expr)?)* )? ')' ; typemod : ('&' ('in' | 'out' | 'inout')?)? ;参数可以是裸void(无参数),也可以是"类型 + 引用修饰 + 可选参数名 + 可选默认值"的重复序列;typemod允许&后跟in/out/inout,对应 AngelScript 的引用参数与方向修饰。
顶层声明:类、接口、枚举、typedef、导入、命名空间
文法为每种顶层声明定义了专用规则:
class_:可选shared/abstract/final/external修饰,支持前向声明(class Foo;)或完整定义;继承列表为':' IDENTIFIER (',' IDENTIFIER)*(单继承);类体由virtprop、func_、var_、funcdef组成。interface_:可选external/shared修饰,可继承多个接口,类体只允许virtprop与intfmthd(接口方法:type_ '&'? IDENTIFIER paramlist 'const'? ';')。mixin_:'mixin' class_,即 mixin 类声明直接复用完整类语法。enum_:可选shared/external,枚举成员支持IDENTIFIER ('=' expr)?的显式赋值,也允许空枚举体或前向声明。typdef:'typedef' PRIMTYPE IDENTIFIER ';',为内置类型起别名(注意:此处 typedef 的源类型仅限PRIMTYPE)。import_:'import' type_ '&'? IDENTIFIER paramlist FUNCATTR 'from' STRING ';',对应 AngelScript 从外部模块导入函数的语法。func_:函数声明,可选shared/external/private/protected修饰,返回类型可为type_ '&'?或析构'~',后跟参数列表、const限定与FUNCATTR,函数体可为';'(纯声明)或statblock。var_:变量声明,支持private/protected、多变量逗号列表、= initlist/expr或构造参数arglist的初始化。virtprop:虚属性块type_ '&'? IDENTIFIER '{' (('get'|'set') 'const'? FUNCATTR (statblock|';'))* '}',即属性可分别定义 getter 与 setter。namespace:'namespace' IDENTIFIER '{' script '}',命名空间体递归复用script,因此支持嵌套命名空间。
语句与表达式:控制流、lambda 与构造调用
语句集合
statement : if_ | for_ | while_ | return_ | statblock | break_ | continue_ | dowhile | switch_ | exprstat | try_ ; statblock : '{' (var_ | statement)* '}' ;控制流规则与常见 C 系语言一致,但细节值得注意:
for_的初始化部分同时接受var_或exprstat,条件为exprstat,步进为assign (',' assign)*;switch_后跟case_*,case_为('case' expr | 'default') ':' statement*,从文法形态看未显式要求 break 结尾(与 AngelScript 语义一致:case 语句块由语法层面承接);try_为'try' statblock 'catch' statblock,仅支持单一 catch 块且不携带异常变量声明(文法层面简化);dowhile是'do' statement 'while' '(' assign ')' ';';exprstat允许空语句(assign? ';')。
表达式:自底向上的优先级结构
表达式部分采用"赋值 → 三元 → 二元 → 一元/后缀 → 原子"的经典分层:
assign : condition (ASSIGNOP assign)? ; condition : expr ('?' assign ':' assign)? ; expr : exprterm (exprop exprterm)* ; exprterm : (type_ '=')? initlist | EXPRPREOP* exprvalue exprpostop* ;assign右结合地支持全部ASSIGNOP;condition处理三元条件;expr通过exprop承载五类二元运算符(所有二元运算符同层并列,即文法层面不区分算术/比较优先级,真正的优先级需要结合 AngelScript 语言语义理解,或由解析树后处理进一步区分——这是"simple grammar"的典型取舍)。
exprvalue的原子包括:VOID、constructcall(type_ arglist,即类型 + 参数列表的构造调用)、funccall(scope IDENTIFIER arglist)、varaccess(scope IDENTIFIER)、cast、LITERAL、括号表达式'(' assign ')'、lambda_。其中:
cast为'cast' '<' type_ '>' '(' assign ')',即 AngelScript 的显式类型转换语法;lambda_为'function' '(' 参数列表 ')' statblock,即匿名函数;exprpostop支持成员访问(.后接函数调用或标识符)、索引/切片('[' (IDENTIFIER ':')? assign ... ']',带可选命名参数)、函数调用后缀arglist、以及++/--;arglist允许IDENTIFIER ':'前缀,对应 AngelScript 的命名实参语法;initlist为递归嵌套的花括号初始化列表'{' (assign | initlist)? (',' (assign | initlist)?)* '}',与exprterm中的(type_ '=')? initlist组合,可表达带显式类型的初始化。
运行与验证:构建、测试与命令行解析
方式一:Maven 单模块构建与测试
在仓库根目录执行(该模块已注册进根聚合 pom):
mvn -pl angelscript installantlr4-maven-plugin 会基于 angelscript.g4 生成 Lexer/Parser/Listener/Visitor 的 Java 源码;随后 antlr4test-maven-plugin 以start_为入口规则,自动解析 examples/example1.txt 中的样例:
void main() { //print("Hello world\n"); }该样例覆盖了最简单的合法脚本形态:一个void main()函数、空函数体与一条行注释。测试通过意味着文法至少能正确解析函数声明、语句块与注释跳过逻辑。
方式二:使用仓库 grun 脚本观察解析树
仓库提供的 _scripts/grun.sh 封装了"生成 → 编译 → 图形化/文本解析树"的完整流程。其用法为:
./_scripts/grun.sh -g <grammar目录名> <源文件>脚本会调用org.antlr.v4.Tool生成词法/语法文件(-visitor模式)、javac编译,再以org.antlr.v4.gui.TestRig输出-gui -tree解析树。使用前需先设置ANTLR_JAVA_LIB环境变量指向本地的 antlr4 jar,例如:
export ANTLR_JAVA_LIB=/path/to/antlr-4.13.2-complete.jar ./_scripts/grun.sh -g angelscript angelscript/examples/example1.txt将example1.txt换成任何你手写的.txt脚本,即可快速验证文法对各类 AngelScript 片段的接受情况。注意:脚本中的grammar_names/grammar_start_rules/grammar_source_files三个关联数组目前仅预置了演示项,实际使用时需按自己调试的文法补充对应映射(对 angelscript 而言即为angelscript → start_ → angelscript.g4)。
局限与二次开发提示
基于文法源码的结构分析,使用时有几点值得留意(均属于对当前仓库实现的客观描述,而非对语言本身的评判):
- NUMBER 规则仅匹配小数形式:纯整数字面量在词法层没有独立规则,若你的脚本中出现大量十进制整数,可能落入其他分支或需要按语言实际语义扩展
NUMBER/BITS规则。 - 二元运算符同级扁平化:
expr将所有exprop运算符置于同一层,解析树中不体现语言定义的优先级/结合性层级;若需要精确的求值顺序,需在遍历解析树时自行实现优先级表。 - try 语句仅支持单 catch 且无异常变量:文法未覆盖
catch (SomeException e)形式的异常声明,解析带异常对象的脚本前需评估是否需要扩展。 - NUMBER 与 BITS 的边界:
NUMBER缺少指数形式;BITS每前缀仅匹配一个字符。若目标脚本使用了1e5、0xFF00等多位十六进制字面量,建议在 fork/使用时按需收紧或扩展词法规则。
这些判断全部可从 angelscript.g4 的规则文本直接复现,读者可对照文法逐条验证。整体而言,这份文法以"简单、无动作、忠实 BNF"为设计目标,为快速解析 AngelScript 脚本、构建语法高亮/静态分析/代码生成工具提供了可复用的起点,并通过 desc.xml 声明了对 10 种 ANTLR 目标语言的支持,可直接接入 grammars-v4 的构建与测试体系使用。
- 编程语言
- 编译器
- 开发工具
【免费下载链接】grammars-v4
Grammars written for ANTLR v4; expectation that the grammars are free of actions.
相关推荐
基于 ANTLR4 的 ALPACA 元胞自动机语言文法解析:grammars-v4/alpaca 语法实战指南
基于 ANTLR4 的 ALPACA 元胞自动机语言文法解析:grammars v4/alpaca 语法实战指南 导读 本文面向希望理解并复用 ALPACA 语
编程语言编译器开发工具5分钟快速上手:OBS多平台同步直播插件完整指南
5分钟快速上手:OBS多平台同步直播插件完整指南 你是否曾为不同直播平台重复配置OBS而感到烦恼?obs multi rtmp插件正是解决这一痛点的终极解决方案
编程语言编译器开发工具Rule Template Skeleton
Rule Template Skeleton Figma MCP Integration Rules Required flow get_design_cont
编程语言编译器开发工具
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考