Closed hangingman closed 3 years ago
ref #32
nask.cf
まだ一部修正の余地はあるが、BNFCで作成したBNFは以下の通り
-- -- Nask.cf -- $ bnfc -m -cpp_stl nask.cf -- comment "#" "\\n" ; comment ";" "\\n" ; -- terminator Statement "\\n" ; entrypoints Program; Prog. Program ::= [Statement] ; (:[]). [Statement] ::= Statement ; (:). [Statement] ::= Statement [Statement] ; LabelStmt. Statement ::= Label ; DeclareStmt. Statement ::= Ident "EQU" Exp ; ConfigStmt. Statement ::= "[" ConfigType String "]" ; MnemonicStmt. Statement ::= Opcode [MnemonicArgs] ; OpcodeStmt. Statement ::= Opcode ; (:[]). [MnemonicArgs] ::= MnemonicArgs ; (:). [MnemonicArgs] ::= MnemonicArgs "," [MnemonicArgs] ; MnemoArg. MnemonicArgs ::= Exp ; EqExp. Exp ::= Exp "==" Exp ; NeqExp. Exp ::= Exp "!=" Exp ; LtExp. Exp ::= Exp "<" Exp ; GtExp. Exp ::= Exp ">" Exp ; LteExp. Exp ::= Exp "<=" Exp ; GteExp. Exp ::= Exp ">=" Exp ; PlusExp. Exp ::= Exp "+" Exp ; MinusExp. Exp ::= Exp "-" Exp ; MulExp. Exp ::= Exp "*" Exp ; DivExp. Exp ::= Exp "/" Exp ; ModExp. Exp ::= Exp "%" Exp ; IndirectAddrExp. Exp ::= "[" Exp "]" ; DatatypeExp. Exp ::= DataType "[" Exp "]" ; RangeExp. Exp ::= DataType Exp ":" Exp ; LabelExp. Exp ::= Label ; ImmExp. Exp ::= Factor ; NumberFactor. Factor ::= Integer ; HexFactor. Factor ::= Hex ; IdentFactor. Factor ::= Ident ; StringFactor. Factor ::= String ; BitsConfig. ConfigType ::= "BITS" ; InstConfig. ConfigType ::= "INSTRSET" ; OptiConfig. ConfigType ::= "OPTIMIZE" ; FormConfig. ConfigType ::= "FORMAT" ; PaddConfig. ConfigType ::= "PADDING" ; PadsConfig. ConfigType ::= "PADSET" ; SectConfig. ConfigType ::= "SECTION" ; AbsoConfig. ConfigType ::= "ABSOLUTE" ; FileConfig. ConfigType ::= "FILE" ; ByteDataType. DataType ::= "BYTE" ; WordDataType. DataType ::= "WORD" ; DwordDataType. DataType ::= "DWORD" ; OpcodesAAA. Opcode ::= "AAA" ; OpcodesAAD. Opcode ::= "AAD" ; OpcodesAAS. Opcode ::= "AAS" ; OpcodesAAM. Opcode ::= "AAM" ; ...(以下、定数定義が続く) token Hex '0' ('x'|'X') (digit | ["abcdef"] | ["ABCDEF"])+ '-'* '$'* ; token Label (letter | digit | '_')+ ':' ;
地味にこれは大変で、BNFC側で comment "#" "\\n" ; の形式でコメントを定義しつつそれでは生成されたflexの改行部分がうまく動かないのでsedでパッチを当てている
comment "#" "\\n" ;
最終的なflexの定義は以下のような感じ。Qiitaに記事を書いた flexには.*?のような最短マッチは実装されていない
<INITIAL>"#" BEGIN COMMENT; /* BNFC: block comment "#" "\\n" */ <COMMENT>\n BEGIN INITIAL; <COMMENT>[^\n] /* skip */; <INITIAL>";" BEGIN COMMENT1; /* BNFC: block comment ";" "\\n" */ <COMMENT1>\n BEGIN INITIAL; <COMMENT1>[^\n] /* skip */;
test.txt を用意
test.txt
DB 0x01, 0x02 DB 0x02 # comment DB 0x03 ; comment DB "hello"
$ ./testnask test.txt Parse Successful! [Abstract Syntax] (Prog [(MnemonicStmt [OpcodesDB] [(MnemoArg [(ImmExp [(HexFactor "0x01")])]), (MnemoArg [(ImmExp [(HexFactor "0x02")])])]), (MnemonicStmt [OpcodesDB] [(MnemoArg [(ImmExp [(HexFactor "0x02")])])]), (MnemonicStmt [OpcodesDB] [(MnemoArg [(ImmExp [(HexFactor "0x03")])])]), (MnemonicStmt [OpcodesDB] [(MnemoArg [(ImmExp [(StringFactor "hello")])])])]) [Linearized Tree] DB 0x01, 0x02 DB 0x02 DB 0x03 DB "hello"
ref #32
nask.cf
は385行(ほとんどオペコードの定数定義)まだ一部修正の余地はあるが、BNFCで作成したBNFは以下の通り
確認
1行コメントの字句解析と構文解析
地味にこれは大変で、BNFC側で
comment "#" "\\n" ;
の形式でコメントを定義しつつそれでは生成されたflexの改行部分がうまく動かないのでsedでパッチを当てている最終的なflexの定義は以下のような感じ。Qiitaに記事を書いた flexには.*?のような最短マッチは実装されていない
test.txt
を用意