2. Hiphop 编译原理分析
接着上节没有分析完的内容继续分析
2.1. hiphop 编译处理流程
编译流程以 echo “test”;简单分析
(1)加载web server基本信息,通过调用RuntimeOption::Load(empty)方法进行加载
(2)初始化加载扩展基本内容:prepareOptions(po, argc, argv);初始化编译配置;BuiltinSymbols::LoadSuperGlobals()加载php 如_get,_session等函数的返回值类型等;BuiltinSymbols::Load和ar->loadBuiltins()加载扩展类、扩展方法、扩展常量、扩展变量
(3)parser:通过调用Package的parser方法,执行lex和bison进行词法和语法分析,生成语法分析树
(4) analyzeProgram:语义分析阶段,进行划分作用域和控制流等
(5)(7)代码优化
(6)类型推导
(8)生成代码
2.2. hiphop 词法分析
例:echo “test”;
进入词法和语法分析的入口是Package::parse方法
词法分析规则文件是在src/Utile/Parse/hphp.x中,是用flex进行词法分析的
echo “test”
匹配了2个token分别为:
T_ECHO 和T_CONSTANT_ENCAPSED_STRING
Hphp.x中的匹配规则如下:
echo词法分析为T_ECHO
<ST_IN_SCRIPTING>"echo" { SETTOKEN; return T_ECHO;}
“test” 解析TOKEN为T_CONSTANT_ENCAPSED_STRING
ANY_CHAR (.|[\n])
DOUBLE_QUOTES_LITERAL_DOLLAR("$"+([^a-zA-Z_\x7f-\xff$\"\\{]|("\\"{ANY_CHAR})))
DOUBLE_QUOTES_CHARS("{"*([^$\"\\{]|("\\"{ANY_CHAR}))|{DOUBLE_QUOTES_LITERAL_DOLLAR})
<ST_IN_SCRIPTING>(b?[\"]{DOUBLE_QUOTES_CHARS}*("{"*|"$"*)[\"]){
int bprefix = (yytext[0] != '"') ? 1 : 0;
std::string strval =
_scanner->escape(yytext + bprefix + 1,
yyleng - bprefix -2, '"');
_scanner->setToken(yytext, yyleng, strval.c_str(), strval.length());
return T_CONSTANT_ENCAPSED_STRING;
}
Hiphop 定义的默认Token 结构是:
#define YYSTYPE HPHP::ScannerToken
调用流程:
(1)首先调用:hphp.y中的
static int yylex(YYSTYPE *token,HPHP::Location *loc, Parser *_p) {
return _p->scan(token, loc);}调用扫描器;
(2)然后扫描器scan调用扫描器:Scanner::getNextToken ,获取token
(3)然后调用hphp.x中的:
int Scanner::scan() {
return yylex(m_token, m_loc, m_yyscanner);
}
(4)执行yylex对lex语法进行分析
TOKEN分词,目前echo “test”给拆分成了2个TOKEN
echo => T_ECHO
“test” =>T_CONSTANT_ENCAPSED_STRING
这里都是通过正则匹配进行词法分析的:
(1) echo
<ST_IN_SCRIPTING>"echo" { SETTOKEN; return T_ECHO;}
当遇到echo 时则返回T_ECHO,其他依次类推,更多的分析,我们将在原理分析二中进行分析语句(statement)和表达式(expression)
(2) “test”
通过正则分析最终匹配T_CONSTANT_ENCAPSED_STRING,常量String的这个TOKEN
词法分析完成后,下一步就是进行语法分析了
2.3. hiphop 语法分析
之前lex 已经划分出了2个token: T_ECHO 和T_CONSTANT_ENCAPSED_STRING
根据token 查找语法规则:
Hphp的语法分析是用bison分析的,在src/Utile/Parse/hphp.y文件中
T_ECHO expr_list { _p->onEcho($$, $2,0);}
匹配上这里后,然后expr_list 又是一个合成规则,继续递归往下找,直到找到最终匹配规则:
common_scalar:
T_LNUMBER { _p->onScalar($$, T_LNUMBER, $1);}
|T_DNUMBER { _p->onScalar($$, T_DNUMBER, $1);}
|T_CONSTANT_ENCAPSED_STRING {_p->onScalar($$,
T_CONSTANT_ENCAPSED_STRING, $1);}
最终封装为一个语法树
具体规则内容:
start:
top_statement_list { _p->popLabelInfo();
_p->saveParseTree($$);}
;
top_statement_list:
top_statement_list
top_statement { _p->addStatement($$,$1,$2);}
| {_p->onStatementListStart($$);}
;
top_statement:
statement { _p->nns($1.num() == T_DECLARE);
$$ =$1;}
............
;
statement:
……..
|T_ECHO expr_list ';' {_p->onEcho($$, $2, 0);}
/////////////////////////////////////
expr_list:
expr_list ',' expr { _p->onExprListElem($$, &$1, $3);}
|expr {_p->onExprListElem($$, NULL, $1);};
/////////////////////////////////
expr:
...............
|scalar { $$ =$1;}
.............;
/////////////////////////////////////////
scalar:
.........
|common_scalar { $$ =$1;}
............
;
common_scalar:
T_LNUMBER { _p->onScalar($$,T_LNUMBER, $1);}
|T_DNUMBER {_p->onScalar($$, T_DNUMBER, $1);}
|T_CONSTANT_ENCAPSED_STRING {_p->onScalar($$,
T_CONSTANT_ENCAPSED_STRING, $1);}
…………..
具体流程如下:
语法分析从start开始,类似top_statement:{…..}是一个语句;
如我们的echo,他会逐个的语句中去找,最终在
statement:
……..
|T_ECHO expr_list ';' {_p->onEcho($$, $2, 0);}
这个语句中找到了T_ECHO,然后{这里面的是调用的实现代码}
移进是一个自顶向下的过程,规约是一个自底向上的过程;
Statement=> T_ECHO=> expr_list=> expr=>scalar=>common_scalar=> T_CONSTANT_ENCAPSED_STRING
这就一个echo “test” 的语法分析:
首先找到T_ECHO 然后向下找expr_list;
expr_list 又有子集expr;
expr,这个表达式呢又找到是一个scalar的;
scalar表达式子集中common_scalar又有匹配;
最终在common_scalar中找到匹配的TOKEN (T_CONSTANT_ENCAPSED_STRING)
匹配的过程其实就是一个移进规约的过程:
Echo “test”
这里的.是游标
Echo .”test” 移进
EchoExpression “test”. 规约
EchoExpression ExpressionList 规约
EchoExpression. ScalarExpression移进
EchoExpression ExpressionList. 移进
EchoExpression ExpressionList规约
EchoExpression. ExpressionList移进
Statement 规约
Statement. 移进
top_statement 规约
top_statement. 移进
top_statement_list 规约
移进规约后生成一颗语法树;
Parser::onScalar 这个方法是获取T_CONSTANT_ENCAPSED_STRING这个token 后创建一个saclarExpression的实例
然后调用_p->onExprListElem($$, NULL, $1);是将saclarExpression封装到exprList中
然后调用onEcho 是将exprList封装到EchoStatment语句中,这样就生成了一个语法树
上面的$$类似于树的顶点,也就是每次处理后返回的封装节点,$1则是传入的token或者表达式等内容的信息,对其进行封装
生成的语法树:
hiphop Token 的数据结构:
class Token : public ScannerToken :
ExpressionPtr exp;
StatementPtr stmt;
Class ScannerToken:
int m_num; // internal token id
std::string m_text;
bool m_check;
相关推荐
hiphop无穷动
每个人都喜欢Hip Hop音乐和Hip Hop Beats,现在Trap成为都市音乐界的一种趋势。 这就是为什么如果您是一名艺术家,则必须获得最好的嘻哈节拍和器乐。 不管他们是R&B,Smooth,Trap还是New School ...他们都必须听...
【HipHop-Step的历史与名称由来】 HipHop-Step,作为街舞文化的重要组成部分,起源于20世纪70年代末至80年代初的纽约。它的诞生源自多种舞蹈形式的融合,其中包括非洲舞蹈、Capoeira、B-Boy舞蹈、Jazz舞以及Tap舞...
通过下载并分析Hiphop-API-master这个压缩包,我们可以深入研究其内部结构,包括源代码文件、文档、示例和测试等,以全面了解Hiphop API的功能和用法。此外,社区的支持和讨论也是学习和解决问题的重要资源,可以...
"Raslani Hip Hop"可能是指一种特定的字体风格,它结合了Hip Hop文化的元素,旨在为文本内容增添独特的个性和动态感。这种字体可能广泛应用于音乐制作、广告设计、游戏界面、社交媒体帖子以及各种创意项目中,以吸引...
"HIP与NOW缺陷"是两个常见的问题,尤其是在半导体制造和集成电路(IC)设计中。本文将深入探讨这两个缺陷的本质、成因以及如何进行预防和解决。 首先,HIP,全称为Heat Induced Pinholing,翻译为热诱导针孔缺陷。...
Sa-HipHop,最新的南非音乐Mp3下载还包括SA Hip Hop,非洲之家,深层之屋,Gqom,科威特,部落,Masandi和Ampiano。 Sa-HipHop:南非的灵魂音乐在Sa-HipHop的此处下载,我们随时为您提供最好,最精彩的Sa Hip Hop和...
简单hiphop街舞教学视频.doc
享受您最喜爱的Hip Hop艺术家的高清图像 - Lil Pump。每个新标签都会获得不同的壁纸。 如果您喜欢嘻哈音乐,那么您肯定对Lil Pump有所了解。 我们添加了您最喜欢的艺术家的高清背景。 此外,借助我们的Twitter小部件...
安装此扩展程序并享受您最喜爱的RnB和Hip Hop艺术家的高清背景 - The Weeknd。 您喜欢RnB和嘻哈音乐吗? 您喜欢The Weeknd吗? 如果您这样做,那么此扩展名仅适合您。 每个新标签页都会为您显示不同的高清背景或The ...
《HipHop PHP:Facebook的PHP虚拟机与JIT技术解析》 HipHop PHP,是由Facebook在2010年推出的一款高效能的PHP运行时环境,旨在提高PHP代码的执行效率,尤其是对于大规模Web应用来说,它能显著提升性能。这款工具...
嘻哈(Hip Hop)街舞文化起源于20世纪70年代初的美国纽约布朗克斯区,由牙买加移民Kool Herc开创。Kool Herc是最早将大型音响设备带到街头,举办露天派对的人,他的派对因其创新的音乐播放方式——使用唱盘技巧放大...
获取Hip Hop音乐最大传奇-Tupac(2pac)的高清图像 享受! 如果您喜欢2pac和他的音乐。 您打开的每个新标签页都会为他提供高清背景。 除此之外,我们还为您提供了他的官方Twitter帐户的快速访问权限。 因此,您将第...
其中,广告牌(Billboard)的嘻哈图表(Hip-Hop Chart)更是备受关注,它反映了当下最热门的嘻哈音乐趋势。本篇文章将围绕“广告牌嘻哈图表API”展开,探讨如何利用Python语言与其进行交互,获取并分析实时的嘻哈...
1. **hiphop**:hiphop是一种源自美国的街头文化,包含了说唱(Rap)、涂鸦(Graffiti)、街舞(Breakdance)和DJ(Disk Jockey)四大部分。此模板将hiphop元素融入设计,如使用hiphop风格的图形、字体和色彩,以...
HipHop:响应式Web编程 Hiphop.js是用于编排Web应用程序的 DSL。 "use hiphop" "use hopscript" const hh = require ( "hiphop" ) ; hiphop module prg ( in A , in B , in R , out O ) { do { fork { await ...
您是否在为下一个项目寻找West Coast,Gangsta,G-Funk或Hip Hop Beats和Instrumental? 这是你的地方! 许多人在节拍和器乐中寻找那种高品质的声音,这些声音使人想起了旧学校和西海岸的嘻哈音乐的开端,但是却没有...