当前位置: 首页 > 面试题库 >

获取Antlr规则的原始文本

闻人哲茂
2023-03-14
问题内容

我是ANTLR初学者,想计算符号的SHA1-哈希值。

我的简化示例语法:

grammar Example;

method @after{calculateSha1($text); }: 'call' ID;

ID: 'A'..'Z'+;
WS: (' '|'\n'|'\r')+ {skip(); }
COMMENT: '/*' (options {greedy=false;}: .)* '*/' {$channel=HIDDEN}

当词法分析器删除所有空白时,将使用不同的字符串callABC,但是call /* DEF */ ABC不幸的是,获得了相同的SHA1-Hash值。

是否有可能在所有跳过的空格和其他通道的文本之间获得规则的“原始”文本?

(我想到的一种可能性是将所有字符都包含在WS-和COMMENT-lexer规则中,但是还有更多规则,因此这不是很实用。)

我使用标准的ANTLRInputStream来提供Lexer,但是我不知道如何接收原始文本。


问题答案:

而不是skip()-ping WS令牌,也将其放在HIDDEN通道上:

grammar Example;

@parser::members {
  void calculateSha1(String text) {
    try {
      java.security.MessageDigest md = java.security.MessageDigest.getInstance("SHA-1");
      byte[] sha1 = md.digest(text.getBytes());
      System.out.println(text + "\n" + java.util.Arrays.toString(sha1) + "\n");
    } catch(Exception e) {
      e.printStackTrace();
    }
  }
}

parse 
  :  method+ EOF
  ;

method
@after{calculateSha1($text);}
  :  'call' ID
  ;

ID      : 'A'..'Z'+;
WS      : (' ' | '\t' | '\n' | '\r')+ {$channel=HIDDEN;};
COMMENT : '/*' .* '*/' {$channel=HIDDEN;};

上面的语法可以通过以下方式进行测试:

import org.antlr.runtime.*;

public class Main {
  public static void main(String[] args) throws Exception {
    String source = "call ABC call /* DEF */ ABC";
    ExampleLexer lexer = new ExampleLexer(new ANTLRStringStream(source));
    ExampleParser parser = new ExampleParser(new CommonTokenStream(lexer));
    parser.parse();
  }
}

它将以下内容打印到控制台:

致电ABC
[48,-45,113,5,-52,-128,-78,75,-52,-97,-35,25,-55,59,-85,96,-58,58,-96, 10]

致电/ * DEF * / ABC
[-57,-2,-115,-104,77,-37,4,93,116,-123,-47,-4,33,42,-68,-95,-43,91,94, 77]

即:相同的解析器规则,但不同$text的(因此具有不同的SHA1)。



 类似资料:
  • 考虑ANTLR4中的以下lexer规则: 在可以访问(其中是由解析器规则生成的的子类)的树行走场景中,是否可以获得lexer规则和的文本表示?我当前使用获取整个文本表示,并使用regexes解析和的内容,我只是想知道是否有一个“cleaner”开箱即用的解决方案。 注意:由于外部依赖关系,不能将作为解析器规则。 提前感谢有意义的回答。

  • 问题内容: 使用Java 7语法https://github.com/antlr/grammars-v4/blob/master/java7/Java7.g4,我想查找具有特定名称的方法,然后仅打印该方法。我看到我可以在匹配时使用该规则。因此,我继承并覆盖了此侦听器方法: 如何获得原始文本? 给我一个字符串,其中所有空格都被删除。我想要注释和原始格式。 问题答案: ANTLR的类有一个方法,该方法

  • 本文向大家介绍ANTLR 优先规则,包括了ANTLR 优先规则的使用技巧和注意事项,需要的朋友参考一下 示例 几个词法分析器规则可以匹配相同的输入文本。在这种情况下,令牌类型将选择如下: 首先,选择与最长输入匹配的词法分析器规则 如果文本与隐式定义的标记匹配(例如'{'),请使用隐式规则 如果多个词法分析器规则匹配相同的输入长度,请根据定义顺序选择第一个 以下是组合语法: 给出以下输入: 将从词法

  • 本文向大家介绍ANTLR 简单规则,包括了ANTLR 简单规则的使用技巧和注意事项,需要的朋友参考一下 示例 Lexer规则定义令牌类型。它们的名称必须以大写字母开头,以区别于解析器规则。 基本语法: 语法 含义 A 匹配名称为lexer的规则或片段 A A B 比赛A之后B (A|B) 匹配A或B 'text' 匹配文字“文本” A? 匹配A零或一次 A* 匹配A零次或多次 A+ 匹配A一次或多

  • 问题内容: 在我的应用程序中,我使用来显示一些日志信息。因为我想突出显示文本中的某些特定行(例如错误消息),所以将设置为“ ”。这样,我可以设置文本格式。 现在,我创建一个JButton,将其内容复制到剪贴板中。这部分很简单,但是我的问题是,当我调用时,我得到了HTML代码,例如: 而不是只获取原始内容: 有没有办法只获取纯文本格式的内容?还是我需要自己将HTML转换为原始文本? 问题答案: 基于

  • 问题内容: 我在相当基本的android开发水平上。 我想从诸如“ http://www.google.com”的页面获取文本。(我将使用的页面只有文本,因此没有图片或类似的东西)所以,要明确:我想将页面上的文本写入应用程序中的字符串等。 我尝试了这段代码,但是我什至不知道它是否能满足我的要求。 无论如何我都无法收到任何文字。我应该怎么做? 问题答案: 从您提供的示例代码中,您甚至没有读取请求的响