Antlr4语法';t解析多行输入

Antlr4语法';t解析多行输入,antlr4,Antlr4,我想用Antlr4编写一个语法来解析某个定义,但我一直在努力让Antlr合作 定义有两种类型的线,一种类型,一种属性。我可以让语法正确解析类型行,但它要么忽略属性行,要么无法识别属性类型,这取决于我如何调整语法 这是我的语法(尝试583): 以下是一个示例输入: type SimpleType intProp1: int stringProp2 : String (返回类型,但忽略intProp1、stringProp2。) 我做错了什么?通常,当规则与整个输入不匹配

我想用Antlr4编写一个语法来解析某个定义,但我一直在努力让Antlr合作

定义有两种类型的线,一种类型,一种属性。我可以让语法正确解析类型行,但它要么忽略属性行,要么无法识别属性类型,这取决于我如何调整语法

这是我的语法(尝试583):

以下是一个示例输入:

    type SimpleType

    intProp1: int
    stringProp2 : String
(返回类型,但忽略intProp1、stringProp2。)


我做错了什么?

通常,当规则与整个输入不匹配,但与它的前缀匹配时,它只会匹配该前缀,并将其余输入保留在流中,而不会产生错误。如果希望规则始终与整个输入匹配,可以在规则末尾添加
EOF
。这样,当它不能匹配整个输入时,您将得到正确的错误消息

因此,让我们将您的
start
规则更改为
start:statement+EOF。现在将
start
应用于输入将导致以下错误消息:

第3行:0个无关输入'intProp1'应为{,'type',PROPERTY_NAME,NEWLINE}
第4行:0个无关输入'stringProp2'应为{,'type',PROPERTY_NAME,NEWLINE}

因此显然
intProp1
stringProp2
不被识别为
PROPERTY\u NAME
s。因此,让我们看看生成了哪些令牌(您可以使用
-tokens
选项
grun
或通过在代码中迭代令牌流来实现这一点):

这里有三条定义完全相同的lexer规则。这是个坏兆头

每当多个lexer规则可以在当前输入上匹配时,ANTLR就会选择一个产生最长匹配的规则,如果是ties,则选择语法中最先出现的规则。这被称为最大咀嚼规则

如果有多个规则具有相同的定义,这意味着这些规则将始终在同一输入上匹配,并且它们将始终生成相同长度的匹配。因此,根据最大数量规则,将始终使用第一个定义(
TYPE_NAME
),而其他定义也可能不存在


问题基本上可以归结为这样一个事实,即没有任何词汇能够区分不同类型的名称,因此词法分析器无法确定给定标识符代表的名称类型。这告诉我们,名称不应该是lexer规则。相反,
IDENTIFIER
应该是一个lexer规则,
FOO_NAME
s应该是(有些不必要的)解析器规则,或者完全删除(您可以在当前使用
FOO_NAME
的任何地方使用
IDENTIFIER
)。

这正是我需要的洞察力。我把名字分开是因为它们不仅仅是一行的标识符。但是我修改了代码,删除了匹配规则,现在它可以工作了。谢谢
    type SimpleType

    intProp1: int
    stringProp2 : String
[@0,0:3='type',<'type'>,1:0]
[@1,5:14='SimpleType',<TYPE_NAME>,1:5]
[@2,15:15='\n',<NEWLINE>,1:15]
[@3,16:16='\n',<NEWLINE>,2:0]
[@4,17:24='intProp1',<TYPE_NAME>,3:0]
[@5,25:25=':',<':'>,3:8]
[@6,27:29='int',<TYPE_NAME>,3:10]
[@7,30:30='\n',<NEWLINE>,3:13]
[@8,31:41='stringProp2',<TYPE_NAME>,4:0]
[@9,43:43=':',<':'>,4:12]
[@10,45:50='String',<TYPE_NAME>,4:14]
[@11,51:51='\n',<NEWLINE>,4:20]
[@12,52:51='<EOF>',<EOF>,5:0]
TYPE_NAME
    :   IDENTIFIER ;

PROPERTY_NAME
    :   IDENTIFIER ;

PROPERTY_TYPE
    :   IDENTIFIER ;

fragment IDENTIFIER
    :   (LETTER | '_') (LETTER | DIGIT | '_' )* ;