是否有可能跟踪先例令牌以解决ANTLR4中的歧义



我从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 令牌,但您可以标记它们,以便在进行树上漫步时可以区分它们。

相关内容

  • 没有找到相关文章

最新更新