• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
詳説ぺちぺち
 

詳説ぺちぺち

on

  • 1,074 views

 

Statistics

Views

Total Views
1,074
Views on SlideShare
1,073
Embed Views
1

Actions

Likes
1
Downloads
2
Comments
0

1 Embed 1

https://twitter.com 1

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    詳説ぺちぺち 詳説ぺちぺち Presentation Transcript

    • 詳説ぺちぺち 闇PHP勉強会 + PHPソースコード リーディングワークショップ 2012/01/28 do_aki
    • do_aki (どぅーあき)• |所属| > 株式会社もしも (ドロップシッピング・アフィリエイトASP)• |仕事| > インフラ(サーバ管理)兼 Webアプリケーション開発• |出現| > 渋谷・山手線沿線• |特性| > PHPer http://do-aki.net/
    • あじぇんだ• 第1章 ぺちぺち• 第2章 Scanner (字句解析器)• 第3章 Parser (構文解析器)• まとめ
    • 第1章ぺちぺち
    • Japanese Programming Language らきすた風 画像生成 (ジェネレーター) http://raki.st/
    • 闇鍋的PHP魔改造 2011/09/10 PHPカンファレンス2011 Presented By do_aki
    • PHPの言語そのものの作りとかよく 知らないし、内部構造もよく分からないけど、オレオレPHPを作って みたくてトライ&エラー繰り返していたら気づいたらPHPを基にした 日本語プログラミング言語ができ ちゃってたから発表してみたよ! ・・・というもの
    • <?php function HelloPHP() { echo "Hello PHP World"; } HelloPHP(); PHPぺちぺち 関数 はろーぺちぺち() ここから 「"はろー ぺちぺち わーるど"」と表示; ここまで ぺちぺち はろーぺちぺち();
    • 条件分岐もし [条件] ならば … そうでないならば …条件おわり
    • 繰り返し繰り返し [条件] の間ここから …ここまで
    • 変数/条件/演算子変数:ほげ は 0 です1 が 2 より小さい (1<2)1 が 2 より大きい (1>2)1 足す 2 (1+2)10 を 3 で割った余り (10%3)
    • 組み合わせるとぺちぺち変数:ほげ は 1です;繰り返し 変数:ほげ が 10 以下 の間ここから もし 変数:ほげ を 3 で割った余り が 0 に等しい ならば 「 “アホn"」と表示; そうでないならば 「 変数:ほげ,"n"」と表示; 条件おわり 変数:ほげ に 変数:ほげ 足す 1 を代入;ここまで
    • ぺちぺち と PHP の違い・Zend/zend_language_scanner.l add 98 lines & modify 22 lines・Zend/zend_language_parser.y add 65 lines & modify 1 line
    • 第2章Scanner
    • スキャナの状態 zend_language_scanner.l の半分から下あたり<ST_IN_SCRIPTING>"function" { return T_FUNCTION;} この文字列 このトークンを 返す が来たら<ST_IN_SCRIPTING>“{“ { yy_push_state(ST_IN_SCRIPTING TSRMLS_CC); return {;}
    • スキャナの状態 zend_language_scanner.l の半分から下あたり<ST_IN_SCRIPTING>“def" { return T_FUNCTION;} この文字列 このトークンを <?php返す が来たら<ST_IN_SCRIPTING>“{“ { の代わりに def function def hello() { echo “like ruby?”; yy_push_state(ST_IN_SCRIPTING TSRMLS_CC); return {; なんちゃって ruby のでき }} あがり
    • ぺちぺちでは<ST_IN_SCRIPTING>“function“|”関数” {<ST_IN_SCRIPTING>"function" { return T_FUNCTION;}<ST_IN_SCRIPTING>“{“ { ここから” {<ST_IN_SCRIPTING>“{“|” yy_push_state(ST_IN_SCRIPTING TSRMLS_CC); return {;}
    • スキャナの状態• INITIAL• ST_IN_SCRIPTING• ST_LOOKING_FOR_PROPERTY• ST_LOOKING_FOR_VARNAME• ST_VAR_OFFSET• ST_DOUBLE_QUOTES• ST_BACKQUOTE• ST_HEREDOC• ST_NOWDOC• ST_END_HEREDOC
    • ほとんどはこの状態 スキャナの状態• INITIAL 初期状態• ST_IN_SCRIPTING 基本状態• ST_LOOKING_FOR_PROPERTY ->これ• ST_LOOKING_FOR_VARNAME ${ これ}• ST_VAR_OFFSET $xxx[これ]• ST_DOUBLE_QUOTES “これ”• ST_BACKQUOTE `これ`• ST_HEREDOC <<<“DOC” の後• ST_NOWDOC <<<‘DOC’ の後• ST_END_HEREDOC DOC の終わり
    • ぺちぺち動かずぺちぺち echo "petipeti!n"; OKぺちぺち NG echo "petipeti!n";
    • <INITIAL>"<?php"([ t]|{NEWLINE})<INITIAL>("<?php"|"ぺちぺち")([ t]|{NEWLINE}) {<ST_IN_SCRIPTING>("?>"|"</script"{WHITESPACE}*">"){NEWLINE}? {<ST_IN_SCRIPTING>("?>"|"</script"{WHITESPACE}*">"|"ぺちぺちおしまい"){NEWLINE}? { これだけじゃ足りない orz <INITIAL>{ANY_CHAR} ???
    • 落とし穴• “変数”の扱いは少し複雑 – 3カ所 + 隠し1カ所 (Parser 側からのみ参照)• 複雑な処理をしているところも – HEREDOC , NOWDOC – __CLASS__• 簡単にセグる
    • <ST_IN_SCRIPTING,ST_DOUBLE_QUOTES,ST_HEREDOC,ST_BACKQUOTE,ST_VAR_OFFSET>"$"{LABEL} { zend_copy_value(zendlval, (yytext+1), (yyleng-1)); zendlval->type = IS_STRING; return T_VARIABLE; } <ST_IN_SCRIPTING,ST_DOUBLE_QUOTES,ST_HEREDOC,ST_BACKQUOTE,ST_VAR_OFFSET>(“$“|”変数:”){LABEL} { zend_copy_value(zendlval, (yytext+1), (yyleng-1)); zendlval->type = IS_STRING; } return T_VARIABLE; NG
    • <ST_IN_SCRIPTING,ST_DOUBLE_QUOTES,ST_HEREDOC,ST_BACKQUOTE,ST_VAR_OFFSET>"$"{LABEL} { zend_copy_value(zendlval, (yytext+1), (yyleng-1)); zendlval->type = IS_STRING; return T_VARIABLE; } 変数名をコ ピーして保持 <ST_IN_SCRIPTING,ST_DOUBLE_QUOTES,ST_HEREDOC,ST_BACKQUOTE,ST_VAR_OFFSET>”変数:” {LABEL} { zend_copy_value(zendlval, (yytext+7), (yyleng-7)); zendlval->type = IS_STRING; return T_VARIABLE; }
    • 第2章 Scanner まとめ• 元々あるキーワードの変更/追加は簡単• スキャナの状態もほとんど意識する必要 はない• ところどころ Cで無理矢理処理してる部分 があるので注意
    • 第2章Scanner 完
    • 第3章Parser
    • Scanner によるトークンへの分解<?php T_OPEN_TAG T_VARIABLE $x = $a + 1; ‘=‘ ++$x; T_VARIABLE ‘+’ T_LNUMBER ‘;’ T_INC T_VARIABLE ‘;’
    • Syntax Error T_LNUMBER ‘=’1 = $a; T_VARIABLE ‘;‘Perser にトークンの並びが定義さ れていない
    • zend_language_parser.y ルール名fully_qualified_class_name: namespace_name { $$ = $1; } | T_NAMESPACE T_NS_SEPARATOR namespace_name { $$.op_type = IS_CONST; ZVAL_EMPTY_STRING(&$$.u.constant); zend_do_build_namespace_name(&$$, &$$, &$3 TSRMLS_CC); } | T_NS_SEPARATOR namespace_name { char *tmp = estrndup(Z_STRVAL($2.u.constant), …(省略) };トークンの 処理(C言語+α) 並び
    • zend_language_parser.y 拡張するために 新たにルールを作る BAD 処理をどう書けばいいのか分 からない orz
    • 似ているルールを真似る
    • T_VARIABLE $a + 1 ‘+’ T_LNUMBERexpr + expr { zend_do_binary_op(ZEND_ADD, &$$, &$1, &$3 TSRMLS_CC); } New! T_VARIABLE $a 足す 1 T_JA_PLUS T_LNUMBERexpr T_JA_PLUS expr { zend_do_binary_op(ZEND_ADD, &$$, &$1, &$3 TSRMLS_CC); }
    • IF 文T_IF ( expr ) { zend_do_if_cond(&$3, &$4); }statement { zend_do_if_after_statement(&$4, 1); }elseif_list else_single { zend_do_if_end(); }else_single: /* empty */ | T_ELSE statement PHPT_JA_IF expr T_NARABA { zend_do_if_cond(&$2, &$3); }inner_statement_list { zend_do_if_after_statement(&$3, 1); }ja_else_single T_OWARI { zend_do_if_end(); }ja_else_single: /* empty */ ぺちぺち | T_JA_ELSE inner_statement_list
    • 落とし穴• 突然現れる ‘$’ – Scanner で T_VARIABLE として処理されてな い!?• 本気でやるなら opecode / ZendAPI の知識 が必須• コンパイルしてみないと分からない
    • Parser は 複雑なパズル 解きやすくするツール・方法あったら教えてほしいなー
    • 第3章 Parser 完
    • まとめ
    • Phpをいじり倒す10の方法 (2009) http://www.slideshare.net/moriyoshi/php10
    • 言いたかったこと• オレオレPHP作るの難しくないよ!• 拡張作るのも良いけど、言語そのものに コミットメントしてもいいんじゃないか な• PHPを楽しむ人が増えて、PHP がより一層 面白いものになってくれたらいいな
    • 改造のお供に• GNU GLOBAL (http://www.gnu.org/software/global/) – 静的にソースコードを解析するのに便利! – PHP のソースを展開したディレクトリで htags -Ffgnasv – CGI 使えれば検索も可能
    • 最後に• ぺちぺちは github においてあります• http://git.io/petipeti
    • ありがとうございました• 質疑応答?