2018年7月21日土曜日

開発環境

ということで、SION.g4を書いてみることに。まずはSIONの「各種データのサポート状況」を見ながら書いてみて、次にLexical Structureを見ながらちょっと修正してみた。

SION.g4

//  Created by kamimura on 2018/07/21.
//  Copyright © 2018 kamimura. All rights reserved.

grammar SION;

si_self : si_nil
        | si_bool
        | si_bool
        | si_int
        | si_double
        | si_string
        | SI_DATA
        | si_date
        | si_array
        | si_map
        ;

si_nil: 'nil';
si_bool: si_true
       | si_false
       ;
si_true: 'true';
si_false: 'false';

si_int: SI_SIGN? si_ints;
si_ints: si_bin
       | si_oct
       | SI_DECIMAL
       | si_hex
       ;
si_bin:'0b' si_bin_digits;
si_bin_digits: ('0'|'1') ('0'|'1'|'_')*;

si_oct:'0o' SI_OCT_DIGIT;
SI_OCT_DIGIT: [0-7][_0-7]*;

SI_DECIMAL: [0-9]+ [_0-9]*;

si_hex: '0x' SI_HEX_DIGIT;
SI_HEX_DIGIT: [0-9a-fA-F] [_0-9a-fA-F]*;

si_double: SI_DOUBLE_DECIMAL
         | SI_DOUBLE_HEX
         ;

SI_DOUBLE_DECIMAL: [0-9][_0-9]* '.' ([0-9][_0-9]*)*
                 | [0-9][_0-9]* ('.' ([0-9][_0-9]*)*)? SI_DECIMAL_EXP;
SI_DECIMAL_EXP: ('e'|'E') SI_SIGN? SI_DECIMAL;

SI_DOUBLE_HEX: '0x' SI_HEX_DIGITS;
SI_HEX_DIGITS: SI_HEX_DIGIT ('.' SI_HEX_DIGIT)? SI_HEX_EXP;
SI_HEX_EXP: ('p'|'P') SI_SIGN? SI_DECIMAL;

SI_SIGN: ('+'|'-');

si_string: si_string_line
         | si_string_multiline
         ;
si_string_line: '"'  si_string_line_element '"';
si_string_line_element: ( SI_ESC | . | SI_UNICODE)*?;
si_string_multiline: '"""' si_string_multiline_element '"""';
si_string_multiline_element: ( SI_ESC | . | SI_UNICODE | '\r'?'\n')*?;

SI_ESC: '\\' ["\\/bfnrt];
SI_UNICODE: [\u{000000}-\u{10ffff}];

SI_DATA: '.Data("' SI_BASE64* '")';
SI_BASE64: [a-zA-Z0-9+/=];

si_date: '.Date(' si_double ')';
si_array: si_array_empty
        | '[' si_array_elements ']'
        ;
si_array_empty: '[' ']';
si_array_elements: si_self (',' si_self)*;    

si_map: si_empty_map
      | si_nonempty_map
      ;
      
si_empty_map: '[' ':' ']';
si_nonempty_map: '[' si_pair (',' si_pair)* ']';
si_pair: si_nil_key_pair
       | si_bool_key_pair
       | si_int_key_pair
       | si_double_key_pair
       | si_string_key_pair
       | si_array_key_pair
       | si_map_key_pair
       ;
si_nil_key_pair: si_nil ':' si_self;
si_bool_key_pair: si_bool ':' si_self;
si_int_key_pair: si_int ':' si_self;
si_double_key_pair: si_double ':' si_self;
si_string_key_pair: si_string ':' si_self;
si_array_key_pair: si_array ':' si_self;
si_map_key_pair: si_map ':' si_self;

COMMENT: '//' .*? '\r'? '\n' -> skip;
WS: [ \t\n\r]+ -> skip ;

各ルールの最初に全て「si」(SIONのSI)を付けたのは、target言語(試したのは Java と Python)の予約語と衝突してエラーになる場合があったからで、それなら最初から全てに「si」を付けておけば、あとあと問題が起こりにくいかなぁと考えて。

大文字、小文字の違いは、小文字でエラーになった場合に大文字に書き直したらエラーがなくなったからそうしてみたという理由で、ANTLRでの大文字小文字の違いはまだよく分かってなかったり。(このことについては、The Definitive ANTLR 4 Referenceをしっかり読み返せば分かりそう。)

必要以上に(?)できるだけルールを細かく分けて書いたのは、後々他の言語(ANTLR4はJava、C#、Python、JavaScript、Go、C++、Swiftに対応してるみたい)で作成するときに役立つかもしれないと考えて。

次回は、出来上がったSIONVisitor.pyを編集してみることに。

(意外に早くできたら、これとは逆方向のPython のオブジェクトをSIONに変換するのをちゃんと修正、追加等してくっつけようかなぁと思ってみたり。)

0 コメント:

コメントを投稿