PHPで字句解析 + 構文木生成ツールを作る その3
俺俺BNFから文法規則を生成できるようになりました。
試しにJSONの文法を定義してみます。
// json_grammar.txt // 俺俺BNF space := SPACE comment := "//" LINE ignore := (space | comment)* @leaf string_val := DOUBLE_QUOTE_STRING_ITEM* string := "\"" string_val "\"" @leaf key_val := DOUBLE_QUOTE_STRING_ITEM* key := "\"" key_val "\"" @leaf true := "true" @leaf false := "false" @leaf number := ("-")? DECIMAL_INTEGER ("." DIGIT+)? ([eE] [-+]? DIGIT+)? @leaf null := "null" literal := (string | true | false | null | number) ignore value := literal | object | array @node array := "[" ignore (value ("," ignore value )*)? "]" ignore @node key_and_value := key ignore ":" ignore value @node object := "{" ignore (key_and_value ("," ignore key_and_value)*)? "}" ignore @node json := ignore (object | array | value)*
PHPのコード
<?php include_relative( 'BNFProcessor.php'); $json_grammar_bnf = file_get_contents( 'json_grammar.txt'); // ここで文法生成 $p = new BNFProcessor(); $grammars = $p->process( $json_grammar_bnf); // json text $text = '{"menu": { "id": "file", "value": "File", "popup": { "menuitem": [ {"value": "New", "onclick": "CreateNewDoc()"}, {"value": "Open", "onclick": "OpenDoc()"}, {"value": "Close", "onclick": "CloseDoc()"} ] } }}'; // さっき生成した文法でJSONテキストを解釈して構文木を表示 $node = $grammars['json']->process( $si = new StringIterator( $text)); $node->display();
これを実行すると…
json { object { key_and_value { key_val('menu') object { key_and_value { key_val('id') string_val('file') } key_and_value { key_val('value') string_val('File') } key_and_value { key_val('popup') object { key_and_value { key_val('menuitem') array { object { key_and_value { key_val('value') string_val('New') } key_and_value { key_val('onclick') string_val('CreateNewDoc()') } } object { key_and_value { key_val('value') string_val('Open') } key_and_value { key_val('onclick') string_val('OpenDoc()') } } object { key_and_value { key_val('value') string_val('Close') } key_and_value { key_val('onclick') string_val('CloseDoc()') } } } } } } } } } }
きちんと構文木が生成されていることがわかります。