Java 外部输入

Java 外部输入,java,antlr,antlr4,Java,Antlr,Antlr4,我有一个语法文件BoardFile.g4,它有(仅相关部分): 这将生成lexer和解析器。但是,当我对以下文件使用它时,会出现以下错误: line 12:0 extraneous input 'keyup' expecting {<EOF>, KEYPRESS} 关于这个错误,我在SO中问了其他问题,但没有一个对我有帮助。我不知道出了什么问题。为什么会出现此错误?字符串“keyup”被标记为名称标记:这就是问题所在 您必须认识到lexer独立于解析器运行。如果解析器试图匹配KEY

我有一个语法文件BoardFile.g4,它有(仅相关部分):

这将生成lexer和解析器。但是,当我对以下文件使用它时,会出现以下错误:

line 12:0 extraneous input 'keyup' expecting {<EOF>, KEYPRESS}
关于这个错误,我在SO中问了其他问题,但没有一个对我有帮助。我不知道出了什么问题。为什么会出现此错误?

字符串
“keyup”
被标记为
名称
标记:这就是问题所在

您必须认识到lexer独立于解析器运行。如果解析器试图匹配
KEYPRESS
标记,则lexer不会“侦听”它,而是按照规则构造一个标记:

  • 匹配使用最多字符的规则
  • 如果有更多规则匹配相同数量的字符,请选择首先定义的规则
  • 考虑到这些规则以及规则的顺序:

    NAME : [A-Za-z_][A-Za-z_0-9]* ;
    
    INT : [0-9]+ ;
    
    KEY : [a-z] | [0-9] | 'shift' | 'ctrl' | 'alt' | 'meta' | 'space' | 'left' | 'right' | 'up' | 'down' | 'minus' | 'equals' | 'backspace' | 'openbracket' | 'closebracket' | 'backslash' | 'semicolon' | 'quote' | 'enter' | 'comma' | 'period' | 'slash' ;
    
    KEYPRESS : 'keyup' | 'keydown' ;
    
    将在大多数
    替代项之前创建
    名称
    标记,并将创建所有
    按键
    替代项

    而且由于
    INT
    匹配一个或多个数字,并且在
    之前定义,而
    键也有一个单数替代,因此显然lexer永远不会产生
    按键
    令牌

    如果将
    NAME
    INT
    规则移动到
    KEY
    KEYPRESS
    规则下方,那么我猜大部分令牌都会按照您的预期构造

    编辑 可能的解决方案如下所示:

    KEY : [a-z] | 'shift' | 'ctrl' | 'alt' | 'meta' | 'space' | 'left' | 'right' | 'up' | 'down' | 'minus' | 'equals' | 'backspace' | 'openbracket' | 'closebracket' | 'backslash' | 'semicolon' | 'quote' | 'enter' | 'comma' | 'period' | 'slash' ;
    
    KEYPRESS : 'keyup' | 'keydown' ;
    
    NAME : [A-Za-z_][A-Za-z_0-9]* ;
    
    SINGLE_DIGIT : [0-9] ;
    
    INT : [0-9]+ ;
    
    也就是说,我从
    中删除了
    [0-9]
    选项,并引入了一个
    单位
    规则(放在
    INT
    规则之前!)

    现在创建一些额外的解析器规则:

    integer : INT | SINGLE_DIGIT ;
    
    key : KEY | SINGLE_DIGIT ;
    
    并将解析器规则中所有出现的
    INT
    更改为
    integer
    (不要调用规则
    INT
    :它是一个保留字),并将所有
    KEY
    更改为
    KEY


    您可能还想做一些类似于
    NAME
    KEY
    中的
    [a-z]
    选项的事情(也就是说,一个小写字符现在永远不会被标记为
    NAME
    ,始终是
    KEY
    )。

    您的问题是什么?你希望你的代码做什么?我想正确解析文件。为什么我会出错?很抱歉没有说清楚-我已经更新了问题。你是如何处理换行的?我忽略所有的换行。我有
    空白:[\t\r\n]+->skip“正确解析文件”是什么意思?非常感谢!成功了!但是,现在我在NAME和INT之前有了KEY,像
    leftFlipper NAME=a x=16 y=2 orientation=0
    这样的东西会给出一个错误,因为现在NAME在匹配NAME之前匹配KEY。@aashishtripathe,确实,一个数字现在不会作为
    INT
    匹配,而是作为
    @aashishtripathe检查我的编辑你保存了我的培根。谢谢
    KEY : [a-z] | 'shift' | 'ctrl' | 'alt' | 'meta' | 'space' | 'left' | 'right' | 'up' | 'down' | 'minus' | 'equals' | 'backspace' | 'openbracket' | 'closebracket' | 'backslash' | 'semicolon' | 'quote' | 'enter' | 'comma' | 'period' | 'slash' ;
    
    KEYPRESS : 'keyup' | 'keydown' ;
    
    NAME : [A-Za-z_][A-Za-z_0-9]* ;
    
    SINGLE_DIGIT : [0-9] ;
    
    INT : [0-9]+ ;
    
    integer : INT | SINGLE_DIGIT ;
    
    key : KEY | SINGLE_DIGIT ;