用ANTLR分析简单的十六进制格式字符串
一、问题:
假设现在有一个16进制格式的文本字符串,如下:
0x00, 0x06, 0x6E, 0x61, 0x6e, 0x61, 0x6d, 0x69,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
目标是解析其中的含义。
其中
0x00, 0x06, 0x6E, 0x61, 0x6e, 0x61, 0x6d, 0x69,
表示一个长度为6的字符串
0x6E, 0x61, 0x6e, 0x61, 0x6d, 0x69即"nanami"
而0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02表示两个32位无符号整数1和2。
二、思路:
如果用ANTLR的.g文件描述,大概是:
packet
: str16 uint32 uint32
;
意思是依次读取变长字符串、32位整数、32位整数。
我的想法是用ANTLR的谓词语法处理变长的字符串
完整的.g文件如下:
/*
Text :
0x00, 0x06, 0x6E, 0x61, 0x6e, 0x61, 0x6d, 0x69,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
Start Rule :
packets
Output :
username : nanami
x : 1
y : 2
*/
grammar Binary;
@header {
}
@members {
private int str_num = 0;
private int str_length = 0;
}
packets
: (packet (',')? NEWLINE* )*
;
packet
:
username=str16 {System.out.println("username : " + $username.value);}
x=uint32 {System.out.println("x : " + x);}
y=uint32 {System.out.println("y : " + y);}
;
str16 returns [String value]
@init { str_num = 0; StringBuffer sb = new StringBuffer();}
@after { value = sb.toString();}
: s1=ushort16 {str_length = $s1.value;}
(
{str_num < str_length}?=>(
b1=byte8 {sb.append((char)$b1.value);}
{str_num++;}
)
)*
;
byte8 returns [int value]
@init { value = 0; }
@after {}
: b1=BYTE8
{
if ($b1.text.startsWith("0x")) {
value |= Integer.parseInt($b1.text.substring(2), 16);
}
}
',' NEWLINE?
;
ushort16 returns [int value]
@init { value = 0;}
@after {}
: b1=BYTE8
{
if ($b1.text.startsWith("0x")) {
value |= Integer.parseInt($b1.text.substring(2), 16) << 8;
}
} ',' NEWLINE?
b2=BYTE8
{
if ($b2.text.startsWith("0x")) {
value |= Integer.parseInt($b2.text.substring(2), 16);
}
} ',' NEWLINE?
;
uint32 returns [int value]
@init { value = 0; }
@after {}
: b1=BYTE8
{
if ($b1.text.startsWith("0x")) {
value |= Integer.parseInt($b1.text.substring(2), 16) << 24;
}
} ',' NEWLINE?
b2=BYTE8
{
if ($b2.text.startsWith("0x")) {
value |= Integer.parseInt($b2.text.substring(2), 16) << 16;
}
} ',' NEWLINE?
b3=BYTE8
{
if ($b3.text.startsWith("0x")) {
value |= Integer.parseInt($b3.text.substring(2), 16) << 8;
}
} ',' NEWLINE?
b4=BYTE8
{
if ($b4.text.startsWith("0x")) {
value |= Integer.parseInt($b4.text.substring(2), 16);
}
} ',' NEWLINE?
;
// LEXER
BYTE8: '0x' HexDigit HexDigit;
fragment
HexDigit: ('0'..'9'|'a'..'f'|'A'..'F');
WS: (' '|'\t'|'\u000C') {$channel=HIDDEN;};
NEWLINE: ('\r')? '\n';
三、测试结果:
用ANTLRWorks测试,输入数据设置为
0x00, 0x06, 0x6E, 0x61, 0x6e, 0x61, 0x6d, 0x69,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
开始规则(Start Rule)设置为 packets
输出为:
username : nanami
x : 1
y : 2
四、总结:
相比起其它语言(诸如C的struct和Erlang的binary数据类型匹配),
用ANTLR的BNF语法处理二进制的解码会比较麻烦(需要先转换为文本型的字符串),
而且灵活性很小(虽然可以用谓词分析变长的字符串,但处理更复杂的结构会很困难)。
不过个人觉得这个问题对于了解ANTLR的语法和ANTLRWorks的测试环境很有帮助。
分享到:
相关推荐
用antlr分析处理布尔表达式的例子,包括:语法定义.g文件;生成的词法分析和语法分析器;带有图形界面的分析器调用代码。 其中带有GUI的分析器ParserFrame,可以用于任何.g文件生成的词法、语法分析器,只要通过改变...
它是如何工作的我正在使用ANTLR生成带有语法文件的Java词法分析器和解析器。 “计算器语言”由数字,运算符,空格,方括号组成...我构建的语法的目的是将计算器语言转换为堆栈机器语言。然后,我们可以使用src / ...
我们学校的编译原理课程设计有关antlr的词法分析和语法分析
ANTLR是一款强大的语法分析器生成工具,可用于读取、处理、执行和翻译结构化的文本或二进制文件。它被广泛应用于学术领域和工业生产实践,是众多语言、工具和框架的基石。Twitter搜索使用ANTLR进行语法分析,每天...
ANTLR3.0简单编译入门.pdf,学习antlr很好的资源
文法分析器类主要用于把读入的字节流根据规则分段
antlr第五章Action协助分析 出处www.antlr.org.cn
antlr指南 第四章语法分析 出自www.antlr.org.cn
利用Antlr生成C++描述的分析程序.pdf Antlr入门详细教程.doc 利用ANTLR生成C 描述的分析程序.htm 使用 Antlr 处理文本.htm 使用 Antlr 开发领域语言.htm 强悍的ANTLR Lexer.htm a little madness » Blog Archive »...
antlr-v4的jar包,及其简单的官方使用教程,可用于生成词法分析和语法分析的Java代码。语法分析的方式是LL(1)。
小型常规语言编译器 仅支持简单变量定义,支持的数据类型有: uint8(无符号字符型数据——8位) char(字符型数据) string(字符串类型数据) uint16(16位无符号整数) int16(16位整数)...
赠送jar包:antlr4-runtime-4.2.jar; 赠送原API文档:antlr4-runtime-4.2-javadoc.jar; 赠送源代码:antlr4-runtime-4.2-sources.jar; 赠送Maven依赖信息文件:antlr4-runtime-4.2.pom; 包含翻译后的API文档:...
正文 使用Antlr+Stringtemplate生成method chaining 在这里 http://blog.csdn.net/younggift/article/details/7028932
JavaEE源代码 antlr-2.7.6rc1JavaEE源代码 antlr-2.7.6rc1JavaEE源代码 antlr-2.7.6rc1JavaEE源代码 antlr-2.7.6rc1JavaEE源代码 antlr-2.7.6rc1JavaEE源代码 antlr-2.7.6rc1JavaEE源代码 antlr-2.7.6rc1JavaEE源...
antlr 2.7.7源码,下载自:http://repo.spring.io/plugins-release/org/antlr/com.springsource.antlr/2.7.7/
赠送jar包:antlr-3.5.jar; 赠送原API文档:antlr-3.5-javadoc.jar; 赠送源代码:antlr-3.5-sources.jar; 赠送Maven依赖信息文件:antlr-3.5.pom; 包含翻译后的API文档:antlr-3.5-javadoc-API文档-中文(简体)版...
ANTLR 1989-2006 Developed by Terence Parr @ University of San Francisco We reserve no legal rights to the ANTLR--it is fully in the public domain. An individual or company may do whatever they ...
其中.g为ANTLR源文件,可生成语法分析器和语法树的.java文件,然后进行必要的修改(添加成员变量)。提供的.java文件已经修改好。直接放在项目里,选择主类Frame,编译运行即可。在窗口里输入测试文件的路径,即可绘...
开源项目-antlr-antlr4.zip,antlr 4.6发布,支持go代码生成