代码之家  ›  专栏  ›  技术社区  ›  garyM

antlr4如何修复lexer模式隐式令牌错误?

  •  2
  • garyM  · 技术社区  · 6 年前

    我与一些文本发生了令牌冲突,并且正在考虑使用lexer模式来解决这些问题。

    我在Lexer文件中创建了模式,但当我编译解析器文件时,会收到以下警告:

    warning(125): TSqlParser.g4:2377:26: implicit definition of token DISK in parser
    warning(125): TSqlParser.g4:2377:31: implicit definition of token TAPE in parser
    warning(125): TSqlParser.g4:2377:36: implicit definition of token URL in parser
    

    我怎样才能解决这个问题?

    我的模式定义是:

    BACKUP:                                'BACKUP' -> pushMode(BackupTokens);
    
    mode BackupTokens:
    DISK:                                  'DISK' -> popMode();
    TAPE:                                  'TAPE' -> popMode();
    URL:                                   'URL' -> popMode();
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   Bart Kiers    6 年前

    lexer语法中有几个错误:

    • 不是的 popMode() 但是 popMode
    • 不是的 mode BackupTokens: 但是 mode BackupTokens;

    所以,当你调用lexer语法时 TSqlLexer 包括以下内容:

    lexer grammar TSqlLexer;
    
    BACKUP : 'BACKUP' -> pushMode(BackupTokens);
    
    mode BackupTokens;
      DISK : 'DISK' -> popMode;
      TAPE : 'TAPE' -> popMode;
      URL  : 'URL'  -> popMode;
    

    那么您的解析器语法应该包括适当的 tokenVocab 在its中 options { ... } 块:

    parser grammar TSqlParser;
    
    options {
      tokenVocab=TSqlLexer;
    }
    
    ...
    

    编辑

    你知道模式块停在哪里吗?还是运行到EOF?

    模式块在 EOF ,或在下一个 mode

    提示:定义 fragment 在你语法的最上面的部分,你可以使用这些 碎片 来自所有模式:

    lexer grammar TSqlLexer;
    
    BACKUP : 'BACKUP' -> pushMode(BackupTokens);
    
    fragment DIGIT : [0-9];
    
    mode BackupTokens;
      ...
      A_RULE: DIGIT;
    
    mode OtherMode;
      ...
      SOME_RULE: DIGIT+;