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

时间:2016-03-11 13:44:21

标签: parsing antlr antlr4 lexer

我从ANTLR4开始,我想要的是在根据令牌读取执行某些操作时识别此格式。 我想要制作的东西:

  • IDENTIFIER:Test1([a-zA-Z09] {10})

      

    {insert' Test1' in personId column}

  • 代码:F0101F

  • FULL_NAME:FIRST_NAME([A-Z] +)LAST_NAME([A-Z] +)
      

    {在firstName列中插入FIRST_NAME.value并在其中插入LAST_NAME.value   lastName column}

  • ADRESS:DIGIT + STREET_NAME([A-Z] +)
      

    {在streetName列中插入STREET_NAME.value}

  • OTHER_INFORMATION :( [A-Z] +)
      

    {在其他栏中插入OTHER_INFORMATION.value}

我做了什么:

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令牌时遇到问题。 由于所有令牌基本上都是相同的格式,我试图找到一种方法来跟踪先前令牌或上下文以解决歧义,并同时检查格式(例如,如果它&#39;超过10个char throw例外)

1 个答案:

答案 0 :(得分:0)

您可以做的事情是找出生成的解析器将输入哪些规则(即访问哪个上下文),您可以使用ANTLR创建访问者。对它有一个很好的解释here(参见Bart Kiers的回应)。

通常,如果有两个相同的规则,您可以将它们合并为一个,然后标记它们的用法。例如,对于这些规则:

float16

没有理由真正拥有它们。相反,你可以用这种方式写出全名的语法:

firstNameInformation
:
    WORD
;

lastNameInformation
:
    WORD
;

在这种情况下,您只使用WORD标记,但是标记它们以便在进行树木漫步时可以区分它们。