我从ANTLR4开始,我想要的是识别这种格式,同时根据令牌读取执行一些操作。我正在尝试生产的内容:
-
标识符:Test1 ([a-zA-Z09]{10})
{在 personId 列中插入"Test1"}
-
编号: F0101F
FULL_NAME: FIRST_NAME ( [A-Z]+) - LAST_NAME ( [A-Z]+ )
{在名字列中插入FIRST_NAME.value,LAST_NAME并在 姓氏列}
- 地址:数字+ STREET_NAME ([A-Z]+)
{在街道名称列中插入STREET_NAME.值 }
- OTHER_INFORMATION: ([A-Z]+)
{在其他列中插入OTHER_INFORMATION.值}
我做了什么:
prod
:
read_information+
;
read_information
:
{getCurrentToken().getType()== ID }?
idElement
|
{getCurrentToken().getType()== CODE }?
codeElement
|
{getCurrentToken().getType()== FULLNAME}?
fullNameElement
|
{getCurrentToken().getType()== STREET}?
streetElement
|
{getCurrentToken().getType()== OTHER}?
otherElement
;
codeElement
:
CODE
{getCurrentToken().getText().matches("[A-F0-9]{6}")}?
codeInformation
|
{/*throw someException*/}
;
codeInformation
:
HEXCODE
;
HEXCODE
:
[a-fA-F0-9]+
;
CODE
:
'CODE:'
;
otherElement
:
OTHER otherInformation
;
otherInformation
:
STR
;
OTHER
:
'OTHER:'
;
streetElement
:
STREET streetInformation
;
STREET
:
'STREET:'
;
streetInformation
:
STR
;
STR
:
[a-zA-Z0-9]+
;
WORD
:
[a-zA-Z]+
;
fullNameElement
:
FULLNAME firstNameInformation lastNameInformation
;
FULLNAME
:
'FULL_NAME:'
;
firstNameInformation
:
WORD
;
lastNameInformation
:
WORD
;
idElement
:
ID idInformation
;
ID
:
'ID:'
;
idInformation
:
{getCurrentToken().getText().length()<=10}?
STR
;
我不确定这是否是正确的方法,因为我在阅读 WORD 令牌时遇到问题。由于所有令牌基本上都是相同的格式,我正在尝试找到一种方法来跟踪先例令牌或上下文以解决歧义,并同时检查格式(例如,如果它超过 10 个字符抛出异常)
为了找出生成的解析器将输入哪些规则(即访问哪个上下文),您可以使用 ANTLR 来创建访问者。这里有一个很好的解释(见巴特·基尔斯的回应)。
通常,如果有两个相同的规则,则可以将它们合并为一个,然后标记它们的用法。例如,对于这些规则:
firstNameInformation
:
WORD
;
lastNameInformation
:
WORD
;
没有理由真正拥有它们。相反,您可以通过以下方式编写全名的语法:
fullNameElement
:
FULLNAME firstname=WORD lastname=WORD
;
在这种情况下,您只使用 WORD 令牌,但您可以标记它们,以便在进行树上漫步时可以区分它们。