📄 compiler.js
字号:
+ " missing semicolons");
JSC$message (msg);
}
}
/*
* General help functions.
*/
function JSC$parser_syntax_error ()
{
error (JSC$filename + ":" + JSC$linenum.toString () + ": syntax error");
}
/* All warnings are reported through this function. */
function JSC$warning (line)
{
System.stderr.writeln (line);
}
/* All messages are reported throught this function. */
function JSC$message (line)
{
System.stderr.writeln (line);
}
function JSC$parser_get_token (stream)
{
JSC$num_tokens++;
var token;
if (JSC$parser_peek_token_valid)
{
JSC$parser_peek_token_valid = false;
JSC$parser_token_value = JSC$parser_peek_token_value;
JSC$parser_token_linenum = JSC$parser_peek_token_linenum;
token = JSC$parser_peek_token_token;
}
else
{
token = JSC$lexer (stream);
JSC$parser_token_value = JSC$token_value;
JSC$parser_token_linenum = JSC$token_linenum;
}
if (token == JSC$tIDENTIFIER && JSC$parser_token_value == "arguments")
JSC$num_arguments_identifiers++;
return token;
}
function JSC$parser_peek_token (stream)
{
if (JSC$parser_peek_token_valid)
return JSC$parser_peek_token_token;
else
{
JSC$parser_peek_token_token = JSC$lexer (stream);
JSC$parser_peek_token_value = JSC$token_value;
JSC$parser_peek_token_linenum = JSC$token_linenum;
JSC$parser_peek_token_valid = true;
return JSC$parser_peek_token_token;
}
}
function JSC$parser_get_semicolon_asci (stream)
{
var token = JSC$parser_peek_token (stream);
if (token == #';')
{
/* Everything ok. It was there. */
return JSC$parser_get_token (stream);
}
/* No semicolon. Let's see if we can insert it there. */
if (token == #'}'
|| JSC$parser_token_linenum < JSC$parser_peek_token_linenum
|| token == JSC$tEOF)
{
/* Ok, do the automatic semicolon insertion. */
if (JSC$warn_missing_semicolon)
JSC$warning (JSC$filename + ":" + JSC$parser_token_linenum.toString ()
+ ": warning: missing semicolon");
JSC$num_missing_semicolons++;
return #';';
}
/* Sorry, no can do. */
JSC$parser_syntax_error ();
}
function JSC$parser_expr_is_left_hand_side (expr)
{
return (expr.etype == JSC$EXPR_CALL
|| expr.etype == JSC$EXPR_OBJECT_PROPERTY
|| expr.etype == JSC$EXPR_OBJECT_ARRAY
|| expr.etype == JSC$EXPR_NEW
|| expr.etype == JSC$EXPR_THIS
|| expr.etype == JSC$EXPR_IDENTIFIER
|| expr.etype == JSC$EXPR_FLOAT
|| expr.etype == JSC$EXPR_INTEGER
|| expr.etype == JSC$EXPR_STRING
|| expr.etype == JSC$EXPR_REGEXP
|| expr.etype == JSC$EXPR_ARRAY_INITIALIZER
|| expr.etype == JSC$EXPR_NULL
|| expr.etype == JSC$EXPR_TRUE
|| expr.etype == JSC$EXPR_FALSE);
}
function JSC$parser_parse_source_element (stream)
{
if (JSC$parser_parse_function_declaration (stream))
return true;
var stmt = JSC$parser_parse_stmt (stream);
if (!stmt)
return false;
if (stmt.stype == JSC$STMT_VARIABLE)
/*
* This is a variable declaration at the global level. These
* are actually global variables.
*/
stmt.global_level = true;
JSC$global_stmts.push (stmt);
return true;
}
function JSC$parser_parse_function_declaration (stream)
{
var id, args, block;
if (JSC$parser_peek_token (stream) != JSC$tFUNCTION)
return false;
/* Record how many `arguments' identifiers have been seen so far. */
var num_arguments_identifiers = JSC$num_arguments_identifiers;
JSC$parser_get_token (stream);
if (JSC$parser_get_token (stream) != JSC$tIDENTIFIER)
JSC$parser_syntax_error ();
id = JSC$parser_token_value;
var ln = JSC$parser_token_linenum;
var id_given = id;
if (JSC$nested_function_declarations.length > 0)
{
/* This is a nested function declaration. */
id = ".F:" + (JSC$anonymous_function_count++).toString ();
}
JSC$nested_function_declarations.push (id);
if (JSC$parser_get_token (stream) != #'(')
JSC$parser_syntax_error ();
/* Formal parameter list opt. */
args = new Array ();
while (JSC$parser_peek_token (stream) != #')')
{
if (JSC$parser_get_token (stream) != JSC$tIDENTIFIER)
JSC$parser_syntax_error ();
args.push (JSC$parser_token_value);
var token = JSC$parser_peek_token (stream);
if (token == #',')
{
JSC$parser_get_token (stream);
if (JSC$parser_peek_token (stream) != JSC$tIDENTIFIER)
JSC$parser_syntax_error ();
}
else if (token != #')')
JSC$parser_syntax_error ();
}
if (JSC$parser_get_token (stream) != #')')
JSC$parser_syntax_error ();
JSC$parser_peek_token (stream);
var lbrace_ln = JSC$parser_peek_token_linenum;
block = JSC$parser_parse_block (stream);
if (typeof block == "boolean")
JSC$parser_syntax_error ();
/* Did the function use the `arguments' identifier? */
var use_arguments = false;
if (JSC$num_arguments_identifiers > num_arguments_identifiers)
{
use_arguments = true;
if (JSC$warn_deprecated)
JSC$warning (JSC$filename + ":" + ln.toString ()
+ ": warning: the `arguments' property of Function "
+ "instance is deprecated");
}
JSC$functions.push (new JSC$function_declaration (ln, lbrace_ln, id,
id_given, args,
block, use_arguments));
JSC$nested_function_declarations.pop ();
return true;
}
function JSC$parser_parse_block (stream)
{
var block;
if (JSC$parser_peek_token (stream) != #'{')
return false;
JSC$parser_get_token (stream) != #'{';
var ln = JSC$parser_peek_token_linenum;
/* Do we have a statement list? */
if (JSC$parser_peek_token (stream) != #'}')
/* Yes we have. */
block = JSC$parser_parse_stmt_list (stream);
else
/* Do we don't */
block = new Array ();
if (JSC$parser_get_token (stream) != #'}')
JSC$parser_syntax_error ();
block.linenum = ln;
return block;
}
function JSC$parser_parse_stmt_list (stream)
{
var list, done, item;
list = new Array ();
done = false;
while (!done)
{
item = JSC$parser_parse_stmt (stream);
if (typeof item == "boolean")
{
/* Can't parse more statements. We'r done. */
done = true;
}
else
list.push (item);
}
return list;
}
function JSC$parser_parse_stmt (stream)
{
var item, token;
if (typeof (item = JSC$parser_parse_block (stream)) != "boolean")
return new JSC$stmt_block (item.linenum, item);
else if (JSC$parser_parse_function_declaration (stream))
{
/* XXX The function declaration as statement might be incomplete. */
if (JSC$nested_function_declarations.length == 0)
/* Function declaration at top-level statements. */
return new JSC$stmt_empty (JSC$parser_token_linenum);
/* Function declaration inside another function. */
var container_id = JSC$nested_function_declarations.pop ();
JSC$nested_function_declarations.push (container_id);
var f = JSC$functions[JSC$functions.length - 1];
var function_id = f.name;
var given_id = f.name_given;
return new JSC$stmt_function_declaration (JSC$parser_token_linenum,
container_id, function_id,
given_id);
}
else if (typeof (item = JSC$parser_parse_variable_stmt (stream))
!= "boolean")
return item;
else if (typeof (item = JSC$parser_parse_if_stmt (stream))
!= "boolean")
return item;
else if (typeof (item = JSC$parser_parse_iteration_stmt (stream))
!= "boolean")
return item;
else if (typeof (item = JSC$parser_parse_expr (stream))
!= "boolean")
{
if (item.etype == JSC$EXPR_IDENTIFIER)
{
/* Possible `Labeled Statement'. */
token = JSC$parser_peek_token (stream);
if (token == #':' && item.linenum == JSC$parser_peek_token_linenum)
{
/* Yes it is. */
JSC$parser_get_token (stream);
var stmt = JSC$parser_parse_stmt (stream);
if (!stmt)
JSC$parser_syntax_error;
return new JSC$stmt_labeled_stmt (item.linenum, item.value,
stmt);
}
/* FALLTHROUGH */
}
JSC$parser_get_semicolon_asci (stream);
return new JSC$stmt_expr (item);
}
else
{
token = JSC$parser_peek_token (stream);
if (token == #';')
{
JSC$parser_get_token (stream);
return new JSC$stmt_empty (JSC$parser_token_linenum);
}
else if (token == JSC$tCONTINUE)
{
JSC$parser_get_token (stream);
/* Check the possible label. */
var label = null;
token = JSC$parser_peek_token (stream);
if (token == JSC$tIDENTIFIER
&& JSC$parser_token_linenum == JSC$parser_peek_token_linenum)
{
JSC$parser_get_token (stream);
label = JSC$parser_token_value;
}
item = new JSC$stmt_continue (JSC$parser_token_linenum, label);
JSC$parser_get_semicolon_asci (stream);
return item;
}
else if (token == JSC$tBREAK)
{
JSC$parser_get_token (stream);
/* Check the possible label. */
var label = null;
token = JSC$parser_peek_token (stream);
if (token == JSC$tIDENTIFIER
&& JSC$parser_token_linenum == JSC$parser_peek_token_linenum)
{
JSC$parser_get_token (stream);
label = JSC$parser_token_value;
}
item = new JSC$stmt_break (JSC$parser_token_linenum, label);
JSC$parser_get_semicolon_asci (stream);
return item;
}
else if (token == JSC$tRETURN)
{
JSC$parser_get_token (stream);
var linenum = JSC$parser_token_linenum;
if (JSC$parser_peek_token (stream) == #';')
{
/* Consume the semicolon. */
JSC$parser_get_token (stream);
item = null;
}
else
{
if (JSC$parser_peek_token_linenum > linenum)
{
/*
* A line terminator between tRETURN and the next
* token that is not a semicolon. ASCI here.
*/
if (JSC$warn_missing_semicolon)
JSC$warning (JSC$filename + ":" + linenum.toString ()
+ ": warning: missing semicolon");
JSC$num_missing_semicolons++;
item = null;
}
else
{
item = JSC$parser_parse_expr (stream);
if (typeof item == "boolean")
JSC$parser_syntax_error ();
JSC$parser_get_semicolon_asci (stream);
}
}
return new JSC$stmt_return (linenum, item);
}
else if (token == JSC$tSWITCH)
{
JSC$parser_get_token (stream);
return JSC$parser_parse_switch (stream);
}
else if (token == JSC$tWITH)
{
JSC$parser_get_token (stream);
var linenum = JSC$parser_token_linenum;
if (JSC$parser_get_token (stream) != #'(')
JSC$parser_syntax_error ();
var expr = JSC$parser_parse_expr (stream);
if (typeof expr == "boolean")
JSC$parser_syntax_error ();
if (JSC$parser_get_token (stream) != #')')
JSC$parser_syntax_error ();
var stmt = JSC$parser_parse_stmt (stream);
if (typeof stmt == "boolean")
JSC$parser_syntax_error ();
return new JSC$stmt_with (linenum, expr, stmt);
}
else if (token == JSC$tTRY)
{
JSC$parser_get_token (stream);
return JSC$parser_parse_try (stream);
}
else if (token == JSC$tTHROW)
{
JSC$parser_get_token (stream);
var linenum = JSC$parser_token_linenum;
/*
* Get the next token's linenum. We need it for strict_ecma
* warning.
*/
JSC$parser_peek_token (stream);
var peek_linenum = JSC$parser_peek_token_linenum;
/* The expression to throw. */
var expr = JSC$parser_parse_expr (stream);
if (typeof expr == "boolean")
JSC$parser_syntax_error ();
if (JSC$warn_strict_ecma && peek_linenum > linenum)
JSC$warning (JSC$filename + ":" + JSC$linenum.toString ()
+ ": warning: ECMAScript don't allow line terminators"
+ " between `throw' and expression");
JSC$parser_get_semicolon_asci (stream);
return new JSC$stmt_throw (linenum, expr);
}
else
/* Can't parse more. We'r done. */
return false;
}
}
function JSC$parser_parse_switch (stream)
{
var linenum = JSC$parser_token_linenum;
if (JSC$parser_get_token (stream) != #'(')
JSC$parser_syntax_error ();
var expr = JSC$parser_parse_expr (stream);
if (!expr)
JSC$parser_syntax_error ();
if (JSC$parser_get_token (stream) != #')')
JSC$parser_syntax_error ();
if (JSC$parser_get_token (stream) != #'{')
JSC$parser_syntax_error ();
/* Parse case clauses. */
var clauses = new Array ();
while (true)
{
var token = JSC$parser_get_token (stream);
if (token == #'}')
break;
else if (token == JSC$tCASE || token == JSC$tDEFAULT)
{
var stmts = new Array ();
stmts.expr = null;
if (token == JSC$tCASE)
{
stmts.expr = JSC$parser_parse_expr (stream);
if (!stmts.expr)
JSC$parser_syntax_error ();
}
if (JSC$parser_get_token (stream) != #':')
JSC$parser_syntax_error ();
stmts.linenum = JSC$parser_token_linenum;
/* Read the statement list. */
while (true)
{
token = JSC$parser_peek_token (stream);
if (token == #'}' || token == JSC$tCASE || token == JSC$tDEFAULT)
/* Done with this branch. */
break;
var stmt = JSC$parser_parse_stmt (stream);
if (!stmt)
JSC$parser_syntax_error ();
stmts.push (stmt);
}
stmts.last_linenum = JSC$parser_token_linenum;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -