📄 script_enc.c
字号:
case TOK_ASSIGN : return ET_ASSIGN; case TOK_PLUSEQ : return ET_PLUSEQ; case TOK_MINUSEQ : return ET_MINUSEQ; case TOK_MULTIPLYEQ : return ET_MULTIPLYEQ; case TOK_DIVIDEEQ : return ET_DIVIDEEQ; case TOK_MODEQ : return ET_MODEQ; case TOK_LSHIFTEQ : return ET_LSHIFTEQ; case TOK_RSHIFTEQ : return ET_RSHIFTEQ; case TOK_RSHIFTFILLEQ : return ET_RSHIFTFILLEQ; case TOK_ANDEQ : return ET_ANDEQ; case TOK_XOREQ : return ET_XOREQ; case TOK_OREQ : return ET_OREQ; case TOK_FUNCTION: return ET_FUNCTION_CALL; case TOK_VAR: return ET_VAR; default: assert(0); return (u32) -1; }}static const char *expr_name[] ={"ET_CURVED_EXPR","ET_NEGATIVE","ET_NOT","ET_ONESCOMP","ET_INCREMENT","ET_DECREMENT","ET_POST_INCREMENT","ET_POST_DECREMENT","ET_CONDTEST","ET_STRING","ET_NUMBER","ET_IDENTIFIER","ET_FUNCTION_CALL","ET_NEW","ET_OBJECT_MEMBER_ACCESS","ET_OBJECT_METHOD_CALL","ET_ARRAY_DEREFERENCE","ET_ASSIGN","ET_PLUSEQ","ET_MINUSEQ","ET_MULTIPLYEQ","ET_DIVIDEEQ","ET_MODEQ","ET_ANDEQ","ET_OREQ","ET_XOREQ","ET_LSHIFTEQ","ET_RSHIFTEQ","ET_RSHIFTFILLEQ","ET_EQ","ET_NE","ET_LT","ET_LE","ET_GT","ET_GE","ET_PLUS","ET_MINUS","ET_MULTIPLY","ET_DIVIDE","ET_MOD","ET_LAND","ET_LOR","ET_AND","ET_OR","ET_XOR","ET_LSHIFT","ET_RSHIFT","ET_RSHIFTFILL","ET_BOOLEAN","ET_VAR","NUMBER_OF_EXPR_TYPE"};#define NUMBER_OF_RANK 15static s32 ET_Rank[NUMBER_OF_EXPR_TYPE] ={ 1,// ET_CURVED_EXPR 2,// ET_NEGATIVE 2,// ET_NOT 2,// ET_ONESCOMP 2,// ET_INCREMENT 2,// ET_DECREMENT 2,// ET_POST_INCREMENT 2,// ET_POST_DECREMENT 14,// ET_CONDTEST 0,// ET_STRING 0,// ET_NUMBER 0,// ET_IDENTIFIER 1,// ET_FUNCTION_CALL 2,// ET_NEW 1,// ET_OBJECT_MEMBER_ACCESS 1,// ET_OBJECT_METHOD_CALL 1,// ET_ARRAY_DEREFERENCE 14,// ET_ASSIGN 14,// ET_PLUSEQ 14,// ET_MINUSEQ 14,// ET_MULTIPLYEQ 14,// ET_DIVIDEEQ 14,// ET_MODEQ 14,// ET_ANDEQ 14,// ET_OREQ 14,// ET_XOREQ 14,// ET_LSHIFTEQ 14,// ET_RSHIFTEQ 14,// ET_RSHIFTFILLEQ 8,// ET_EQ 9,// ET_NE 6,// ET_LT 6,// ET_LE 7,// ET_GT 7,// ET_GE 5,// ET_PLUS 5,// ET_MINUS 3,// ET_MULTIPLY 3,// ET_DIVIDE 3,// ET_MOD 13,// ET_LAND 14,// ET_LOR 10,// ET_AND 12,// ET_OR 11,// ET_XOR 5,// ET_LSHIFT 6,// ET_RSHIFT 6,// ET_RSHIFTFILL 0, // ET_BOOLEAN 14 // ET_VAR/* 0, 0, 0, // variable, number, string 1, 1, 1, 1, 1, // curved expr, call, member, array 2, 2, 2, 2, 2, 2, 2, 2, // unary operator 3, 3, 3, // multiply, divide, mod 4, 4, // add, subtract 5, 5, 5, // bitwise shift 6, 6, 6, 6, // relational 7, 7, // equality 8, // bitwise and 9, // bitwise xor 10, // bitwise or 11, // logical and 12, // logical or 13, // conditional 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14 // assignment */};static s32 ET_leftAssoc[NUMBER_OF_RANK] = {1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0};u32 MoveToToken(ScriptEnc *sc_enc, u32 endTok, u32 cur, u32 end){ u32 cnt = 0; u32 startTok = TOK_EOF, curTok; if (endTok == TOK_RIGHT_CURVE) startTok = TOK_LEFT_CURVE; else if (endTok == TOK_RIGHT_BRACKET) startTok = TOK_LEFT_BRACKET; else if (endTok == TOK_RIGHT_BRACE) startTok = TOK_LEFT_BRACE; else if (endTok == TOK_CONDSEP) startTok = TOK_CONDTEST; else { GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: illegal MoveToToken %s\n", tok_names[endTok])); sc_enc->err = GF_BAD_PARAM; return (u32) -1; } do { curTok = sc_enc->expr_toks[cur++]; if (curTok == startTok) cnt++; else if (curTok == endTok) cnt--; } while ( (curTok != endTok || cnt) && cur < end); if (curTok==endTok && cnt==0) return cur-1; return (u32) -1;}void SFE_FunctionCall(ScriptEnc *sc_enc, u32 start, u32 end);void SFE_Params(ScriptEnc *sc_enc, u32 start, u32 end);void SFE_ConditionTest(ScriptEnc *sc_enc, u32 start, u32 op, u32 end);void SFE_ObjectConstruct(ScriptEnc *sc_enc, u32 start, u32 op, u32 end);void SFE_ArrayDereference(ScriptEnc *sc_enc, u32 start, u32 op, u32 end);void SFE_ObjectMethodCall(ScriptEnc *sc_enc, u32 start, u32 op, u32 end);void SFE_ObjectMemberAccess(ScriptEnc *sc_enc, u32 start, u32 op, u32 end);u32 SFE_Expression(ScriptEnc *sc_enc, u32 start, u32 end, Bool memberAccess){ char *str; u32 n = start; u32 curPos = 0, finalPos = 0; u32 curTok, prevTok; u32 curExpr = 0, expr = 0; u32 curRank, maxRank=0; if (sc_enc->err) return 0; curTok = prevTok = sc_enc->expr_toks[n]; do { curPos = n; switch (curTok) { case TOK_IDENTIFIER: curExpr = ET_IDENTIFIER; break; case TOK_NUMBER: curExpr = ET_NUMBER; break; case TOK_BOOLEAN: curExpr = ET_BOOLEAN; break; case TOK_STRING: curExpr = ET_STRING; break; case TOK_LEFT_CURVE: if (prevTok == TOK_IDENTIFIER) curExpr = ET_FUNCTION_CALL; else curExpr = ET_CURVED_EXPR; n = MoveToToken(sc_enc, TOK_RIGHT_CURVE, n, end); curTok = TOK_RIGHT_CURVE; break; case TOK_LEFT_BRACKET: curExpr = ET_ARRAY_DEREFERENCE; n = MoveToToken(sc_enc, TOK_RIGHT_BRACKET, n, end); curTok = TOK_RIGHT_BRACKET; break; case TOK_PERIOD: curTok = sc_enc->expr_toks[++n]; CHECK_TOK(TOK_IDENTIFIER); if (sc_enc->expr_toks[n+1] == TOK_LEFT_CURVE) { curExpr = ET_OBJECT_METHOD_CALL; n = MoveToToken(sc_enc, TOK_RIGHT_CURVE, n+1, end); curTok = TOK_RIGHT_CURVE; } else { curExpr = ET_OBJECT_MEMBER_ACCESS; } break; case TOK_NEW: curExpr = ET_NEW; curTok = sc_enc->expr_toks[++n]; CHECK_TOK(TOK_IDENTIFIER); curTok = sc_enc->expr_toks[++n]; CHECK_TOK(TOK_LEFT_CURVE); n = MoveToToken(sc_enc, TOK_RIGHT_CURVE, n, end); curTok = TOK_RIGHT_CURVE; break; case TOK_FUNCTION: curExpr = ET_FUNCTION_ASSIGN; break; case TOK_PLUS: if ( prevTok==TOK_RIGHT_CURVE || prevTok==TOK_RIGHT_BRACKET || prevTok==TOK_IDENTIFIER || prevTok==TOK_NUMBER || prevTok==TOK_STRING || prevTok==TOK_INCREMENT || prevTok==TOK_DECREMENT ) { curExpr = ET_PLUS; } else { goto skip_token; } break; case TOK_MINUS: if ( prevTok==TOK_RIGHT_CURVE || prevTok==TOK_RIGHT_BRACKET || prevTok==TOK_IDENTIFIER || prevTok==TOK_NUMBER || prevTok==TOK_STRING || prevTok==TOK_INCREMENT || prevTok==TOK_DECREMENT ) { curExpr = ET_MINUS; } else { curExpr = ET_NEGATIVE; curTok = TOK_NEGATIVE; } break; case TOK_INCREMENT: curExpr = ET_INCREMENT; break; case TOK_DECREMENT: curExpr = ET_DECREMENT; break; case TOK_NOT: curExpr = ET_NOT; break; case TOK_ONESCOMP: curExpr = ET_ONESCOMP; break; case TOK_CONDTEST: curExpr = ET_CONDTEST; break; case TOK_CONDSEP: break; case TOK_LEFT_BRACE: curExpr = ET_CURVED_EXPR; n = MoveToToken(sc_enc, TOK_RIGHT_BRACE, n, end); curTok = TOK_RIGHT_BRACE; break; break; default: if (curTok && (curTok != TOK_VAR) && (curTok < TOK_MULTIPLY || curTok > TOK_OREQ)) { GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: illegal token %s read\n", tok_names[curTok])); sc_enc->err = GF_BAD_PARAM; return 0; } curExpr = TOK_To_ET(curTok); } if (curTok == TOK_CONDSEP) { prevTok = curTok; curTok = sc_enc->expr_toks[++n]; continue; } curRank = ET_Rank[curExpr]; if (curRank > maxRank) { maxRank = curRank; expr = curExpr; finalPos = curPos; } else if (curRank == maxRank && ET_leftAssoc[curRank]) { expr = curExpr; finalPos = curPos; } prevTok = curTok;skip_token: curTok = sc_enc->expr_toks[++n]; } while (n<end); if (expr == ET_INCREMENT) { if (finalPos==start) {} else if (finalPos==end-1) expr = ET_POST_INCREMENT; else { GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: illegal Increment expression\n")); sc_enc->err = GF_BAD_PARAM; return expr; } } else if (expr == ET_DECREMENT) { if (finalPos==start) {} else if (finalPos==end-1) expr = ET_POST_DECREMENT; else { GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: illegal Decrement expression\n")); sc_enc->err = GF_BAD_PARAM; return expr; } } SFE_WRITE_INT(sc_enc, expr, NUMBITS_EXPR_TYPE, "expressionType", (char *) expr_name[expr]); switch (expr) { case ET_MULTIPLY: case ET_DIVIDE: case ET_MOD: case ET_PLUS: case ET_MINUS: case ET_LSHIFT: case ET_RSHIFT: case ET_RSHIFTFILL: case ET_LT: case ET_LE: case ET_GT: case ET_GE: case ET_EQ: case ET_NE: case ET_AND: case ET_XOR: case ET_OR: case ET_LAND: case ET_LOR: SFE_Expression(sc_enc, start, finalPos, 0); SFE_Expression(sc_enc, finalPos+1, end, 0); break; case ET_ASSIGN: case ET_PLUSEQ: case ET_MINUSEQ: case ET_MULTIPLYEQ: case ET_DIVIDEEQ: case ET_MODEQ: case ET_LSHIFTEQ: case ET_RSHIFTEQ: case ET_RSHIFTFILLEQ: case ET_ANDEQ: case ET_XOREQ: case ET_OREQ: { u32 ret = SFE_Expression(sc_enc, start, finalPos, 0); if ( ret != ET_IDENTIFIER && ret != ET_OBJECT_MEMBER_ACCESS && ret != ET_ARRAY_DEREFERENCE ) { GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: LeftVariable expected, %s returned\n", expr_name[ret])); sc_enc->err = GF_BAD_PARAM; return expr; } SFE_Expression(sc_enc, finalPos+1, end, 0); } break; case ET_IDENTIFIER: str = (char *)gf_list_get(sc_enc->id_buf, 0); gf_list_rem(sc_enc->id_buf, 0); /*TODO: when accessing member, we should try to translate proto fields into _fieldALL when not using USENAMEs...*/ if (memberAccess) { } SFE_PutIdentifier(sc_enc, str); free(str); break; case ET_NUMBER: str = (char *)gf_list_get(sc_enc->id_buf, 0); gf_list_rem(sc_enc->id_buf, 0); SFE_PutNumber(sc_enc, str); free(str); break; case ET_BOOLEAN: str = (char *)gf_list_get(sc_enc->id_buf, 0); gf_list_rem(sc_enc->id_buf, 0); SFE_PutBoolean(sc_enc, str); free(str); break; case ET_VAR: while (1) { str = (char *)gf_list_get(sc_enc->id_buf, 0); if (!str) break; gf_list_rem(sc_enc->id_buf, 0); GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 1, 1, "hasArgument", NULL); SFE_PutIdentifier(sc_enc, str); free(str); } GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 0, 1, "hasArgument", NULL); break; case ET_STRING: str = (char *)gf_list_get(sc_enc->id_buf, 0); gf_list_rem(sc_enc->id_buf, 0); if (!sc_enc->emul) gf_bifs_enc_name(sc_enc->codec, sc_enc->bs, str); free(str); break; case ET_NEGATIVE: case ET_INCREMENT: case ET_DECREMENT: case ET_NOT: case ET_ONESCOMP: SFE_Expression(sc_enc, finalPos+1, end, 0); break; case ET_CURVED_EXPR: SFE_CompoundExpression(sc_enc, finalPos+1, end-1, 0); break; case ET_POST_INCREMENT : case ET_POST_DECREMENT : SFE_Expression(sc_enc, start, finalPos, 0); break; case ET_FUNCTION_CALL: SFE_FunctionCall(sc_enc, start, end); break; case ET_OBJECT_MEMBER_ACCESS : SFE_ObjectMemberAccess(sc_enc, start, finalPos, end); break; case ET_OBJECT_METHOD_CALL: SFE_ObjectMethodCall(sc_enc, start, finalPos, end); break; case ET_ARRAY_DEREFERENCE: SFE_ArrayDereference(sc_enc, start, finalPos, end); break; case ET_NEW: SFE_ObjectConstruct(sc_enc, start, finalPos, end); break; case ET_CONDTEST: SFE_ConditionTest(sc_enc, start, finalPos, end); break; case ET_FUNCTION_ASSIGN: SFE_NextToken(sc_enc); SFE_CheckToken(sc_enc, TOK_LEFT_CURVE); SFE_Arguments(sc_enc); SFE_StatementBlock(sc_enc); SFE_NextToken(sc_enc); SFE_CheckToken(sc_enc, TOK_SEMICOLON); break; default: GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: illegal expression type %s\n", expr_name[expr])); sc_enc->err = GF_BAD_PARAM; break; } return expr;}void SFE_FunctionCall(ScriptEnc *sc_enc, u32 start, u32 end){ u32 curTok; char *str; curTok = sc_enc->expr_toks[start++]; CHECK_TOK(TOK_IDENTIFIER); str = (char *)gf_list_get(sc_enc->id_buf, 0); gf_list_rem(sc_enc->id_buf, 0); SFE_PutIdentifier(sc_enc, str); free(str); curTok = sc_enc->expr_toks[start++]; CHECK_TOK(TOK_LEFT_CURVE); SFE_Params(sc_enc, start, end-1); curTok = sc_enc->expr_toks[end-1]; CHECK_TOK(TOK_RIGHT_CURVE);}void SFE_ObjectMemberAccess(ScriptEnc *sc_enc, u32 start, u32 op, u32 end){ u32 curTok; char *str; SFE_Expression(sc_enc, start, op, 1); curTok = sc_enc->expr_toks[op]; CHECK_TOK(TOK_PERIOD); curTok = sc_enc->expr_toks[end-1]; CHECK_TOK(TOK_IDENTIFIER); str = (char *)gf_list_get(sc_enc->id_buf, 0); gf_list_rem(sc_enc->id_buf, 0); SFE_PutIdentifier(sc_enc, str); free(str);}void SFE_ObjectMethodCall(ScriptEnc *sc_enc, u32 start, u32 op, u32 end){ u32 curTok; char *str; SFE_Expression(sc_enc, start, op, 0); curTok = sc_enc->expr_toks[op]; CHECK_TOK(TOK_PERIOD); curTok = sc_enc->expr_toks[op+1]; CHECK_TOK(TOK_IDENTIFIER); str = (char *)gf_list_get(sc_enc->id_buf, 0); gf_list_rem(sc_enc->id_buf, 0); SFE_PutIdentifier(sc_enc, str); free(str); curTok = sc_enc->expr_toks[op+2]; CHECK_TOK(TOK_LEFT_CURVE); SFE_Params(sc_enc, op+3, end-1); curTok = sc_enc->expr_toks[end-1]; CHECK_TOK(TOK_RIGHT_CURVE);}void SFE_ArrayDereference(ScriptEnc *sc_enc, u32 start, u32 op, u32 end){ u32 curTok; SFE_Expression(sc_enc, start, op, 0); curTok = sc_enc->expr_toks[op]; CHECK_TOK(TOK_LEFT_BRACKET); SFE_CompoundExpression(sc_enc, op+1, end-1, 0); curTok = sc_enc->expr_toks[end-1]; CHECK_TOK(TOK_RIGHT_BRACKET);}void SFE_ObjectConstruct(ScriptEnc *sc_enc, u32 start, u32 op, u32 end){ u32 curTok; char *str; curTok = sc_enc->expr_toks[start++]; CHECK_TOK(TOK_NEW); curTok = sc_enc->expr_toks[start++]; CHECK_TOK(TOK_IDENTIFIER); str = (char *)gf_list_get(sc_enc->id_buf, 0); gf_list_rem(sc_enc->id_buf, 0); SFE_PutIdentifier(sc_enc, str); free(str); curTok = sc_enc->expr_toks[start++]; CHECK_TOK(TOK_LEFT_CURVE); SFE_Params(sc_enc, start, end-1); curTok = sc_enc->expr_toks[end-1]; CHECK_TOK(TOK_RIGHT_CURVE);}void SFE_ConditionTest(ScriptEnc *sc_enc, u32 start, u32 op, u32 end){ u32 curTok; SFE_Expression(sc_enc, start, op, 0); curTok = sc_enc->expr_toks[op]; CHECK_TOK(TOK_CONDTEST); start = op+1; op = MoveToToken(sc_enc, TOK_CONDSEP, op, end-1); SFE_Expression(sc_enc, start, op, 0); curTok = sc_enc->expr_toks[op]; CHECK_TOK(TOK_CONDSEP); SFE_Expression(sc_enc, op+1, end, 0);}void SFE_Params(ScriptEnc *sc_enc, u32 start, u32 end){ u32 curTok; curTok = sc_enc->expr_toks[start]; if (curTok != TOK_RIGHT_CURVE) { SFE_WRITE_INT(sc_enc, 1, 1, "hasParam", NULL); SFE_CompoundExpression(sc_enc, start, end, 1); } else { SFE_WRITE_INT(sc_enc, 0, 1, "hasParam", NULL); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -