在腳本里有很多語句組成的,那么對于語句又是怎么進行語法分析的呢?下面就來分析
for
語句的分析過程,它的聲明代碼如下:
#001
?
class LLScriptFor : public LLScriptStatement
#002
?
{
#003
?
public:
構造函數,輸入保存的值。
#004
?
??
LLScriptFor(S32 line, S32 col, LLScriptExpression *sequence, LLScriptExpression *expression, LLScriptExpression *expressionlist, LLScriptStatement *statement)
#005
?
??????
: LLScriptStatement(line, col, LSSMT_FOR), mSequence(sequence), mExpression(expression), mExpressionList(expressionlist), mStatement(statement),
#006
?
mType(LST_NULL)
#007
?
??
{
#008
?
??
}
#009
?
析構造函數。
#010
?
??
~LLScriptFor()
#011
?
??
{
#012
?
??
}
#013
?
遞歸處理函數。
#014
?
??
void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type,
#015
?
LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
獲取語句生成代碼的大小。
#016
?
??
S32 getSize();
#017
?
初始化表達式。
#018
?
??
LLScriptExpression
?????
*mSequence;
條件判斷表達式。
#019
?
??
LLScriptExpression
?????
*mExpression;
最后執行的表達式列表。
#020
?
??
LLScriptExpression
?????
*mExpressionList;
循環體的語句塊。
#021
?
??
LLScriptStatement
??????
*mStatement;
腳本的類型。
#022
?
??
LSCRIPTType
????????????
mType;
#023
?
};
下面來分析它的遞歸調用函數的處理:
#001
?
void LLScriptFor::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type,
#002
?
LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
#003
?
{
如果分析出錯就返回。
#004
?
??
if (gErrorToText.getErrors())
#005
?
??
{
#006
?
??????
return;
#007
?
??
}
下面根據不同的遍來處理。
#008
?
??
switch(pass)
#009
?
??
{
打印輸出腳本的代碼。
#010
?
??
case LSCP_PRETTY_PRINT:
#011
?
??????
fdotabs(fp, tabs, tabsize);
#012
?
??????
fprintf(fp, "for ( ");
#013
?
??????
if(mSequence)
#014
?
??????????
mSequence->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount,
#015
?
NULL);
#016
?
??????
fprintf(fp, " ; ");
#017
?
??????
mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
#018
?
??????
fprintf(fp, " ; ");
#019
?
??????
if(mExpressionList)
#020
?
??????????
mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry,
#021
?
entrycount, NULL);
#022
?
??????
fprintf(fp, " )/n");
#023
?
??????
if(mStatement)
#024
?
??????????
mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount,
#025
?
NULL);
#026
?
??????
break;
下面輸出編譯出來的匯編代碼。
#027
?
??
case LSCP_EMIT_ASSEMBLY:
#028
?
??????
{
#029
?
??????????
S32 tjump1 =
?
gTempJumpCount++;
#030
?
??????????
S32 tjump2 =
?
gTempJumpCount++;
#031
?
??????????
if(mSequence)
#032
?
??????????????
mSequence->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize,
#033
?
entry, entrycount, NULL);
#034
?
??????????
fprintf(fp, "LABEL ##Temp Jump %d##/n", tjump1);
#035
?
??????????
mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount,
#036
?
NULL);
#037
?
??????????
fprintf(fp, "JUMPNIF ##Temp Jump %d##/n", tjump2);
#038
?
??????????
if(mStatement)
#039
?
??????????????
mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize,
#040
?
entry, entrycount, NULL);
#041
?
??????????
if(mExpressionList)
#042
?
??????????????
mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize,
#043
?
entry, entrycount, NULL);
#044
?
??????????
fprintf(fp, "JUMP ##Temp Jump %d##/n", tjump1);
#045
?
??????????
fprintf(fp, "LABEL ##Temp Jump %d##/n", tjump2);
#046
?
??????
}
#047
?
??????
break;
下面優化代碼,如果代碼不用運行,就可以刪除。
#048
?
??
case LSCP_PRUNE:
#049
?
??????
if (ptype == LSPRUNE_DEAD_CODE)
#050
?
??????????
prunearg = TRUE;
#051
?
??????
else
#052
?
??????????
prunearg = FALSE;
#053
?
??????
break;
下面進行
for
語句的類型檢查。
#054
?
??
case LSCP_TYPE:
#055
?
??????
if(mSequence)
#056
?
??????????
mSequence->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount,
#057
?
NULL);
#058
?
??????
mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
#059
?
??????
mType = type;
#060
?
??????
if(mExpressionList)
#061
?
??????????
mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry,
#062
?
entrycount, NULL);
#063
?
??????
if(mStatement)
#064
?
??????????
mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount,
#065
?
NULL);
#066
?
??????
break;
下面生成
for
語句的目標代碼。
#067
?
??
case LSCP_EMIT_BYTE_CODE:
#068
?
??????
{
#069
?
??????????
char jumpname1[32];
????
??
/*Flawfinder: ignore*/
#070
?
??????????
snprintf(jumpname1, sizeof(jumpname1), "##Temp Jump %d##", gTempJumpCount++);
?
/* Flawfinder: ignore */
#071
?
??????????
char jumpname2[32];
????????
??
/*Flawfinder: ignore*/
#072
?
??????????
snprintf(jumpname2, sizeof(jumpname2), "##Temp Jump %d##", gTempJumpCount++);
??
/* Flawfinder: ignore */
#073
?
#074
?
??????????
if(mSequence)
#075
?
??????????????
mSequence->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap,
#076
?
stacksize, entry, entrycount, NULL);
#077
?
??????????
chunk->addLabel(jumpname1);
#078
?
??????????
mExpression->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry,
#079
?
entrycount, NULL);
#080
?
??????????
chunk->addByte(LSCRIPTOpCodes[LOPC_JUMPNIF]);
#081
?
??????????
chunk->addByte(LSCRIPTTypeByte[mType]);
#082
?
??????????
chunk->addBytes(LSCRIPTDataSize[LST_INTEGER]);
#083
?
??????????
chunk->addJump(jumpname2);
#084
?
??????????
if(mStatement)
#085
?
??????????????
mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize,
#086
?
entry, entrycount, NULL);
#087
?
??????????
if(mExpressionList)
#088
?
??????????????
mExpressionList->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk,
#089
?
heap, stacksize, entry, entrycount, NULL);
#090
?
??????????
chunk->addByte(LSCRIPTOpCodes[LOPC_JUMP]);
#091
?
??????????
chunk->addBytes(LSCRIPTDataSize[LST_INTEGER]);
#092
?
??????????
chunk->addJump(jumpname1);
#093
?
??????????
chunk->addLabel(jumpname2);
#094
?
??????
}
#095
?
??????
break;
下面生成
CIL
的匯編代碼。
#096
?
??
case LSCP_EMIT_CIL_ASSEMBLY:
#097
?
??????
{
#098
?
??????????
S32 tjump1 =
?
gTempJumpCount++;
#099
?
??????????
S32 tjump2 =
?
gTempJumpCount++;
#100
?
??????????
if(mSequence)
#101
?
??????????????
mSequence->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize,
#102
?
entry, entrycount, NULL);
#103
?
??????????
fprintf(fp, "LabelTempJump%d:/n", tjump1);
#104
?
??????????
mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount,
#105
?
NULL);
#106
?
??????????
fprintf(fp, "brfalse LabelTempJump%d/n", tjump2);
#107
?
??????????
if(mStatement)
#108
?
??????????????
mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize,
#109
?
entry, entrycount, NULL);
#110
?
??????????
if(mExpressionList)
#111
?
??????????????
mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize,
#112
?
entry, entrycount, NULL);
#113
?
??????????
fprintf(fp, "br LabelTempJump%d/n", tjump1);
#114
?
??????????
fprintf(fp, "LabelTempJump%d:/n", tjump2);
#115
?
??????
}
#116
?
??????
break;
下面進行遞歸處理
for
里出現的表達式。
#117
?
??
default:
#118
?
??????
if(mSequence)
#119
?
??????????
mSequence->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount,
#120
?
NULL);
#121
?
??????
mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
#122
?
??????
if(mExpressionList)
#123
?
??????????
mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry,
#124
?
entrycount, NULL);
#125
?
??????
if(mStatement)
#126
?
??????????
mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount,
#127
?
NULL);
#128
?
??????
break;
#129
?
??
}
#130
?
??
gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
#131
?
}
在語法分析里,把所有合法的語句都生成一個合適的類對象,然后通過遍歷所有類對象進行類型檢查,或者生成代碼。所有其它語句都是這樣進行的,比如語句 if 就是使用類 LLScriptIf 來保存和分析的。當檢查所有腳本都是合法的語法后,就生成了語法樹,后面通過遍歷語法樹來生成代碼。
?
?
?
第二人生開發包提供,價格
198
元
/
套(含郵費)。
包括內容如下:
1.
???
《第二人生的源碼分析》
PDF
文檔。
2.
???
第二人生客戶端源程序。
3.
???
提供三個月的技術服務,
提供快速編譯指導,比如通過
QQ
遠程編譯操作。
提供完整的書參考。
聯系方式:
QQ:
????????????
9073204
MSN:
???????????
caimouse1976@sina.com
EMAIL:
???
??????
ccaimouse@gmail.com
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
