You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Tree-sitter语法中解析带可选模块前缀的类型标识符?

ASN.1类型标识符的Tree-sitter语法解析问题

我需要解析ITU-T建议X.680至X.683中定义的ASN.1类型标识符,该标识符支持两种合法形式:带模块前缀的MyModule.MyType,以及不带前缀的MyType,且模块名与类型标识符的语法完全一致。

我当前编写的Tree-sitter语法如下:

DefinedType: $ => prec.right(seq(
  optional(seq($.modulereference, '.')),
  alias($.uppercased_identifier, 'typereference'),
  optional($.ActualParameterList),
)),

但解析XSD.String时,Tree-sitter会将XSD识别为typereference,遇到句点时直接报错。我尝试过使用prec.right()、prec.left()以及conflicts配置,都无法让解析器选择最长的匹配项。想请教这种可选前缀的解析在Tree-sitter中是否可行,以及正确的实现方式是什么?


解决方案

这种可选前缀的解析是可行的,问题出在原语法用optional包裹前缀的方式,会让Tree-sitter优先匹配更短的不带前缀结构。调整语法定义的方式即可解决:

  1. 显式区分两种匹配分支:将DefinedType定义为包含两个分支的choice,分别对应带模块前缀和不带前缀的情况。
  2. 给带前缀分支设置更高优先级:确保解析器优先尝试匹配更长的带前缀结构,失败后再退回到不带前缀的情况。

调整后的语法代码:

DefinedType: $ => prec(1, choice(
  // 带模块前缀的分支,优先级更高
  seq(
    $.modulereference, '.',
    alias($.uppercased_identifier, 'typereference'),
    optional($.ActualParameterList)
  ),
  // 不带前缀的分支
  seq(
    alias($.uppercased_identifier, 'typereference'),
    optional($.ActualParameterList)
  )
))

关键说明

  • 原语法中的optional会让解析器先尝试跳过前缀部分,直接匹配typereference,导致更长的带前缀匹配被忽略。
  • 显式的choice结构配合优先级设置,能强制解析器先检查是否存在带前缀的完整结构,再处理不带前缀的情况。
  • 需确保modulereference的语法定义与typereference的基础规则完全一致(比如都是符合ASN.1规范的大写标识符),这样解析器才能正确识别前缀部分。

内容的提问来源于stack exchange,提问作者Jonathan Wilbur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 22:52:21