ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

用 ANTLR4 解析 Racket BSL:grammars-v4 中 HtDP 初学语言文法深度解读

用 ANTLR4 解析 Racket BSL:grammars-v4 中 HtDP 初学语言文法深度解读 编程语言编译器开发工具【免费下载链接】grammars-v4Grammars written for ANTLR v4; expectation that the grammars are free of actions.项目地址https://gitcode.com/gh_mirrors/gr/grammars-v4点击查看免费下载Racket BSLBeginner Student Language是 How to Design ProgramsHtDP教材为初学者设计的受限函数式语言本仓库的racket-bsl目录基于官方语言参考实现了一版无内嵌动作free of actions的 ANTLR4 文法。本文以 racket-bsl/README.md 为主线结合 BSL.g4、示例程序与 Maven 构建配置逐层拆解该文法的解析规则、词法设计、测试用例写法以及构建验证方式帮助你快速理解如何用 ANTLR4 描述一个 Lisp 系教学语言并为在此基础上扩展 BSL 变体如 ISL、带 lambda 的中间语言提供可直接照搬的骨架。BSL 文法是什么从 README 出发racket-bsl目录下的 README 非常精简核心信息就两点这是一个针对 Racket BSL 的简单 ANTLR4 文法A simple ANTLR4 grammar并且与仓库的整体约定一致——文法不包含任何内嵌 action纯描述语法结构。文法实现集中在一个文件 BSL.g4 中词法规则与语法规则同文件共存并配有一个真实可用的示例程序 temperature-conversion.rkt。从项目根目录的 README.md 可以确认整个仓库的约定根目录下的每个子目录名即为语言或文件格式的全小写名称racket-bsl即 Racket BSL 教学语言的文法目录。目录结构如下racket-bsl/ ├── BSL.g4 # 唯一文法源文件词法 语法 ├── README.md # 文法说明 ├── desc.xml # 声明可生成的目标语言 ├── pom.xml # Maven 构建与测试配置 └── examples/ └── temperature-conversion.rkt # 华氏/摄氏温度换算示例顶层结构program 与 defOrExprBSL 程序由定义、表达式、测试用例、库导入四类顶层构件自由拼接而成。文法通过两个规则组织顶层结构program : defOrExpr EOF ; defOrExpr : definition | expr | testCase | libraryRequire ;其中program是整个文法的入口规则entryPointEOF强制要求词法分析器消化全部输入避免部分匹配导致的静默错误。这一设计与pom.xml中测试插件配置的entryPoint值一一对应entryPointprogram/entryPoint grammarNameBSL/grammarName exampleFilesexamples//exampleFiles即 pom.xml 中的 antlr4test-maven-plugin 会以program为入口用examples/目录下的全部示例文件作为测试输入验证文法能否完整解析。定义规则 definition函数、变量与结构体BSL 程序的核心之一是用define定义函数、变量与结构体。文法给出了四种定义形态definition : ( define ( name NAME ) expr ) | ( define name expr ) | ( define name ( lambda ( NAME ) expr ) ) | ( define-struct name ( name* ) ) ;第一条对应多参函数定义如(define (fahrenheit-celsius f) ...)注意参数列表NAME要求至少一个形参且形参必须是NAME而非任意name即不能是SYMBOL第二条对应变量绑定(define x expr)第三条是(define name (lambda (params) expr))的显式 lambda 写法与第一条在语义上等价的两种语法形态第四条对应define-struct 结构体定义字段列表name*允许为零个或多个字段。示例程序 temperature-conversion.rkt 中的(define (fahrenheit-celsius f) (* 5/9 (- f 32)))正是第一条规则的实际应用函数名fahrenheit-celsius中的-、字符之所以能被词法器接受依赖于NAME规则的字符集设计详见后文。表达式规则 exprcond、if、逻辑组合与字面量表达式是 BSL 语法的主体文法支持函数调用、条件分支、逻辑组合与四类原子字面量expr : ( name expr ) | ( cond ([ expr expr ]) ) | ( cond ([ expr expr ])* [ else expr ] ) | ( if expr expr expr ) | ( and expr expr ) | ( or expr expr ) | ’() | name | NUMBER | BOOLEAN | STRING | CHARACTER ;逐条解读( name expr )是函数调用expr保证至少一个实参因此无参调用如(f)在本文法中不被接受——这与 BSL 教学语言的常见用法一致但确实是使用时的边界约束cond支持两种形态无 else 分支([ expr expr ])与带 else 分支注意语法文本中else 关键字后带一个空格字符这与 Racket 实际关键字else存在细微差异是阅读与复用本文法时需要留意的细节if固定三参条件、真分支、假分支and/or要求expr expr即至少两个参数’()表示空表字面量注意这里使用的是弯引号字符 ’U2019而非普通单引号与下方SYMBOL词法规则保持一致name、NUMBER、BOOLEAN、STRING、CHARACTER构成原子表达式。测试用例 testCaseBSL 的单元测试语法BSL 的一大特色是把测试写成与程序同级的顶层构件。文法完整覆盖了六种check-测试形态testCase : ( check-expect expr expr ) | ( check-random expr expr ) | ( check-within expr expr expr ) | ( check-member-of expr expr ) | ( check-satisfied expr name ) | ( check-error expr expr? ) ;check-expect断言两表达式求值结果相等是最常用的测试形式check-within多一个容差参数适合浮点比较check-member-of断言结果属于某个候选集合exprcheck-satisfied断言结果满足某个谓词谓词以name出现不能是带引号的符号check-error断言抛出错误expr?可选表示可附带期望的错误信息。示例文件中的两条断言即为check-expect的真实用例(check-expect (fahrenheit-celsius 212) 100) (check-expect (fahrenheit-celsius -40) -40)库导入 libraryRequireBSL 程序常需导入教学库如htdp/bsl与测试库如rackunit文法给出了四种require形态libraryRequire : ( require STRING ) | ( require name ) | ( require ( name STRING (( STRING ))? ) ) | ( require ( name STRING pkg ) ) ; pkg : ( STRING STRING NUMBER NUMBER ) ;带引号字符串形式(require lib.rkt)裸名称形式(require rackunit)示例文件第 3 行正是这种写法带包路径的形式如(require (planet ...))一类的复合导入最后一种结合pkg规则形如(require (planet pkg (owner name 1 0)))用四个字符串/数字元素描述包名、所有者、主版本与次版本。词法设计从 NAME 到字面量BSL 文法的词法部分BSL.g4同样值得细读它直接决定了 BSL 中标识符到底能包含哪些字符这一语言定义的核心问题。SYMBOL 与 NAME标识符字符集SYMBOL : ’ NAME ; NAME : ([$%!*\\^_~] | [--:-Za-z]) ;name语法规则由SYMBOL带弯引号前缀的符号值与NAME二选一组成。NAME的字符集直接来自官方文档不包含空格以及 , \( ) [ ] { } | ; # 的字符序列。从正则表达式看允许的字符分为两组显式列出的运算符字符$ % ! * ^ _ ~区间[--:-Za-z]即-0x2D到:0x3A之间的字符含- . / 0-9 :0x3C到Z0x5A之间的字符含 ? A-Z再加上小写a-z。这解释了为何示例中函数名fahrenheit-celsius、-40中的负号都能被合法解析-、都在允许区间内。NUMBER 与 INT数字字面量NUMBER : INT | INT . [0-9]* [1-9] | INT / INT ; INT : [1-9] [0-9]* | 0 ;数字支持三种形态整数、小数、分数。两个值得注意的约束INT不允许前导零01不合法0单独成规则小数形式INT . [0-9]* [1-9]强制要求小数点后以非零数字结尾因此5.5合法而5.0不合法——这与 BSL 文档数字示例如 123、3/2、5.5的表述相符。BOOLEAN、STRING 与 CHARACTERBOOLEAN : #true | #T | #t | #false | #F | #f ; STRING : ([ -~])* ; CHARACTER : # \u005C [A-Za-z0-9] | # \u005C space ;布尔值完整兼容大小写与缩写#true/#T/#t与#false/#F/#f字符串用可打印 ASCII[ -~]描述注意文法注释中提到了\转义示例但词法规则本身并未实现转义处理因此含转义符的字符串如This is a string with \ inside在实际解析中会被截断这是本文法相对官方规范的一个简化点字符以#\开头\u005C即反斜杠支持单个字母/数字字符或space。隐藏通道LANG、COMMENT 与 WSLANG : #lang ~ (\n | \r)* \r? \n - channel (HIDDEN) ; COMMENT : ; ~ (\n | \r)* \r? \n - channel (HIDDEN) ; WS : ( | \r | \t | \u000C | \n) - channel (HIDDEN) ;三条规则全部送入 HIDDEN 通道对解析树透明#lang行BSL 源文件的第一行声明、;分号注释、空白字符都不会出现在语法树中。示例文件第一行#lang htdp/bsl正是由LANG规则吞掉并隐藏的。实战验证解析示例程序以 temperature-conversion.rkt 为例对照文法走一遍解析流程#lang htdp/bsl (require rackunit) (define (fahrenheit-celsius f) (* 5/9 (- f 32))) (check-expect (fahrenheit-celsius 212) 100) (check-expect (fahrenheit-celsius -40) -40)第 1 行#lang htdp/bsl由LANG规则匹配并隐藏第 3 行(require rackunit)匹配libraryRequire的( require name )分支第 5-6 行(define (fahrenheit-celsius f) ...)匹配definition的函数定义分支函数体(* 5/9 (- f 32))是嵌套调用外层*调用实参为5/9分数 NUMBER与(- f 32)减法调用-为 NAME-40中负号同理可解析为 NAME 或配合 NUMBER第 8-9 行两条check-expect匹配testCase。验证方式与整个仓库一致在仓库根目录执行 test.sh本质是mvn testantlr4-maven-plugin 先基于 BSL.g4 生成解析器代码antlr4test-maven-plugin 再以program为入口遍历examples/目录完成解析断言。构建配置中还打开了visitor与listener生成开关pom.xml方便你在拿到解析树后直接挂载自定义遍历逻辑。根据 desc.xml 的声明该文法面向 CSharp、Cpp、Dart、Go、Java、JavaScript、Python3、TypeScript、Antlr4ng 等多种目标语言生成。已知边界与扩展思路基于文法源码可以推断出本实现相对 Racket BSL 官方规范的几个简化点复用时需注意无引号转义STRING规则不处理\含转义内容的字符串会解析异常弯引号符号SYMBOL与空表’()使用 U2019 弯引号而非 ASCII 单引号输入文件必须使用与之匹配的字符cond 的 else 分支关键字写作else 带尾部空格与标准 Racket 的else存在细微差异无参调用不被接受函数调用要求expr与 BSL 中至少一参的教学约定保持一致顶层层级definition、expr、testCase、libraryRequire以defOrExpr任意排列未做定义必须位于表达式之前等语义级约束——语义检查需在上层语义分析阶段完成。若需扩展至带 lambda 的中间语言ISL可参考同仓库 racket-isl/README.md 及其对应的文法目录作为从 BSL 出发进一步学习 HtDP 语言家族文法设计的下一站。赞分享编程语言编译器开发工具【免费下载链接】grammars-v4Grammars written for ANTLR v4; expectation that the grammars are free of actions.项目地址https://gitcode.com/gh_mirrors/gr/grammars-v4点击查看免费下载相关推荐使用 ANTLR4 语法解析 Geek Codegrammars-v4 中 geekcode 语法的完整解读使用 ANTLR4 语法解析 Geek Codegrammars v4 中 geekcode 语法的完整解读 Geek Code 是 1990 年代互联网文化编程语言编译器开发工具用 ANTLR4 解析 Bitcoin Miniscript 表达式grammars-v4/miniscript 语法深度解析用 ANTLR4 解析 Bitcoin Miniscript 表达式grammars v4/miniscript 语法深度解析 本篇文章以 grammars编程语言编译器开发工具P 语言文法解析grammars-v4 中最小图灵完备语言的 ANTLR4 实现P 语言文法解析grammars v4 中最小图灵完备语言的 ANTLR4 实现 本篇文章围绕 grammars v4 仓库中的 p/p.g4 https编程语言编译器开发工具上一篇JoyAI-Echo未来展望I2V支持与Director Agent功能前瞻下一篇PlantUML sdot 包源码解析Smetana 布局引擎GraphViz 内部移植版的导出实现创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表