使用 ANTLR 可以很快速的开发新的语言。
于是我写了个 .g4 文件, 使用 C# 为语法添加上语义之后, 可以用来解析一些文件。
这个语言我把它叫做 Wandai’s Data Block parse Language。
使用名为 GLOBAL 的 map 来存放变量们, 我把它叫做变量表。
语法如下:
<ID> 为合法变量, 允许 a-z, A-Z, ‘_’, 0-9 但是不能以 0-9 开头。
<expr> 为表达式, 其返回类型一定为 64 位整数。
print(<ID>); 可以输出变量
print(<expr>); 可以输出表达式
remove(<ID>); 可以将一个变量删除
skip(<expr>); 可以从流中跳过一定长度的数据
(‘ubyte’ | ‘uint’ | ‘ushort’ | ‘ulong’ | ‘char’ | ‘byte’ | ‘int’ | ‘short’ | ‘long’) <ID>; 可以读取一个指定的类型并存放入变量中。
(‘little_endian’ | ‘big_endian’) (‘ubyte’ | ‘uint’ | ‘ushort’ | ‘ulong’ | ‘char’ | ‘byte’ | ‘int’ | ‘short’ | ‘long’) <ID>; 可以根据指定的大小端读取一个指定的类型并存放入变量中。
<ID>
{
<var_def>
…
}; 可以用来定义一坨。
在 <ID> 之后加入 [<expr>] 可以定义”数组”。
例如, 可以使用 print(GLOBAL); 来输出变量表。
例如, 用于解析没有FACT块的wav文件可以撰写如下DBL代码:
RIFF_HEADER
{
char RiffID[4];
little_endian uint RiffSize;
char RiffFormat[4];
};
print(RIFF_HEADER);
delete(RIFF_HEADER);
FMT_BLOCK
{
char FmtID[4];
little_endian uint FmtSize;
WAVE_FORMAT
{
little_endian ushort FormatTag;
little_endian ushort Channels;
little_endian uint SamplesPerSec;
little_endian uint AvgBytesPerSec;
little_endian ushort BlockAlign;
little_endian ushort BitsPerSample;
};
skip(FmtSize-16);
};
print(FMT_BLOCK);
delete(FMT_BLOCK);
DATA_BLOCK
{
char DataID[4];
little_endian uint DataSize;
skip(DataSize);
};
print(DATA_BLOCK);
delete(DATA_BLOCK);
结果如下:
相关代码: PackageReader


1 条评论。