用ANTLR分析簡單的十六進製制格式字串

2021-08-31 23:05:36 字數 2228 閱讀 9574

用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

packets

: (packet (',')? newline* )*

;packet

: username=str16

x=uint32

y=uint32

;str16 returns [string value]

@init

@after

: s1=ushort16

( ?=>(

) )*

;byte8 returns [int value]

@init

@after {}

: b1=byte8

}',' newline?

;ushort16 returns [int value]

@init

@after {}

: b1=byte8

} ',' newline?

b2=byte8

} ',' newline?

;uint32 returns [int value]

@init

@after {}

: b1=byte8

} ',' newline?

b2=byte8

} ',' newline?

b3=byte8

} ',' newline?

b4=byte8

} ',' newline?

;// lexer

byte8: '0x' hexdigit hexdigit;

fragment

hexdigit: ('0'..'9'|'a'..'f'|'a'..'f');

ws: (' '|'\t'|'\u000c') ;

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的測試環境很有幫助。

十六進製制的減法

實驗要求 程式設計計算3550h 2320h,按16進製制輸出計算所得的差1230h。再輸出3550h 2321h的差,檢驗程式的正確性。考慮依次將1230h 即0001 0010 0011 0000 b 從高位到低位,每4位二進位制數一組分離出來,再將4位二進位制數轉換為ascii碼,利用dos系...

十六進製制的TXT檔案怎麼以十六進製制讀出來?

txt中的內容是4e6574776f726b205365637572697479 但是執行後的不是txt中的十六進製制內容,include include include include typedef unsigned char byte typedef unsigned int dword 32...

漢字轉十六進製制 十六進製制轉漢字的函式

十六進製制轉漢字 public static string getchsfromhex string hex catch 獲得 cp936,chinese超集 system.text.encoding chs system.text.encoding.getencoding 936 code pag...