Antlr4 - 获取函数的参数 Java
Antlr4 - Get function's param(s) Java
我有以下语法
GUID : GUIDBLOCK GUIDBLOCK '-' GUIDBLOCK '-' GUIDBLOCK '-' GUIDBLOCK
'-'
GUIDBLOCK GUIDBLOCK GUIDBLOCK;
SELF : 'self(' GUID ')';
fragment
GUIDBLOCK: [A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9];
atom : SELF # CurrentGuid
这是我的访客
@Override
public String visitCurrentGuid(CalcParser.CurrentRecordContext ctx) {
System.out.println("Guid is : " + ctx.getText());
System.out.println("Guid is : " + ctx.getChild(0));
return ctx.getText();
}
有输入"self(5827389b-c8ab-4804-8194-e23fbdd1e370)"
只有一个 child 是整个输入本身 "self(5827389b-c8ab-4804-8194-e23fbdd1e370)"
我应该如何获取 guid 部分?
根据我的理解,如果我的语法结构构造为 AST,我应该能够打印出树。
我应该如何更新我的语法?
谢谢
片段根本不会出现在 AST 中 - 它们基本上被视为您直接在使用它们的词法分析器规则中写入它们的内容。因此,将代码移动到片段中会使您的代码更易于阅读,但根本不会影响生成的 AST。
其他词法分析器规则使用的词法分析器规则在该上下文中也被视为片段。也就是说,如果一个词法分析器规则使用另一个词法分析器规则,它仍然会产生没有嵌套结构的单个标记——就像你使用了一个片段一样。事实上,它是一个词法分析器规则而不是一个片段,只有当模式单独出现而不是更大模式的一部分时才会有所不同。
关键是词法分析器规则总是产生单个标记,并且标记没有子标记。它们是 AST 的叶子。带有子节点的节点是根据解析器规则生成的。
您拥有的唯一解析器规则是 atom
。 atom
仅调用另一条规则 SELF
。因此生成的树将由一个 atom
组成,它包含一个 SELF
标记作为其唯一的子节点,并且如前所述,标记是叶子,所以这是树的末端。
要获得有用的树,您可能想要做的是使 GUIDBLOCK
成为词法分析器规则(事实上,您唯一的词法分析器规则)并将其他所有内容转换为解析器规则。这也意味着您可以摆脱 atom
(如果需要,可以将 SELF
重命名为 atom
)。
然后你会得到一个包含 self
(或者 atom
如果你重命名)节点的树,它包含一个 'self('
标记作为它的子节点,一个 guid
节点(您可能想为其分配一个名称以便于访问)和一个 )
令牌。 guid
节点又将包含一系列 GUIDBLOCK
和 '-'
标记。您还可以在每次使用 GUIDBLOCK
之前添加 blocks+=
以获得仅包含 GUIDBLOCK
标记且没有破折号的列表。
将 'self('
变成两个标记(即 'self' '('
)也可能有意义 - 特别是如果您想要添加一条规则来忽略空格。
我有以下语法
GUID : GUIDBLOCK GUIDBLOCK '-' GUIDBLOCK '-' GUIDBLOCK '-' GUIDBLOCK
'-'
GUIDBLOCK GUIDBLOCK GUIDBLOCK;
SELF : 'self(' GUID ')';
fragment
GUIDBLOCK: [A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9];
atom : SELF # CurrentGuid
这是我的访客
@Override
public String visitCurrentGuid(CalcParser.CurrentRecordContext ctx) {
System.out.println("Guid is : " + ctx.getText());
System.out.println("Guid is : " + ctx.getChild(0));
return ctx.getText();
}
有输入"self(5827389b-c8ab-4804-8194-e23fbdd1e370)"
只有一个 child 是整个输入本身 "self(5827389b-c8ab-4804-8194-e23fbdd1e370)"
我应该如何获取 guid 部分?
根据我的理解,如果我的语法结构构造为 AST,我应该能够打印出树。
我应该如何更新我的语法?
谢谢
片段根本不会出现在 AST 中 - 它们基本上被视为您直接在使用它们的词法分析器规则中写入它们的内容。因此,将代码移动到片段中会使您的代码更易于阅读,但根本不会影响生成的 AST。
其他词法分析器规则使用的词法分析器规则在该上下文中也被视为片段。也就是说,如果一个词法分析器规则使用另一个词法分析器规则,它仍然会产生没有嵌套结构的单个标记——就像你使用了一个片段一样。事实上,它是一个词法分析器规则而不是一个片段,只有当模式单独出现而不是更大模式的一部分时才会有所不同。
关键是词法分析器规则总是产生单个标记,并且标记没有子标记。它们是 AST 的叶子。带有子节点的节点是根据解析器规则生成的。
您拥有的唯一解析器规则是 atom
。 atom
仅调用另一条规则 SELF
。因此生成的树将由一个 atom
组成,它包含一个 SELF
标记作为其唯一的子节点,并且如前所述,标记是叶子,所以这是树的末端。
要获得有用的树,您可能想要做的是使 GUIDBLOCK
成为词法分析器规则(事实上,您唯一的词法分析器规则)并将其他所有内容转换为解析器规则。这也意味着您可以摆脱 atom
(如果需要,可以将 SELF
重命名为 atom
)。
然后你会得到一个包含 self
(或者 atom
如果你重命名)节点的树,它包含一个 'self('
标记作为它的子节点,一个 guid
节点(您可能想为其分配一个名称以便于访问)和一个 )
令牌。 guid
节点又将包含一系列 GUIDBLOCK
和 '-'
标记。您还可以在每次使用 GUIDBLOCK
之前添加 blocks+=
以获得仅包含 GUIDBLOCK
标记且没有破折号的列表。
将 'self('
变成两个标记(即 'self' '('
)也可能有意义 - 特别是如果您想要添加一条规则来忽略空格。