我是一名ANTLR初学者,想要计算符号的SHA1-Hash.
我的简化示例语法:
grammar Example;
method @after{calculateSha1($text); }: 'call' ID;
ID: 'A'..'Z'+;
WS: (' '|'\n'|'\r')+ {skip(); }
COMMENT: '/*' (options {greedy=false;}: .)* '*/' {$channel=HIDDEN}
Run Code Online (Sandbox Code Playgroud)
由于词法分析器删除了不同字符串的所有空格callABC,call /* DEF */ ABC不幸的是得到相同的SHA1-Hash值.
是否有可能在开始和结束标记之间获取规则的"原始"文本以及所有跳过的空格和其他通道的文本?
(我想到的一种可能性是成员WS- 和 - COMMENT工具规则中的所有字符,但是还有更多规则,所以这不太实用.)
我使用标准的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;};
Run Code Online (Sandbox Code Playgroud)
上面的语法可以通过以下方式进行测试:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
这会将以下内容打印到控制台:
拨打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 不同)。
| 归档时间: |
|
| 查看次数: |
1956 次 |
| 最近记录: |