处理语法中过多的终端节点
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_()
的每个可能结果?
谢谢
如果 messageDefinition
和 enumType
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);
}
我正在尝试使用 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_()
的每个可能结果?
谢谢
如果 messageDefinition
和 enumType
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);
}