使用 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 条评论。