尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

grammars-v4 仓库 TypeScript 语法详解:基于 ANTLR v4 的实用主义 TypeScript 解析方案

grammars-v4 仓库 TypeScript 语法详解:基于 ANTLR v4 的实用主义 TypeScript 解析方案 编程语言编译器开发工具【免费下载链接】grammars-v4Grammars written for ANTLR v4; expectation that the grammars are free of actions.项目地址https://gitcode.com/gh_mirrors/gr/grammars-v4点击查看免费下载导读本文聚焦 grammars-v4 仓库中 javascript/typescript 目录下的 TypeScript ANTLR v4 语法。该语法由 Andrii Artiushok 于 2019 年基于 Positive Technologies 维护的 JavaScript 语法扩展而来其核心设计目标并非逐字复刻 TypeScript 官方规范而是追求实际可用性、解析性能与文法清晰度。读完本文你将掌握该语法的设计哲学与适用范围、词法与语法规则的架构组织、如何借助 LexerBase/ParserBase 解决正则字面量与模板字符串等歧义、仓库内丰富的示例与测试组织方式以及当前已知的歧义问题与使用限制。一、语法定位于设计理念实践优先非规范逐字实现关联文档 javascript/typescript/README.md 开篇即给出一个重要声明本 TypeScript 语法并不与 TypeScript 标准完全一一对应开发期间的主要目标是实用practical usage、性能performance与清晰clarity即消除重复规则。这意味着该语法是一个面向真实代码解析场景的工程化实现而不是 TypeScript 官方语法规范的机械翻译。它直接继承自 Positive Technologies 的 JavaScript 语法后者同样是 grammars-v4 仓库中久经考验、用于真实项目如安全扫描、代码审计的成熟文法。从仓库结构看该语法由三部分协同构成javascript/typescript/TypeScriptLexer.g4词法规则负责将源码拆分为 tokenjavascript/typescript/TypeScriptParser.g4语法规则负责将 token 流组织为语法树各语言运行时的基类实现Java/CSharp/Cpp/TypeScript承载语义谓词背后的状态逻辑。需要特别指出的是它并非孤立的 TypeScript 实现——通过import/export、class、interface、namespace等规则的叠加它天然向下兼容大部分 JavaScriptES6代码这也是仓库在 javascript/typescript/examples 中同时放置.ts与.js示例文件如Export.js、Import.js、TemplateStrings.js、NonNullAssertOp.js的原因——这些纯 JS 文件同样被纳入测试输入。二、仓库资源全景语法文件、运行基类与示例该语法目录的关键文件如下文件作用TypeScriptLexer.g4词法规则定义全部 token、模板字符串模式TEMPLATE mode与 ERROR 通道TypeScriptParser.g4语法规则覆盖类型系统、接口、类、命名空间、装饰器与完整 ECMAScript 表达式Java/TypeScriptLexerBase.javaJava 运行基类strict 模式栈、模板深度跟踪、正则字面量判定Java/TypeScriptParserBase.javaJava 运行基类p()/n()/notLineTerminator()/lineTerminatorAhead()等语义谓词CSharp/、Cpp/、TypeScript/同基类的 C#、C、TypeScript 移植版本examples/23 个覆盖类、接口、泛型、枚举、模板字符串、装饰器的测试输入pom.xmlMaven 构建与测试配置desc.xml语法描述元数据目标语言、ANTLR 版本、测试输入通配符其中 desc.xml 明确声明antlr-version^4.7/antlr-version目标语言为CSharp;Java;TypeScript测试输入为examples/*.ts。这给出了该语法在当前仓库中的运行前提需要 ANTLR 4.7 及以上版本官方验证目标为 C#、Java 与 TypeScript 三种运行时。三、词法层设计如何驯服 TypeScript 的最难分词点TypeScript/JavaScript 的词法分析公认有两大难点正则字面量 vs 除法运算符的区分以及模板字符串template literal内部状态的跟踪。该语法的词法文件给出了工程化的解决方案。3.1 正则字面量的语义谓词判定在 TypeScriptLexer.g4 中RegularExpressionLiteral规则结尾处有一个语义谓词RegularExpressionLiteral: / RegularExpressionFirstChar RegularExpressionChar* {this.IsRegexPossible()}? IdentifierPart* ;IsRegexPossible()在 Java/TypeScriptLexerBase.java 中实现其核心思想是——若前一个位于默认通道的 token 之后不可能出现除法例如前一个 token 是Identifier、DecimalLiteral、This、CloseParen等表达式收尾符则当前/只能解释为正则字面量起点反之前一个 token 是运算符、OpenBrace或输入起始则可能是除法。这依赖nextToken()覆写中对lastToken的持续记录TypeScriptLexerBase.java。switch (this.lastToken.getType()) { case TypeScriptLexer.Identifier: case TypeScriptLexer.DecimalLiteral: case TypeScriptLexer.CloseBracket: case TypeScriptLexer.CloseParen: ... return false; // 此处不可能出现正则字面量 default: return true; }3.2 模板字符串与花括号嵌套深度的双栈管理模板字符串是另一个状态机难题。词法文件中用TEMPLATE模式配合三个计数变量解决BackTick: {this.IncreaseTemplateDepth();} - pushMode(TEMPLATE);对应地在 TypeScriptLexerBase.java 中维护两个关键状态templateDepth嵌套模板字符串的反引号深度。例如${a ? ${X中X处深度为 2用于判断某个}是普通CloseBrace还是闭合模板内表达式的TemplateCloseBracebracesDepth模板表达式内部{...}的嵌套深度防止${[1,2,3].map(x { return x * 2;}).join()}中函数体的}被误判为模板结束符。判定逻辑为IsInTemplateString()返回templateDepth 0 bracesDepth 0TypeScriptLexerBase.java。对应地词法规则中TemplateCloseBrace : {this.IsInTemplateString()}? } - popMode;与CloseBrace : } {this.ProcessCloseBrace();};相互配合这正是 examples/TemplateStrings.js 中多种嵌套场景含嵌套模板、转义反引号、含换行模板、嵌套大括号能被正确解析的底层原因。3.3 strict 模式与use strict处理ProcessOpenBrace()/ProcessCloseBrace()TypeScriptLexerBase.java维护一个scopeStrictModes栈每进入一个{块就把当前 strict 状态入栈遇到字符串字面量use strict/use strict时切换当前状态TypeScriptLexerBase.java。这一机制直接服务于词法规则中仅在非 strict 模式下才合法的旧式八进制字面量OctalIntegerLiteral : 0 [0-7] {!this.IsStrictMode()}?;同时词法层还定义了一个ERROR通道任何UnexpectedCharacter都会进入该通道而非直接报错便于上层收集诊断信息。四、语法层架构从 A.1 类型系统到 ECMAScript 表达式TypeScriptParser.g4 采用TypeScript 专属部分 ECMAScript 公共部分的分层组织方式并在注释中保留了与 TypeScript 规范章节A.1 Types、A.5 Interface、A.7 Enum、A.8 Namespaces的对应关系。4.1 类型系统A.1 Types类型规则从type_出发支持联合类型|、交叉类型、函数类型、构造器类型与泛型且允许前导|/对应 TypeScript PR #12386 的语法增强见 TypeScriptParser.g4type_ : (| | )? unionOrIntersectionOrPrimaryType | functionType | constructorType | typeGeneric ; primaryType : ( type_ ) # ParenthesizedPrimType | predefinedType # PredefinedPrimType | typeReference # ReferencePrimType | objectType # ObjectPrimType | primaryType {this.notLineTerminator()}? [ primaryType? ] # ArrayPrimType | [ tupleElementTypes ] # TuplePrimType | typeQuery # QueryPrimType | This # ThisPrimType | typeReference Is primaryType # RedefinitionOfType | KeyOf primaryType # KeyOfType ;值得注意的工程细节预定义类型作为词法 tokenAny、Number、String、Boolean、Symbol、Never、Undefined、Object、Unique、KeyOf等关键字在词法层即被定义为 tokenTypeScriptLexer.g4解析器通过predefinedType规则组合出unique symbol、keyof T等现代 TS 类型右移运算符在词法中禁用/被注释掉原因注释写得很清楚——若在词法层匹配它们会破坏Mapstring, Mapstring, string这类嵌套泛型类型的解析TypeScriptLexer.g4。因此位右移运算在语法层用 组合表达泛型默认值与约束typeParameter支持T extends X约束与T Default默认值examples/Generic.ts 第 28、32、35 行分别演示了T extends Person、K extends keyof T与T DefaultType三种写法。4.2 接口、类、枚举与命名空间接口A.5interfaceDeclaration支持export/declare前缀、泛型参数、extends继承子句以及对象字面量类型的函数体TypeScriptParser.g4。类型成员覆盖属性签名、调用签名、构造签名、索引签名与方法签名。索引签名规则[ identifier : (Number | String) ] typeAnnotation对应 examples/Interface.ts 中[index:string]:string的数组/字典接口写法类classDeclaration支持装饰器、abstract、泛型、extends/implements类成员基propertyMemberBase组合了accessibilityModifier? Async? Static? ReadOnly?TypeScriptParser.g4examples/Class.ts 完整覆盖public/private/protected/readonly/static、getter/setter、构造器与装饰器方法枚举A.7enumDeclaration支持const enum与成员显式赋值命名空间A.8namespaceDeclaration支持declare前缀与点号嵌套命名空间并配套importAliasDeclarationimport q x.y.z;风格别名。4.3 表达式层与语义谓词表达式规则singleExpression是一个体量很大的左递归规则TypeScriptParser.g4完整覆盖 ES6 的运算符优先级幂**右结合、空值合并??、可选链?.、非空断言!、as类型断言、展开运算符、生成器与迭代器字面量等。为消除歧义解析器基类提供了一组语义谓词Java/TypeScriptParserBase.javap(str)/n(str)判断前一个/后一个 token 文本是否为指定值用于for...of中识别of关键字notLineTerminator()检查当前 token 之前是否紧跟换行用于continue/break/return/yield的 ASI 自动分号插入判断lineTerminatorAhead()不仅检查LineTerminator还会识别包含换行的多行注释防止/*\n*/被误判为无换行notOpenBraceAndNotFunctionAndNotInterface()用于expressionStatement的向前看避免{、function、interface开头的语句被误解析为表达式closeBrace()配合eos规则实现可省略分号的语句终止判断。这些谓词通过options { superClass TypeScriptParserBase; }挂接到解析器TypeScriptParser.g4C#、C、TypeScript 运行时各有对应移植保证多语言行为一致。五、构建与测试pom.xml 与示例的组织方式仓库用 Maven 管理该语法的生成与验证。pom.xml 中有两个关键插件antlr4-maven-plugin将TypeScriptLexer.g4与TypeScriptParser.g4作为输入sourceDirectory${basedir}/sourceDirectory生成解析器源码并开启visitor与listener两种遍历模式antlr4test-maven-plugin以program为入口规则对应program : sourceElements? EOF;将examples/目录下的文件作为测试输入逐一解析用于回归验证。示例目录 examples/ 的 23 个文件覆盖了该语法宣称支持的核心语言特性Class.ts类、访问修饰符、装饰器、Interface.ts接口、索引签名、只读属性、Generic.ts泛型约束与默认值、Enum.ts、Module.ts、Type.ts、NonNullAssertOp.js非空断言!、TemplateStrings.js嵌套模板字符串的边界场景等。其中多个文件在注释中标注了对应的 antlr/grammars-v4 issue 链接如 #2978、#3051说明这些示例本身就是历史上真实解析缺陷的回归用例。六、已知问题与使用注意事项README 明确记录了该语法的当前限制javascript/typescript/README.md语法非常古老且存在大量歧义primaryType 决策点 11Decision 11、singleExpression 决策点 236Decision 236等。结合源码可以给出更精确的使用建议歧义源自设计取舍为了覆盖 ECMAScript 与 TypeScript 两套文法singleExpression左递归规则极长50 备选分支ANTLR 的 ALL(*) 自适应预测在此类规则上会产生多个决策点导致解析时预测开销较大、且可能报告非 LL 语法式歧义告警版本覆盖有限从词法/语法规则可以推断它主要覆盖 TypeScript 2.x~3.x 时代的语法形态如unique symbol、keyof、装饰器较新的语法如 const 类型参数、satisfies、using声明等未包含在内不要将其视为可解析现代全部 TS 代码的完整实现性能导向正如 README 所说设计时优先考虑了性能与消除重复规则因此部分非规范写法可能无法解析这属于预期行为而非缺陷。若需要更贴近官方规范的 TypeScript 解析可参考仓库内其他相关实现如 javascript/javascript 目录下的 ES6 语法但务必根据实际代码样本先在 examples 机制下做一轮解析回归验证。七、总结grammars-v4 仓库中的 TypeScript 语法 是一个工程实用优先的 ANTLR v4 实现它用语义谓词与运行时基类解决了正则字面量、模板字符串、strict 模式、ASI 等 JS 家族语言的经典词法/语法难题用分层规则覆盖了 TypeScript 类型系统与 ES6 表达式并通过 Maven 插件 示例回归的方式保障可维护性。对于希望在自定义工具链代码分析、安全扫描、重构脚手架中快速获得 TypeScript 语法树、且能容忍一定版本滞后与决策歧义的开发者这是一个开箱即用的参考起点——其最宝贵的资产正是 examples/ 中那些标注了 issue 编号的真实边界用例。赞分享编程语言编译器开发工具【免费下载链接】grammars-v4Grammars written for ANTLR v4; expectation that the grammars are free of actions.项目地址https://gitcode.com/gh_mirrors/gr/grammars-v4点击查看免费下载相关推荐用 ANTLR v4 解析 B 语言grammars-v4 仓库 b/b.g4 语法全解与实战验证用 ANTLR v4 解析 B 语言grammars v4 仓库 b/b.g4 语法全解与实战验证 本文围绕 grammars v4 仓库中 b/README编程语言编译器开发工具grammars-v4 仓库中的 Protocol Buffers 3protobuf3ANTLR v4 语法基于符号表的两遍解析消歧实现解析grammars v4 仓库中的 Protocol Buffers 3protobuf3ANTLR v4 语法基于符号表的两遍解析消歧实现解析 导读 本篇编程语言编译器开发工具grammars-v4 中的 HyperTalk 语法用 ANTLR v4 解析 HyperCard 脚本语言grammars v4 中的 HyperTalk 语法用 ANTLR v4 解析 HyperCard 脚本语言 导读 本文讲解 grammars v4 htt编程语言编译器开发工具上一篇推荐Spot Micro 四足机器人项目下一篇【亲测免费】 推荐使用Python的Emoji库——让编程更有趣创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表