当前位置: 首页 > 知识库问答 >
问题:

在antlr4 lexer中,如何有一个规则来捕捉所有剩余的“单词”作为未知标记?

马阳曦
2023-03-14
Whitespace : [ \t\n\r]+ -> skip;
Punctuation : [.,:;?!];
// Other rules here
Unknown : .+? ; 

现在生成的匹配器将'~'捕获为未知,但为输入'~~~'创建3'~'未知标记,而不是单个'~~~'标记。我应该做些什么来告诉lexer为未知的连续字符生成单词标记。我还尝试了“未知:.;”和“未知:.+;”没有结果。

编辑:在当前的antlr版本中。+?现在捕获剩余的单词,所以这个问题似乎得到了解决。

共有1个答案

连成益
2023-03-14

.+?在lexer规则末尾将始终匹配单个字符。但是.+将尽可能多地消耗,这在ANTLR v3中的规则末尾是非法的(v4可能也是如此)。

您所能做的只是匹配一个字符,并在解析器中将这些字符“粘合”在一起:

unknowns : Unknown+ ; 

...

Unknown  : . ; 

...但我只有lexer没有parser...

lexer grammar Lex;

@members {

  public static void main(String[] args) {
    Lex lex = new Lex(new ANTLRInputStream("foo, bar...\n"));
    for(Token t : lex.getAllTokens()) {
      System.out.printf("%-15s '%s'\n", tokenNames[t.getType()], t.getText());
    }
  }

  private java.util.Queue<Token> queue = new java.util.LinkedList<Token>();

  @Override
  public Token nextToken() {    

    if(!queue.isEmpty()) {
      return queue.poll();
    }

    Token next = super.nextToken();

    if(next.getType() != Unknown) {
      return next;
    }

    StringBuilder builder = new StringBuilder();

    while(next.getType() == Unknown) {
      builder.append(next.getText());
      next = super.nextToken();
    }

    // The `next` will _not_ be an Unknown-token, store it in 
    // the queue to return the next time!
    queue.offer(next);

    return new CommonToken(Unknown, builder.toString());
  }
}

Whitespace  : [ \t\n\r]+ -> skip ;
Punctuation : [.,:;?!] ;
Unknown     : . ; 
java -cp antlr-4.0-complete.jar org.antlr.v4.Tool Lex.g4 
javac -cp antlr-4.0-complete.jar *.java
java -cp .:antlr-4.0-complete.jar Lex
Unknown         'foo'
Punctuation     ','
Unknown         'bar'
Punctuation     '.'
Punctuation     '.'
Punctuation     '.'
 类似资料:
  • 现在生成的匹配器捕获“~”为未知,但为输入“~”创建3个“~”未知令牌,而不是单个“~”令牌。我应该做什么来告诉lexer为未知的连续字符生成单词令牌。我还试过“未知:.;”和“未知:.+;”没有结果。 编辑:在当前的antlr版本中。+?现在捕获剩余的单词,所以这个问题似乎已经解决了。

  • 我有一个前端带有angular的spring boot应用程序。 我正在使用html5模式的ui路由器,我希望spring能够呈现相同的索引。所有未知路径上的html。 所以我的问题是,我如何创建一个后备映射,但它允许通过资源?

  • 问题内容: 据我所知,netty通过重写方法exceptionCaught()处理异常。但是我想要的是一个可以处理所有异常的处理程序。因此,管道应类似于: InboundExceptionHandler- inboundHandler1-inboundHandler2-outboundHandler1-outboundHandler2-OutboundExceptionHandler 这意味着我应

  • 可以使用以下命令将 RecyclerView 捕捉到其中心: 示例: 主活动. kt activity_main.xml 也可以将其捕捉到另一侧,就像在一些库中所做的那样,比如这里。 也有一些库允许RecyclerView像ViewPager一样工作,比如这里。 假设我有一个包含许多项目的RecyclView(在我的例子中是水平的),我希望它将每个X项目(X是常数)视为一个单元,并与每个单元对齐。

  • 问题内容: 在下面的HTML片段中,如何使包含“ LAST”的列的宽度占据行的其余部分,并且包含“ COLUMN ONE”和“ COLUMN TWO”的列的宽度足够宽以包含其内容,而不是更大。 谢谢 问题答案: 您将需要告诉前两列不要换行,并为最后一列提供99%的宽度: 编辑: 您应该将所有样式/演示文稿放在(外部…)css中。 对列使用类(如果您仅针对现代浏览器,则可以使用css3选择器,例如)

  • 在我的数据框架中,有一列名为“teams”。它包括城市和球队名称。我想把这个城市拉进另一个纵队。这是数据帧:数据帧示例 我可以使用正则表达式轻松提取列: 然而,在“名称”栏中,对于纽约尼克斯队,它只给了我“New”的值,我想得到“New York”: 结果 那么,我该怎么做呢?如果单元格有2个单词,我该如何从开头只提取一个单词?如果单元格有3个单词,我该如何使用正则表达式从中提取2个单词?