我在“hiphop原理分析2”中主要分析了语法结构、语法树的生成、作用域内容以及analyzeProgram的功能分析;
本章中,我主要分析hiphop中的所有statement,expressio的对应关系,还有对于所有语句和表达式的analyzeProgram的详细分析。
?
1.语句(statement)结构
2.表达式(Expression)结构
3.analyzeProgram详细分析
4.变量表分析
?
?
statement是所有hiphop的一个基类,statement继承Construct,Construct是statement和expression的公共基类,也就是说hiphop的所有的语法结构都是Construct的子类,statement类在src/complier/statement/statement.cpp下;
statementList是一个容器,是封装statement的一个列表容器,m_stmts成员保存statement的内容;
简单表达式语句,如:$a=”aaa”,这样的形式的表达式存放到ExpStatement中,然后下级还会保存其他形式的表达式,封装在m_exp中,ExpStatement在exp_statement.cpp中;
=============================================================================
//存放表达式如: $a=1;
? //?这就是一个expstatement
? //然后在m_exp中存入的是一个assignmentExpressionexp1:a op:= scalarExpression:1
? ExpressionPtr m_exp;
=============================================================================
表达式形式:static$s_1="s_1";或static $a,$b;
???????? Staticstatement中有一个成员m_exp(ExpressionListPtr),在m_exp中保存了所有的static的声明的表达式,一般应该为
???????? SimpleVarible类型,或者Binary_op_expression(exp1:simpleVarible,exp2:scalarExpression)
echoStatement保存echo “aaa”形式的语句,然后echo后面的表达式封装在m_exp(expressionList)中,
=============================================================================
???????? //表达式列表
???????? /*
?????????如echo "aa";
???????? m_exp保存的就是ScalarExpression
?????????如果为echo"aa".$b."cc";
?????????这样的右侧就是BinaryOpExpression嵌套了一个BinaryOpExpression;
?????????如(1)BinaryOpExpression exp1: BinaryOpExpression exp2:scalarExpression (cc)
???????? (2)BinaryOpExpression:exp1:scalarExpression exp2:scalarExpression
???????? */
? ExpressionListPtr m_exp;
=============================================================================
块语句{},他里面有一个成员m_stmts保存块内的语句,目前只发现if用了,m_stmts中保存了所有的块下的statement语句
global $a,$b;
?m_exp (ExpressionListPtr)保存的是global下的所有的表达式内容:
?simpleVarible?有2个对象保存在m_exp下分别是$a,$b
?
return xxx;形式的语句用returnstatement封装,其中有一个成员m_exp(ExpressionPtr)保存return?后面的表达式;
?
methodstatement是类的成员函数是封装到该statement中,其实methodstatement是函数的封装主体,外部函数也将数据封装到methodstatement中,因为functionstatement是其子类,methodstatement类在src/complier/statement/method_statement.cpp中;
============================================================================
function和method的属性封装解释
//是否是类函数
? bool m_method;
? //是否引用
? bool m_ref;
? int m_attribute;
? int m_cppLength;
? //函数的修饰符如(public,protect,private)
? /*??342, T_PUBLIC
???? 343, T_PROTECTED
???? 344, T_PRIVATE*/
? ModifierExpressionPtr m_modifiers;
? //函数名字
? std::string m_name;
? //原始函数名字
? std::string m_originalName;
? //函数的类名称(如果类原始名字为大写,会转为小写)
? std::string m_className;
? //函数类的原始名字(未转换为小写)
? std::string m_originalClassName;
? //参数列表
? ExpressionListPtr m_params;
? //块内语句列表
? StatementListPtr m_stmt;
? //注释
? std::string m_docComment;
============================================================================
functionstatement是methodstatement的子类,封装的语句为非类的成员函数,都是用functionstatement保存,function的属性都保存在methodstatement中,functionstatement类在src/complier/statement/function_statement.cpp中;
?
接口类型的语句信息是封装到InterfaceStatement中,如interfacetest_i{},该类是在interface_statement.cpp中;
Interfacestatement成员:
//token类型353T_CLASS
? int m_type;
? //类之间派生关系在saveParseTree前就确定了(词法)
? //如class A
? //父类的名字,hiphop变名字为小写a
? std::string m_parent;
? //父类的原始名称?原始名称为A
? std::string m_originalParent;
?
classStatement是interfaceStatement的子类,classStatement主要封装的是类的信息,而一些基本的信息会封装在interfacestatement中,classstaement在class_statement.cpp中;
Classstament的成员属性:
//token类型353T_CLASS
? int m_type;
? //类之间派生关系在saveParseTree前就确定了
? //如class A
? //父类的名字,hiphop变名字为小写a
? std::string m_parent;
? //父类的原始名称?原始名称为A
? std::string m_originalParent;
classVarible是类变量语句,如public $a,$b;
classVarible的成员变量解释:
=============================================================================
//如public $a,$b;
? //修饰符idpublic,protected,private
?ModifierExpressionPtr m_modifiers;
? //声明的表达列表
? /*如: public$a,$b;
?m_declaration?就是多个simpleVarible
? */
?ExpressionListPtr m_declaration;
=============================================================================
classConstant是类常量语句,如Const d=2;?或const d,a;
classConstant语句成员解释:
=============================================================================
?
???????? //Constd=2;?或const d,a;
?/*m_exp?中保存的是const的表达式列表,
??如d=2?是BinaryOpExpression(exp1 :smipleVarible :d ;exp2:scalarExpression :2)
? d,a是多个simpleVarible
? */
?ExpressionListPtr m_exp;
=============================================================================
语句形式:unset($a)
Unset是销毁对象的语句,其中m_exp(ExpressionListPtr),保存的是销毁对象的表达式,一般应该是simpleVarible的表达式
?
?
?
?
Loopstatement是hiphop中其他循环语句的基类(do,while,for,foreach)
Php中的do{…}while()语句封装到dostatement中;
Dostatment?下m_stmt(statementList)是保存块内的所有语句的成员;
Dostatement下的m_condition(ExpressionPtr)是保存while中的条件的表达式,一般该表达式为BinaryOpExpression类型;
Php?中的while(){}语句封装到whilestatement中;
Whilestatement中的2个成员:
? //条件表达式,封装while中的条件
?ExpressionPtr m_condition;
? //块内容,封装的是while块内的所有语句
?StatementPtr m_stmt;
Php中的for(;;){..}语句封装到forstatement中;
Forstatement中有4个重要的成员:(exp1,exp2, exp3, m_stmt)
//for?中第一个表达式BinaryOpExpression(二元表达式)
?ExpressionPtr m_exp1;
? //第二个表达式BinaryOpExpression
?ExpressionPtr m_exp2;
? //第三个表达式UnaryOpExpression(一元表达式)
?ExpressionPtr m_exp3;
?//m_stmt?是存放for{}的块内的所有的statement的List
?StatementPtr m_stmt;
Php中foreach(array_expression as $key => $value) {}?的语句封装到foreachstatement中;
Foreachstatement的几个重要的成员:
//如foreach($fib as$index => $value)
? //存数类型都是simplevarible
? //第一个参数flib
?ExpressionPtr m_array;
? //第二个参数index
?ExpressionPtr m_name;
? //第三个参数?value
?ExpressionPtr m_value;
?bool m_ref;
?//m_stmt存放的是foreach?的{}内的所有的statement内容
?StatementPtr m_stmt;
?
Php中的switch语句,switch(){},一般swtichstatement都会和casestatement语句搭配,所以下面看看switchstatement的成员:
//保存的是switch($m_type)括号中的变量的smipleVarible
?ExpressionPtr m_exp;
? //保存的是caseStatment的集合,包括default
?StatementListPtr m_cases;
一般和switch语句搭配,switch(xxx){case xx:},casestatement下有2个成员:
? //是case后的条件表达式,scalarExpression,如case1,default的m_condition是空指针
?ExpressionPtr m_condition;
? //这个是case下的语句,包括break;
?StatementPtr m_stmt;
Php中的if ()整体语句都在ifstatement中封装,有一个statementList的成员保存着多个if:
/*m_stmts?保存的是多个IfBranchStatement如if(){}else if(){}else if(){}
??下面无论有多少个子集if,在m_stmts中只保存2个ifBranchStatement,如果是多个
??那么在第二个statement下面进行链式存储
? */
?StatementListPtr m_stmts;
Ifbranchstatement是if () elseif()这样的块语句,并且可以多个的话都保存在m_stmt中
Ifbranchstatement有2个属性:
m_condition:保存条件表达式;
m_stmt:保存多层if语句的,详细见下面注释:
//条件
? //这?个是if ()括号内的条件,一般为一个BinaryOpExpression
? /*
?????????如果是嵌套if块的话if () elseif() else if() else if()...或if() else
?????????在ifstatement中的m_stmts中会保存2个statement?,第一个保存的是正常的,第二个是链式的
?????????如果是链式连接后面的,那么m_condition是0x0空指针
?????????然后在m_stmt下继续是保存2个stmt以此类推,如:
???????? if(c1)elseif (c2) if else(c3)if else(c4)那么存储结构如下:
???????? ifstatment->m_stmt->(1)ifBranchstatment-> m_condition?是c1,m_stmt是第一个if?下的语句内容
???????? ifstatment->m_stmt->(2)ifBranchstatment-> m_condition?是个0x0,m_stmt?是个ifstatement保存2个ifBranchstatment{
?????????第一个ifBranchstatment??的m_condition是第一个else if?的c2条件m_stmt是第一个else if块内的内容
?????????第二个ifBranchstatment的m_condition是0x0,m_stmt是个ifstatement?保存2个ifBranchstatment;
?
?????????然后第一个ifBranchstatment保存的是第三个elseif的条件和块语句内容,第二个ifBranchstatment
???????? m_condition是0x0 ,m_stmt保存的是一个ifstatement,m_stmts保存着一个ifBranchstatment?是最后的那个elseif
???????? }
? */
?ExpressionPtr m_condition;
?//if块内的所有实现的statmentList的内容
?StatementPtr m_stmt;
?
Breakstatement,continustatement封装break和continue的2个语句类、
?
Try{..}catch(….){}finally{…}
Trystatement的成员:
//try的实现体内容
?StatementPtr m_tryStmt;
? //多个catchstatement
?StatementListPtr m_catches;
? // finallyStmt保存finallystatement
?StatementPtr m_finallyStmt;
Catch(xxxx){},catchstatement的成员变量:
//catch?括号里的变量
?SimpleVariablePtr m_variable;
?//catch的实现体
?StatementPtr m_stmt;
?StatementPtr m_finallyStmt;
?bool m_valid;
Finally{…}
在finallystatement中封装finally语句,其中{}块内的语句通过m_stmt(StatementPtr)变量封装。
?
语句形式:throws Exception
在throwstatement中保存Exception的成员是m_exp(ExpressionPtr)
?
如下5种类型的表达式我未使用过,所以也就没有对其进行分析:
useTraitstaetement,traintAliasstatement,traitPrestatement,gotostatement,
labelstatement
?
expressionList主要是保存表达式列表的一个类,其中有3个成员变量组成:
? //表达式集合
?ExpressionPtrVec m_exps;
? intm_outputCount;
? //是否是array的元素
?bool m_arrayElements;
? //链表类型
?ListKind m_kind;
一元表达式语句,比如$a++,$a[i]等等,在unaryExpression中有几个重要成员:
? //表达式,保存表达式的类型如变量等
?ExpressionPtr m_exp;
?//默认作用域
?BlockScopeRawPtr m_definedScope;
?/符号token
? intm_op;
二元表达式如:$a=1,$a>1等,BinaryExpression有如下几个重要成员:
? //表达式1,左表达式
?ExpressionPtr m_exp1;
? //表达式2,右表达式
?ExpressionPtr m_exp2;
?//op的token类型,caozuofu.html" target="_blank">操作符的token,如?+,-,>等等
? intm_op;
? //是否是赋值表达式
?bool m_assign;
?
assignmentExpression形式:赋值表达式既是一个赋值表达式,也是一个特殊的二元表达式,该表达式的成员如下:
? //变量
?ExpressionPtr m_variable;
? //变量值
?ExpressionPtr m_value;
一般为值表达式,如$a=1,$b=”aaa”,scalarExpression一般封装后面的值如:1,”aaa”,该表达式成员为:
? //类型(tokenid)
? intm_type;
? //序列化的值:"i:3;",这就是int类型,值为3
?std::string m_serializedValue;
?double m_dval;
? //当前值,转换后的值
?std::string m_value;
? //原始值,未进行转换的值,如大写转小写
?std::string m_originalValue;
? //转换值(如类转换等),一般为强转类型值
?std::string m_translated;
简单变量表达式,如:$a=1,$b=”c”,这里的$a和$b都是一个simpleVarible,该表达式成员为:
//变量名称
?std::string m_name;
? //注释
?std::string m_docComment;
? //是否是超级类型如_GET等,参见LoadSuperGlobals()函数
?TypePtr m_superGlobalType;
?Symbol *m_sym;
?Symbol *m_originalSym;
? //是否是合法的$this
?unsigned m_this : 1; // whether this is a legitimate $this
? //是否是global
?unsigned m_globals : 1; // whether is is $GLOBAL
常量表达式,如
define('FOO_BAR','It works!');
主要成员有名称(m_name),注释
?
arrayPairExpression形式是array("a"=>"Dog","b"=>"Cat","c"=>"Horse");这样声明方式的array调用这个表达式;其中的"a"=>"Dog"是里面的一个ArrayPairExpression,ArrayPairExpression成员:
?//m_name保存的是a?是ScalarExpression类型
?ExpressionPtr m_name;
?//m_value?保存的是"Dog"?是ScalarExpression类型
?ExpressionPtr m_value;
?bool m_ref;
arrayElementExpression形式为:array[1]或array[“key”],arrayElementExpression的成员如下:
? //存变量内容的(simpleVarible)
?ExpressionPtr m_variable;
? //存下标内容的(scalarExpression)
?ExpressionPtr m_offset;
?
ObjectPropertyExpression的表达式形式:$b->b=aaa;
其中ObjectPropertyExpression的成员有:
//存放的是$b?内容simpleVarible
?ExpressionPtr m_object;
? //保存的是->b?的b的内容scalarExpression
?ExpressionPtr m_property;
修饰符表达式,其中的m_modifiers主要保存着修饰符的token,如public ,private,protected
staticClassName是functionCall、classConstantExpression、ConstantExpression、staticMemberExpression的父类;staticClassName表达式有如下成员:
? /*
?$a_c=new A();
?echo $a_c::b
??这种的调用方式中m_class存在,是一个simpleVarible的类型
? */
?ExpressionPtr m_class;
? //类的原始名称
?std::string m_origClassName;
? //类名,如果为self::a则,这里是self?,如静态调用时的类名也保存在这里,如B::c
?std::string m_className;
类常量表达式,形式为:B::c,其中有2个重要的成员,如:
? //常量名称,保存的是c ,B??保存在StaticClassName中
?std::string m_varName;
?BlockScope *m_defScope;
静态成员变量表达式,形式如:B::$c,在该表达式类中有几个重要的成员,如下:
//静态调用B::$c保存的是$c ,B类名保存在StaticClassName中,m_exp保存的是$c,scalarExpression的
?ExpressionPtr??? m_exp;
? //是否有效
?bool???????????? m_valid;
? //当前静态成员解析后隶属的类作用域,如B::$c?,那么就是B的作用域
?ClassScopeRawPtr m_resolvedClass;
? //是否是动态的
?bool???????????? m_dynamicClass;
函数调用表达式,相关的调用类的表达式都是functionCall的子类,该表达式有如下具体的成员,并进行分析:
? //调用的函数的函数表达式,如:$a->test();scalarExpr(test)
?ExpressionPtr m_nameExp;
? //调用方法的名称
? /*
?????????类操作中:
???????? $test=newA();
???????? $test->aaa();
???????? m_name保存的是a(这是类的名字)
?????????然后m_origName保存的会是A这是类的原始名字
?????????这个参数信息是类的构造函数传入的参数信息如:
?????????????????? classA{
??????????????????????????? functionA($a,$b){
????????
??????????????????????????? }
?????????????????? }
?????????????????? $a=newA("aaa","bbb");
?????????????????? m_params保存的就是一个expressionList
???????????????????保存了2个scalarExpression("aaa")和一个scalarExpression("bbb")
???????????????????这个不是调用函数的参数,保存的构造函数的参数信息
?
???????? --------------------------------------------------------------
?????????函数操作中:
?????????如:
???????? functionTest($a,$b){
?????????????????? ...
???????? }
???????? Test("a","b");
?????????那么m_name?是test
???????? m_origName保存的是Test
???????? m_params参数信息是保存一个expressionList
?????????保存了2个scalarExpression("a")和一个scalarExpression("b")
? */
?std::string m_name;
? //?调用方法的原始名称
?std::string m_origName;
? intm_ciTemp;
? intm_clsNameTemp;
? /*参数信息
???*/
?ExpressionListPtr m_params;
?
? //Pointers to the corresponding function scope and class scope for this
? //function call, set during the AnalyzeAll phase. These pointers may be
? //null if the function scope or class scope could not be resolved.
? //这个保存的是单独函数的函数作用域,和类的构造函数
?FunctionScopeRawPtr m_funcScope;
? //保存的是类的函数作用域
?ClassScopeRawPtr m_classScope;
?
simpleFunctionCallExpression主要封装的是外部函数的调用,不在类中封装的,如:
在a函数中调用了b函数,其实这个表达式也是很复杂的,如在类中调用,外层中调用,函数中调用,在静态分析和优化阶段都需要对其进行很复杂的处理,并且该表达式是functionCall的子类,信息封装在functionCall中
?
newObjectExpression是functionCall的子类,用于定义newXXX()这样的表达式类型;
其中的名字(m_name)保存在functionCall中还有构造函数的参数也封装在functioncall中(m_params)
ObjectMethodExpression封装的是对象调用函数,如:$a->test(),那么这个test就是ObjectMethodExpression,这个表达式类也是functionCall的子类,在该类中有个成员,m_object保存的是对象信息,如:
$a->test();
m_object?是$a simpleVaribale对象,test()信息保存在funcationcall中
?
?
ParameterExpression主要是function和method中的m_params属性中保存着
?
cloureExpression,QopExpression,DymanicFunctionCall,DymanicVarible,EncapsListExpressionList,ListassignmentExpression,这些目前没有进行分析,IncludeExpression没有遇到主要问题也没有进行详细分析;
?
下一节:hiphop 原理分析3(2)
?