处理语法中过多的终端节点

Dealing with too many terminal nodes in grammar

我正在尝试使用 https://github.com/antlr/grammars-v4/blob/master/protobuf3/Protobuf3.g4 中的语法为 protobuf3 编写解析器。

我正在尝试处理语法中的 _type 声明:

field
  : ( REPEATED )? type_ fieldName EQ fieldNumber ( LB fieldOptions RB )? SEMI
  ;

type_
  : DOUBLE
  | FLOAT
  | INT32
  | INT64
  | UINT32
  | UINT64
  | SINT32
  | SINT64
  | FIXED32
  | FIXED64
  | SFIXED32
  | SFIXED64
  | BOOL
  | STRING
  | BYTES
  | messageDefinition
  | enumType
  ;

里面 enterField 我有这个片段:

    @Override
    public void enterField(Protobuf3Parser.FieldContext ctx) {
        MessageDefinition messageDefinition = this.messageStack.peek();
        Field field = new Field();
        field.setName(ctx.fieldName().ident().getText());
        field.setPosition(ctx.fieldNumber().getAltNumber());
        messageDefinition.addField(field);
        super.enterField(ctx);
    }

但是我不确定如何处理这里的 type_ 上下文。它有太多的终端节点(对于基本类型),它可能有一个 messageType 或一个 enumType。

对于我的用例,我只关心它是基本类型(在这种情况下获取类型名称)还是复杂类型(例如另一个消息或枚举)获取定义名称。

有没有办法做到这一点而不必检查 ctx.field_() 的每个可能结果?

谢谢

如果 messageDefinitionenumType return 都是单个词法分析器标记,您可以使用标签使整个访问变得非常容易:

type_
  : value = DOUBLE
  | value = FLOAT
  | value = INT32
  | value = INT64
  | value = UINT32
  | value = UINT64
  | value = SINT32
  | value = SINT64
  | value = FIXED32
  | value = FIXED64
  | value = SFIXED32
  | value = SFIXED64
  | value = BOOL
  | value = STRING
  | value = BYTES
  | value = messageDefinition
  | value = enumType
  ;

这样你只需要使用字段 value:

    @Override
    public void enterField(Protobuf3Parser.FieldContext ctx) {
        ...

        const type = ctx.type_().value.getText();
        ...

        super.enterField(ctx);
    }