⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compiler.js

📁 一个类似windows
💻 JS
📖 第 1 页 / 共 5 页
字号:
		+ " 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 + -