使用正则捕获自定义玩具语言函数参数及可选类型提示问题
解决自研玩具语言函数参数类型提示的语法高亮问题
问题分析
你当前的正则表达式尝试用单个捕获组覆盖所有参数,但tmLanguage的正则引擎中,重复的捕获组(比如(,\w+(:\w+)?)*里的(:\w+)?)只会保留最后一次匹配的结果,这就导致多参数场景下中间的类型提示无法被正确捕获。单个大正则无法处理这种需要重复识别相同结构的场景,必须改用tmLanguage支持的分块匹配模式。
解决方案
放弃用单个正则匹配整个函数声明,改用begin/end块拆分匹配逻辑:先匹配函数声明的开头,再在参数列表范围内单独匹配每个参数及其类型提示。
具体tmLanguage配置示例
{ "name": "Toy Language", "patterns": [ { "begin": "\\b(func)\\b\\s+\\b(\\w+)\\b\\(", "end": "\\)\\s*->\\s*\\b(\\w+)\\b", "captures": { "1": { "name": "keyword.control.function.toy" }, "2": { "name": "entity.name.function.toy" }, "3": { "name": "storage.type.return.toy" } }, "patterns": [ { "match": "\\b(\\w+)(:\\b(\\w+)\\b)?", "captures": { "1": { "name": "variable.parameter.toy" }, "2": { "name": "punctuation.separator.type.toy" }, "3": { "name": "storage.type.parameter.toy" } } }, { "match": ",", "name": "punctuation.separator.comma.toy" } ] } ] }
配置说明
- 外层
begin/end:匹配函数声明的框架(func 函数名(到)->返回类型),分别标记关键字、函数名和返回类型。 - 内部
patterns:在参数列表的范围内,单独匹配每个参数项:- 匹配参数名
\b(\w+),标记为参数变量; - 匹配可选的类型提示
:\b(\w+)\b,分别标记类型分隔符和类型名; - 匹配逗号分隔符,单独标记样式。
- 匹配参数名
原正则失效原因
原正则\b(func)\b\s+\b(\w+)\b\((\w+(:\w+)?(,\w+(:\w+)?)*)?\)\s*->\s*\b(\w+)\b中,(:\w+)?嵌套在重复组(,\w+(:\w+)?)*里,正则引擎会不断覆盖这个捕获组的内容,最终只保留最后一个参数的类型提示,中间的全部丢失。而分块匹配会逐个识别每个参数,避免了重复捕获组的覆盖问题。
内容的提问来源于stack exchange,提问作者buzzbuzz20xx
相关产品推荐
相关产品推荐

