V8 对 js 的脚本的处理流程大体分为 :

  • parser 生成抽象语法树,这里将每一句 js 语句(statement) 生成为一个节点
  • 本地代码引擎将抽象语法树生成对应的二进制代码,依次 取出每个节点,不同类型的节点有着不同代码生成方法
  • 执行,遇到新的函数调用再次启动这个过程(这时 是 lazy_parser)
    本文所研究的正是这个流程第一步。

V8 parser 处理脚本的层次

  1. 进入 FunctionLiteral* MakeAST(...),这里分辨出要处理时 json 还是普通的 js 脚本,普通 的 js 脚本通过调用 parser.ParseProgram(...)处理

  2. 进入 FunctionLiteral* Parser::ParseProgram(...),这是个 wrapper,主要工作是

    • 构建该脚本运行时所需要的 scope,以及编译时需要的 Scanner
    • 对该脚本语法抽象树的生成工作主要由void* Parser::ParseSourceElements(...)完成,生成的结果放在准备的容器ZoneListWrapper<Statement> body()中。
  • 根据生成结果生成FunctionLiteral类型的返回结果
  1. 进入void* Parser::ParseSourceElements( ...) ,这里的逻辑很简单,就是用Statement* Parser::ParseStatement(...)将每行js语句分析出来,每条js语句被解析成 Statement。

代码分析如下:

    class AstBuildingParser : public Parser { 
        Handle<Script> script_;
        Scanner scanner_ Scope* top_scope_; 
        INLINE(Token::Valuepeek()) { return scanner_.peek(); } 
        INLINE(Token::ValueNext()) { return scanner_.Next(); } 
        void Expect(Token::Valuetoken, bool* ok); 
        AstBuildingParserFactory factory_; 
    } 
    void Parser::Expect(Token::Valuetoken, bool* ok) {
        Token::Valuenext = Next();
        if (next == token) return; 
        ReportUnexpectedToken(next); 
        *ok = false; 
    } 
    // Class Parser 的 Expect 函数实际上将 scanner 的指针往后移动。 
    FunctionLiteral* Parser::ParseProgram(Handle<String> source, bool in_global_context) 
    {
        CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); 
        HistogramTimerScope timer(&Counters::parse); 
        Counters::total_parse_size.Increment(source->length()); 
        
        // Initialize parser state. 
        source->TryFlatten(); 
        // Scanner scanner_初始化 
        scanner_.Initialize(source, JAVASCRIPT); 
        // Compute the parsing mode.
        
        mode_ = FLAG_lazy ? PARSE_LAZILY: PARSE_EAGERLY; 
        if (allow_natives_syntax_ || extension_ != NULL) 
            mode_ = PARSE_EAGERLY; 
        Scope::Type type = in_global_context ? Scope::GLOBAL_SCOPE : Scope::EVAL_SCOPE;
        Handle<String> no_name = factory()->EmptySymbol(); 
        FunctionLiteral* result = NULL; 
        
        //生成一个新的 class Scope 其 parent 为 NULL
        Scope* scope = factory()->NewScope(top_scope_, type, inside_with());
        // LexicalScope 的构造函数里将 class parser 的 top_scope_指针指向刚生成 scope 
        LexicalScope lexical_scope(this, scope);
        TemporaryScope temp_scope(this); 
        ZoneListWrapper<Statement> body(16); bool ok = true; 
        //对于最上层 top scope,其结束标志是 Token::EOS 
        ParseSourceElements(&body, Token::EOS, &ok); 
        
        if (ok) {
            result = NEW(FunctionLiteral(no_name,top_scope_,body.elements(),temp_scope.materialized_literal_count(), temp_scope.expected_property_count(), temp_scope.only_simple_this_property_assignments(), temp_scope.this_property_assignments(), 
0,0, source->length(), false)); 
        } else if (scanner().stack_overflow()) { 
            Top::StackOverflow(); 
        } 
        
        if (result == NULL) 
            zone_scope.DeleteOnExit(); 
        return result;
   } 
   
   
//对于一个 js 函数的分析
FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name, 
int function_token_position, FunctionLiteralType type, bool* ok) { 
seen_loop_stmt_ = false; 
bool is_named = !var_name.is_null();
Handle<String> name = is_named ? var_name : factory()->EmptySymbol(); // The function name, if any.
Handle<String> function_name = factory()->EmptySymbol();
if (is_named && (type == EXPRESSION || type == NESTED)) { 
function_name = name; } 
int num_parameters = 0;
// Parse function body.
{ Scope::Type type = Scope::FUNCTION_SCOPE; 
//进入一个函数体中,为这个函数体新生成一个 class Scope 的实例,其父 scope 为 top_scope_。 Scope* scope = factory()->NewScope(top_scope_, type, inside_with()); 
//对于本层次 class LexicalScope 在其构造函数里的将其 prev_scope_指针记录着上一层 的 top_scope_,而 class parser 的 top_scope_被指向新生成的 scope,而在 class LexicalScope 析 构函数里将恢复 class parser 的 top_scope_为构造函数里记录的 prev_scope_。 
LexicalScope lexical_scope(this, scope); TemporaryScope temp_scope(this); top_scope_->SetScopeName(name); 
// FormalParameterList :: 
// '(' (Identifier)*[','] ')' //出现“(”:函数声明的开始 
Expect(Token::LPAREN,CHECK_OK); int start_pos = scanner_.location().beg_pos; bool done = (peek() == Token::RPAREN); 
//如果紧接着出现 “)”:那么这个函数没有参数,否则分析其参数 while (!done) {//分析该函数参数 
Handle<String> param_name = ParseIdentifier(CHECK_OK); 
if (!is_pre_parsing_) { //把参数加入到该 scope 中 
top_scope_->AddParameter(top_scope_->DeclareLocal(param_name, 
num_parameters++; } 
done = (peek() == Token::RPAREN); 
if (!done) Expect(Token::COMMA, CHECK_OK); } 
//终于出现“)”,该函数参数列表分析完毕 Expect(Token::RPAREN,CHECK_OK); 
//出现“{”,一个函数体的开始 Expect(Token::LBRACE, CHECK_OK); 
//Class ZoneListWrapper 实际上是容纳其模板类型实例的一个列表,这里其容纳的 是 Statement 列表 
ZoneListWrapper<Statement> body = factory()->NewList<Statement>(8); 
...
if (!function_name.is_null() && function_name->length() > 0) { 
//生成一个变量,其名字为该函数名
Variable*fvar = top_scope_->DeclareFunctionVar(function_name); 
//生成一个变量代理 VariableProxy*fproxy = 
top_scope_->NewUnresolved(function_name, inside_with()); //将变量及变量代理绑定起来 
fproxy->BindTo(fvar);
// 首先生成一个Assignment表达式的实例,其target_为fproxy,其value_为classThisFunction 的实例,class ThisFunction 本身就是一个表达式: class ThisFunction: public Expression。 
body.Add(new ExpressionStatement(
new Assignment(Token::INIT_CONST, fproxy, 
NEW(ThisFunction()), RelocInfo::kNoPosition))); 
} 
...
if (is_lazily_compiled && pre_data() != NULL) { 
...
} else { 
//这里逐语句分析
ParseSourceElements(&body, Token::RBRACE,CHECK_OK); materialized_literal_count = temp_scope.materialized_literal_count(); expected_property_count = temp_scope.expected_property_count(); only_simple_this_property_assignments = 
temp_scope.only_simple_this_property_assignments(); this_property_assignments = temp_scope.this_property_assignments(); 
V ariable::V AR)); 
} 
Expect(Token::RBRACE, CHECK_OK);
int end_pos = scanner_.location().end_pos;
...
FunctionEntry entry = log()->LogFunction(start_pos); ... 
//parser 的结果放在这里 FunctionLiteral* function_literal = 
NEW(FunctionLiteral( ...); if (!is_pre_parsing_) { 
function_literal->set_function_token_position(function_token_position); } 
seen_loop_stmt_ = true; 
return function_literal; } 
} `







1.2 Scope 
对于一段 js 脚本,每个层次都对应一个 class Scope,该层次上的变量、作用域范围与此 Scope 紧密相关。如脚本文件,以及该文件里的函数是两个层次的 Scope 
脚本文件的 Scope 生成如下:

`FunctionLiteral* Parser::ParseProgram(Handle<String> source, 
bool in_global_context) { 
//根据参数 bool in_global_context 判定该 Scope 是何种类型,对于脚本文件级, in_global_context 为 1,该 Scope 的类型为 GLOBAL_SCOPE 
Scope::Type type = in_global_context 
? Scope::GLOBAL_SCOPE 
: Scope::EVAL_SCOPE; ... 
//为该级别的 js 代码创建 Scope,对于 js 文件级,top_scope_为 NULL。 Scope* scope = factory()->NewScope(top_scope_, type, inside_with()); 
LexicalScope lexical_scope(this, scope); TemporaryScope temp_scope(this); 
}
//具体 Scope 创建根据 Parser 类型不同而异,对于 class AstBuildingParser,其创建函数如下: Scope* AstBuildingParserFactory::NewScope(Scope* parent, Scope::Type type, 
Scope* result = new Scope(parent, type); result->Initialize(inside_with);
return result; 
} 
2 语法分析的入口 Parser::ParseStatement(...) 
在该函数里进行实质的语法分析。这是一个分拣器:分析出每个 不同的类型再进一步调用相关的分析函数。具体流程操作过程是,首先分离出有关键字 的 
statement。这些 statement 由关键字指明,有很清楚的含义如
门的 statement 分析器再进行更清楚的分析。比如
ParseV ariableStatement(bool* ok); “ if ” 给交句语
ParseIfStatement(ZoneStringList* labels, bool* ok);而对于普通语句如 “forest=1876+forest3;”、 函数调用等语句、交给 Statement* ParseExpressionOrLabelledStatement(ZoneStringList* labels,bool* ok);函数做进一步分析。 
源码解析如下: 
Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { 
		//  Statement :: 

		//  Block 

		//  V ariableStatement 

		//  EmptyStatement 

		//  ExpressionStatement 

		//  IfStatement 

		//  IterationStatement 

		//  ContinueStatement 

		//  BreakStatement 

		//  ReturnStatement 

		//  WithStatement 

		//  LabelledStatement 

		//  SwitchStatement 

		//  ThrowStatement 

bool inside_with) { 
js 语句的类型,然后针对 
“var forest;”,接下来交给专 “ var ” 语句交给 Block* IfStatement* 
		//  TryStatement 

		//  DebuggerStatement 

		//  Note: Since labels can only be used by 'break' and 'continue' 

		//  statements, which themselves are only valid within blocks, 

		//  iterations or 'switch' statements (i.e., BreakableStatements), 

		//  labels can be simply ignored in all other cases; except for 

		//  trivial labeled break statements 'label: break label' which is 

		//  parsed into an empty statement. 

		//  Keep the source position of the statement
int statement_pos = scanner().peek_location().beg_pos; Statement* stmt = NULL; 
switch (peek()) { 
case Token::LBRACE:
return ParseBlock(labels, ok); 
case Token::CONST: // fall through 
case Token::VAR: //“VAR”变量声明语句 
stmt = ParseVariableStatement(ok); break; 
case Token::SEMICOLON: Next(); 
return factory()->EmptyStatement(); 
case Token::IF: //“IF”语句 
stmt = ParseIfStatement(labels, ok); break; 
case Token::DO:
stmt = ParseDoWhileStatement(labels, ok); break; 
case Token::WHILE:
stmt = ParseWhileStatement(labels, ok); break; 
case Token::FOR: 

stmt = ParseForStatement(labels, ok); break; 
case Token::CONTINUE:
stmt = ParseContinueStatement(ok); break; 
case Token::BREAK:
stmt = ParseBreakStatement(labels, ok); break; 
case Token::RETURN:
stmt = ParseReturnStatement(ok); break; 
case Token::WITH:
stmt = ParseWithStatement(labels, ok); break; 
case Token::SWITCH:
stmt = ParseSwitchStatement(labels, ok); break; 
case Token::THROW:
stmt = ParseThrowStatement(ok); break; 
case Token::TRY:{ //try 语句 
// NOTE: It is somewhat complicated to have labels on
// try-statements. When breaking out of a try-finally statement, // one must take great care not to treat it as a
// fall-through. It is much easier just to wrap the entire
// try-statement in a statement block and put the labels there Block* result = NEW(Block(labels, 1, false)); Targettarget(this, result);
TryStatement* statement = ParseTryStatement(CHECK_OK); if (statement) { 
statement->set_statement_pos(statement_pos); } 
if (result) result->AddStatement(statement); 
return result; } 
case Token::FUNCTION: //遇到一个函数 
return ParseFunctionDeclaration(ok); 
case Token::NATIVE:
return ParseNativeDeclaration(ok); 
case Token::DEBUGGER:
stmt = ParseDebuggerStatement(ok); break; 
default: //普通语句走到这里 
stmt = ParseExpressionOrLabelledStatement(labels, ok); } 
// Store the source position of the statement
if (stmt != NULL) stmt->set_statement_pos(statement_pos); return stmt; 
} `
3 普通语句的分析 
3.1 变量声明
当遇到一个 var Token,parser 使用 Block* Parser::ParseVariableDeclarations(bool accept_IN, Expression** var, bool* ok) {...}来分析这个语句。 
Block* Parser::ParseVariableDeclarations(bool accept_IN, Expression** var, 
bool* ok) { 
Variable::Modemode = Variable::VAR; bool is_const = false;
if (peek() == Token::V AR){ 
Consume(Token::VAR); //将 parser 的扫描器指针向前推进到 Var后面的位置 } else if (peek() == Token::CONST) {//CONST 语句与 V AR处理相同 
Consume(Token::CONST); //将 parser 的扫描器指针向前推进到 CONST 后面的位置 mode = Variable::CONST;
is_const = true; 
} else {
UNREACHABLE(); // by current callers 
} 
//生成一个 class Block: public BreakableStatement 节点 Block* block = NEW(Block(NULL, 1, true)); 
VariableProxy*last_var = NULL; // the last variable declared int nvars = 0; // the number of variables declared
do { 
// Parse variable name. 
if (nvars > 0) Consume(Token::COMMA);// 对于多个变量的声明语句,将 器指针向前推进到变量声明的逗号后面 
parser 的扫描 Handle<String> name = ParseIdentifier(CHECK_OK); //提取出当前变量的标识符 
//在当前 scope 里声明该变量,这是最重要的一步 last_var = Declare(name, mode, NULL, 
is_const /* always bound for CONST! */, CHECK_OK); 
nvars++; 
Expression* value = NULL; int position = -1; 
//对于有初始值的声明,按赋值表达式处理 if (peek() == Token::ASSIGN) { 
Expect(Token::ASSIGN, CHECK_OK);
position = scanner().location().beg_pos;
value = ParseAssignmentExpression(accept_IN, CHECK_OK); 
} 
...
} while (peek() == Token::COMMA); 
...
return block; 
} 
3.2 分析 AssignmentExpression 表达式 
//对一个 AssignmentExpression 表达式的分析,“以 forest=99 为例”。 Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) { 
//对于“=”左边,执行 Parser::ParseConditionalExpression,该函数返会 “=”左侧的表达 式,对于 forest=99;分析“=”左边的表达式。 
Expression* expression = ParseConditionalExpression(accept_IN, CHECK_OK); 
if (!Token::IsAssignmentOp(peek())) {//如果接下来 token 不是“=”,直接返回该表达式 // Parsed conditional expression only (no assignment).
return expression; 
} ... 
Token::Valueop = Next(); // Get assignment operator. //取出下一个操作符,对于 “forest=99;”,op 为“=” 
int pos = scanner().location().beg_pos;
Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);//分析“=”右边的 
表达式 
...
return NEW(Assignment(op, expression, right, pos)); //左右两侧的语法结构都已分析完毕 , 
根据生成的左右表达式和操作符 “op”,生成语句“iforest=99”的 statement } 
3.3 LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression 表达式 
//该函数分析诸如 LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression 的语 句
Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) {
... 
//分析 LogicalOrExpression 部分,即“?”左侧
Expression* expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); 
//如果该语句只有 LogicalOrExpression 部分,则 peek 不到“?”,返回 if (peek() != Token::CONDITIONAL) return expression; 
//scanner 的指针移过“?” Consume(Token::CONDITIONAL);
// In parsing the first assignment expression in conditional
// expressions we always accept the 'in' keyword; see ECMA-262, // section 11.12, page 58. 
//分析前一个 AssignmentExpression 部分即“?”和“:”之间的表达式 Expression* left = ParseAssignmentExpression(true, CHECK_OK); 
//检查是否下面出现了 “:”。 Expect(Token::COLON, CHECK_OK); 
//分析后一个 AssignmentExpression 部分即“:”后面的表达式 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); return NEW(Conditional(expression, left, right)); 
} 
3.4 用 ParseBinaryExpression(...)分析“?”左侧的表达式
二元函数分离器 Expression* Parser::ParseBinaryExpression(...);,看起来云里雾里,不得其解。 其实这是因为其原函数里很多代码是用来优化 statement 的。我们将优化部分去掉,先分析 将其主干: 
这个函数使用了一个重要工具: Expression* ParseUnaryExpression(...);,该函数暂且可以理 解为在一串操作序列中取出第一个操作数,以 “ a+b+c ” 为例, Expression* ParseUnaryExpression( ...);返回对应“a”的表达式。 
再者操作符都有自己的优先级, int Precedence(Token::Valuetok, bool accept_IN);这个函数就 是取出对应操作符的优先级。(操作符优先级的定义参见 token.h)。 
该函数最大的特点是递归分析,其每次递归下探的深度,取决由操作符的优先级。每 次 Parser::ParseBinaryExpression(...)使用 Expression* ParseUnaryExpression(...),取出第一个操 作数后,它会检查在取出的操作数后的操作符的优先级是否大于 (高于)该操作数之前的操 作符的优先级。如果不是,就嘎然而止,递归探底 !。这种轻况下函数 Expression* Parser::ParseBinaryExpression(...)实际上就等效于 Expression* ParseUnaryExpression(...)。 
Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { ASSERT(prec >= 4); 
//取出第一个操作数
Expression* x = ParseUnaryExpression(CHECK_OK); 
//如果接下来操作符的优先级(Precedence(peek(), accept_IN))低于第一个操作数前面操作符 的优先级(int prec),就向上返回了。 
for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { //跑到这里说明遇到了更高的优先级的操作符 
// prec1 >= 4 
while (Precedence(peek(), accept_IN) == prec1) { //取出这个操作符 
Token::Valueop = Next();
//去取下一个操作数 ,参数 prec1 + 1,说明同一等级的操作符不会通过递归进行 。而是用这 个 while 循环逐个分解。 
Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); //生成新的表达 
x = NEW(BinaryOperation(op, x, y)); } 
} 
return x; } 
再看完整的代码: 
// Precedence >= 4
Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { 
ASSERT(prec >= 4);
Expression* x = ParseUnaryExpression(CHECK_OK);
for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { 
// prec1 >= 4
while (Precedence(peek(), accept_IN) == prec1) { 
Token::Valueop = Next();
Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); 
// Compute some expressions involving only number literals.
//如果 x 和 y 都是数字那直接算出结果 ,合并表达式。不然后面的二进制生成器要对每个表 达式都生成一遍代码 
if (x && x->AsLiteral() && x->AsLiteral()->handle()->IsNumber() && y && y->AsLiteral() && y->AsLiteral()->handle()->IsNumber()) { 
double x_val = x->AsLiteral()->handle()->Number(); double y_val = y->AsLiteral()->handle()->Number(); 
switch (op) {
case Token::ADD: 
x = NewNumberLiteral(x_val + y_val); 
continue;
case Token::SUB: 
x = NewNumberLiteral(x_val - y_val); 
continue;
case Token::MUL: 
x = NewNumberLiteral(x_val * y_val); 
continue;
case Token::DIV: 
x = NewNumberLiteral(x_val / y_val); 
continue;
case Token::BIT_OR: 
x = NewNumberLiteral(DoubleToInt32(x_val) | DoubleToInt32(y_val)); 
continue;
case Token::BIT_AND: 
x = NewNumberLiteral(DoubleToInt32(x_val) & DoubleToInt32(y_val)); 
continue;
case Token::BIT_XOR: 
x = NewNumberLiteral(DoubleToInt32(x_val) ^ DoubleToInt32(y_val)); 
continue;
case Token::SHL: { 
int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f); x = NewNumberLiteral(value);
continue; 
}
case Token::SHR: { 
uint32_t shift = DoubleToInt32(y_val) & 0x1f; uint32_t value = DoubleToUint32(x_val) >> shift; x = NewNumberLiteral(value);
continue; 
}
case Token::SAR: { 
uint32_t shift = DoubleToInt32(y_val) & 0x1f;
int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift); x = NewNumberLiteral(value);
continue; 
} default: 
break; } 
}
//如果 y 是数字且是触法操作,那么仍旧直接算出结果,合并表达式。 
// Convert constant divisions to multiplications for speed. if (op == Token::DIV && 
y && y->AsLiteral() && y->AsLiteral()->handle()->IsNumber()) { double y_val = y->AsLiteral()->handle()->Number();
int64_t y_int = static_cast<int64_t>(y_val);
// There are rounding issues with this optimization, but they don't 
// apply if the number to be divided with has a reciprocal that can be 
		//  precisely represented as a floating point number. This is the case 

		//  if the number is an integer power of 2. Negative integer powers of 

		//  2 work too, but for -2, -1, 1 and 2 we don't do the strength 

		//  reduction because the inlined optimistic idiv has a reasonable 

		//  chance of succeeding by producing a Smi answer with no remainder. 

if (static_cast<double>(y_int) == y_val && 
(IsPowerOf2(y_int) || IsPowerOf2(-y_int)) && 
(y_int > 2 || y_int < -2)) {
y = NewNumberLiteral(1 / y_val); op = Token::MUL; 
} } 
		//  For now we distinguish between comparisons and other binary 

		//  operations. (Wecould combine the two and get rid of this 

		//  code an AST node eventually.) 

if (Token::IsCompareOp(op)) { 
// Wehave a comparison. Token::Valuecmp = op; switch (op) { 
case Token::NE: cmp = Token::EQ; break;
case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; default: break; 
}
x = NEW(CompareOperation(cmp, x, y)); if (cmp != op) { 
// The comparison was negated - add a NOT. 
x = NEW(UnaryOperation(Token::NOT, x)); } 
} else {
// Wehave a "normal" binary operation. x = NEW(BinaryOperation(op, x, y)); 
} } 
} 
return x; } 
3.5 分析一元表达式 该函数的工作是:要么分离出一元表达式,要么分离出普通表达式 
Expression* Parser::ParseUnaryExpression(bool* ok) { 
		//  UnaryExpression :: 

		//  PostfixExpression 

		//  'delete' UnaryExpression 

		//  'void' UnaryExpression 

		//  'typeof' UnaryExpression 

		//  '++' UnaryExpression 

		//  '--' UnaryExpression 

		//  '+' UnaryExpression 

		//  '-' UnaryExpression 

		//  '~' UnaryExpression 

		//  '!' UnaryExpression 
Token::Valueop = peek(); 
if (Token::IsUnaryOp(op)) { 
op = Next();
Expression* expression = ParseUnaryExpression(CHECK_OK); 
// Compute some expressions involving only number literals. if (expression != NULL && expression->AsLiteral() && 
expression->AsLiteral()->handle()->IsNumber()) {
double value = expression->AsLiteral()->handle()->Number(); switch (op) { 
case Token::ADD: return expression; 
case Token::SUB:
return NewNumberLiteral(-value); 
case Token::BIT_NOT:
return NewNumberLiteral(~DoubleToInt32(value)); 
default: break; } 
} 
return NEW(UnaryOperation(op, expression)); } else if (Token::IsCountOp(op)) { 
op = Next();
Expression* expression = ParseUnaryExpression(CHECK_OK); 

		//  Signal a reference error if the expression is an invalid 

		//  left-hand side expression. Wecould report this as a syntax 

		//  error here but for compatibility with JSC we choose to report the 

		//  error at runtime. 

if (expression == NULL || !expression->IsValidLeftHandSide()) { 
Handle<String> type = Factory::invalid_lhs_in_prefix_op_symbol(); 
expression = NewThrowReferenceError(type); } 
return NEW(CountOperation(true /* prefix */, op, expression)); } else { 
//不是一元表达式
return ParsePostfixExpression(ok); 
} } 
3.6 最基础的表达式分析
Expression* Parser::ParsePrimaryExpression(bool* ok) { 
// // // // // // // // // // // // 
PrimaryExpression :: 'this' 
'null'
'true'
'false'
Identifier Number
String ArrayLiteral ObjectLiteral RegExpLiteral '(' Expression ')' 
Expression* result = NULL; switch (peek()) { 
case Token::THIS: { Consume(Token::THIS); if (is_pre_parsing_) { 
result = VariableProxySentinel::this_proxy(); } else { 
VariableProxy*recv = top_scope_->receiver(); 
result = recv; } 
break; } 
case Token::NULL_LITERAL: Consume(Token::NULL_LITERAL);
result = NEW(Literal(Factory::null_value())); break; 
case Token::TRUE_LITERAL: Consume(Token::TRUE_LITERAL);
result = NEW(Literal(Factory::true_value())); break; 
case Token::FALSE_LITERAL: Consume(Token::FALSE_LITERAL);
result = NEW(Literal(Factory::false_value())); break; 
case Token::IDENTIFIER: { 
//最基本的表示符都会跑到这里 ,对于“forest=99;”,等号左侧的“forest”分析最终会 走到这里 
//取出标识符将其放入 name 变量
Handle<String> name = ParseIdentifier(CHECK_OK); 
if (is_pre_parsing_) {
result = VariableProxySentinel::identifier_proxy(); 
} else {
//创建一个 class VariableProxy类型的对象,并将其放入在当前的 scope 里的 unresolved_列表 中。 
result = top_scope_->NewUnresolved(name, inside_with()); } 
break; } 
case Token::NUMBER: {
//扫描器碰到了一个数字,对于 “forest=99;”,分析等号右侧的“99”,最终会走到这里 
Consume(Token::NUMBER);
//在 V8 内部是用一个双精度数来表示数字 
double value =
StringToDouble(scanner_.literal_string(), ALLOW_HEX | ALLOW_OCTALS); 
result = NewNumberLiteral(value); 
break; } 
case Token::STRING: { 
Consume(Token::STRING); Handle<String> symbol = 
factory()->LookupSymbol(scanner_.literal_string(), scanner_.literal_length()); 
result = NEW(Literal(symbol)); 
break; } 
case Token::ASSIGN_DIV:
result = ParseRegExpLiteral(true, CHECK_OK); break; 
case Token::DIV:
result = ParseRegExpLiteral(false, CHECK_OK); break; 
case Token::LBRACK:
result = ParseArrayLiteral(CHECK_OK); break; 
case Token::LBRACE:
result = ParseObjectLiteral(CHECK_OK); break; 
case Token::LPAREN: Consume(Token::LPAREN);
result = ParseExpression(true, CHECK_OK); Expect(Token::RPAREN,CHECK_OK); break; 
case Token::MOD:
if (allow_natives_syntax_ || extension_ != NULL) { 
result = ParseV8Intrinsic(CHECK_OK); 
break; } 
// If we're not allowing special syntax we fall-through to the // default case. 
default: {
Token::Valuetok = peek();
// Token::Peek returns the value of the next token but // location() gives info about the current token.
// Therefore, we need to read ahead to the next token Next();
ReportUnexpectedToken(tok);
*ok = false;
return NULL; 
} } 
return result; }