?? parser.java
字號(hào):
/**
* @(#)Parser.java 1.39 03/01/23
*
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.sun.tools.javac.v8.parser;
import com.sun.tools.javac.v8.tree.*;
import com.sun.tools.javac.v8.code.*;
import com.sun.tools.javac.v8.util.*;
import com.sun.tools.javac.v8.tree.Tree.*;
/**
* The parser maps a token sequence into an abstract syntax
* tree. It operates by recursive descent, with code derived
* systematically from an LL(1) grammar. For efficiency reasons, an
* operator precedence scheme is used for parsing binary operation
* expressions.
*/
public class Parser implements Tokens {
/**
* 操作符的優(yōu)先級(jí),后面的算符優(yōu)先算法會(huì)用到
*/
private static final int infixPrecedenceLevels = 10;
/**
* 詞法分析類
*/
private Scanner S;
/**
* 語法樹構(gòu)造工廠
*/
private TreeMaker F;
/**
* 錯(cuò)誤診斷的log信息
*/
private Log log;
/**
* 關(guān)鍵字表
*/
private Keywords keywords;
/**
* 對(duì)源語言設(shè)置的類
*/
private Source source;
/**
* The name table.
*/
private Name.Table names;
/**
* Construct a parser from a given scanner, tree factory and log.
* @param genEndPos Should endPositions be generated?
*/
public Parser(Context context, Scanner S, boolean keepDocComments,
boolean genEndPos) {
super();
this.S = S;
this.F = TreeMaker.instance(context);
this.log = Log.instance(context);
this.names = Name.Table.instance(context);
this.keywords = Keywords.instance(context);
this.keepDocComments = keepDocComments;
this.source = Source.instance(context);
this.allowAsserts = source.ordinal >= Source.JDK1_4.ordinal;
this.genEndPos = genEndPos;
if (keepDocComments)
docComments = new Hashtable();
if (genEndPos)
endPositions = new Hashtable();
}
/**
* Switch: should we keep docComments?
*/
boolean keepDocComments;
/**
* Switch: should we recognize assert statements, or just give a warning?
*/
boolean allowAsserts;
/**
* Switch: should we store the ending positions?
*/
boolean genEndPos;
/**
* When terms are parsed, the mode determines which is expected:
* mode = EXPR : an expression
* mode = TYPE : a type
* mode = NOPARAMS : no parameters allowed for type
*/
static final int EXPR = 1;
static final int TYPE = 2;
static final int NOPARAMS = 4;
/**
* The current mode.
*/
private int mode = 0;
/**
* The mode of the term that was parsed last.
*/
private int lastmode = 0;
static Tree errorTree = new Tree.Erroneous();
/**
* Skip forward until a suitable stop token is found.
*/
private void skip() {
int nbraces = 0;
int nparens = 0;
while (true) {
switch (S.token) {
case EOF:
case CLASS:
case INTERFACE:
return;
case SEMI:
if (nbraces == 0 && nparens == 0)
return;
break;
case RBRACE:
if (nbraces == 0)
return;
nbraces--;
break;
case RPAREN:
if (nparens > 0)
nparens--;
break;
case LBRACE:
nbraces++;
break;
case LPAREN:
nparens++;
break;
default:
}
S.nextToken();
}
}
/**
* Generate a syntax error at given position using the given argument
* unless one was already reported at the same position, then skip.
*/
private Tree syntaxError(int pos, String key, String arg) {
if (pos != S.errPos)
log.error(pos, key, arg);
skip();
S.errPos = pos;
return errorTree;
}
/**
* Generate a syntax error at given position unless one was already
* reported at the same position, then skip.
*/
private Tree syntaxError(int pos, String key) {
return syntaxError(pos, key, null);
}
/**
* Generate a syntax error at current position unless one was already reported
* at the same position, then skip.
*/
private Tree syntaxError(String key) {
return syntaxError(S.pos, key, null);
}
/**
* Generate a syntax error at current position unless one was already reported
* at the same position, then skip.
*/
private Tree syntaxError(String key, String arg) {
return syntaxError(S.pos, key, arg);
}
/**
* 如果下一個(gè)輸入的字符和前一個(gè)匹配則繼續(xù),否則拋出錯(cuò)誤。
*/
private void accept(int token) {
if (S.token == token) {
S.nextToken();
} else {
int pos = Position.line(S.pos) > Position.line(S.prevEndPos + 1) ?
S.prevEndPos + 1 : S.pos;
syntaxError(pos, "expected", keywords.token2string(token));
if (S.token == token)
S.nextToken();
}
}
/**
* 報(bào)告表達(dá)式或類型起始錯(cuò)誤
*/
Tree illegal(int pos) {
if ((mode & EXPR) != 0)
return syntaxError(pos, "illegal.start.of.expr");
else
return syntaxError(pos, "illegal.start.of.type");
}
/**
* 報(bào)告當(dāng)前位置表達(dá)式或類型起始錯(cuò)誤
*/
Tree illegal() {
return illegal(S.pos);
}
/**
*用來存放文件注釋的hashtable
*/
Hashtable docComments;
/**
* Make an entry into docComments hashtable,
* provided flag keepDocComments is set and given doc comment is non-null.
* @param tree The tree to be used as index in the hashtable
* @param dc The doc comment to associate with the tree, or null.
*/
void attach(Tree tree, String dc) {
if (keepDocComments && dc != null) {
docComments.put(tree, dc);
}
}
/**
* A hashtable to store ending positions
* of source ranges indexed by the tree nodes.
* Defined only if option flag genEndPos is set.
*/
Hashtable endPositions;
/**
* Make an entry into endPositions hashtable, provided flag
* genEndPos is set. Note that this method is usually hand-inlined.
* @param tree The tree to be used as index in the hashtable
* @param endPos The ending position to associate with the tree.
*/
void storeEnd(Tree tree, int endpos) {
if (genEndPos)
endPositions.put(tree, new Integer(endpos));
}
/**
* Ident = IDENTIFIER
*/
Name ident() {
if (S.token == IDENTIFIER) {
Name name = S.name;
S.nextToken();
return name;
}
if (S.token == ASSERT) {//判斷是否識(shí)別assert語法,是報(bào)錯(cuò)還是僅僅警告
if (allowAsserts) {
log.error(S.pos, "assert.as.identifier");
S.nextToken();
return names.error;
} else {
log.warning(S.pos, "assert.as.identifier");
Name name = S.name;
S.nextToken();
return name;
}
} else {
accept(IDENTIFIER);
return names.error;
}
}
/**
* Qualident = Ident { DOT Ident }
*/
Tree qualident() {
Tree t = F.at(S.pos).Ident(ident());
while (S.token == DOT) {
int pos = S.pos;
S.nextToken();
t = F.at(pos).Select(t, ident());
}
return t;
}
/**
* Literal =
* INTLITERAL
* | LONGLITERAL
* | FLOATLITERAL
* | DOUBLELITERAL
* | CHARLITERAL
* | STRINGLITERAL
* | TRUE
* | FALSE
* | NULL
*/
Tree literal(Name prefix) {
int pos = S.pos;
Tree t = errorTree;
switch (S.token) {
case INTLITERAL:
try {
t = F.at(pos).Literal(Type.INT,
new Integer(Convert.string2int(strval(prefix), S.radix)));
} catch (NumberFormatException ex) {
log.error(S.pos, "int.number.too.large", strval(prefix));
}
break;
case LONGLITERAL:
try {
t = F.at(pos).Literal(Type.LONG,
new Long(Convert.string2long(strval(prefix), S.radix)));
} catch (NumberFormatException ex) {
log.error(S.pos, "int.number.too.large", strval(prefix));
}
break;
case FLOATLITERAL:
{
Float n = Float.valueOf(S.stringVal());
if (n.floatValue() == 0.0F && !isZero(S.stringVal()))
log.error(S.pos, "fp.number.too.small");
else if (n.floatValue() == Float.POSITIVE_INFINITY)
log.error(S.pos, "fp.number.too.large");
else
t = F.at(pos).Literal(Type.FLOAT, n);
break;
}
case DOUBLELITERAL:
{
Double n = Double.valueOf(S.stringVal());
if (n.doubleValue() == 0.0 && !isZero(S.stringVal()))
log.error(S.pos, "fp.number.too.small");
else if (n.doubleValue() == Double.POSITIVE_INFINITY)
log.error(S.pos, "fp.number.too.large");
else
t = F.at(pos).Literal(Type.DOUBLE, n);
break;
}
case CHARLITERAL:
t = F.at(pos).Literal(Type.CHAR, new Integer(S.stringVal().charAt(0)));
break;
case STRINGLITERAL:
t = F.at(pos).Literal(Type.CLASS, S.stringVal());
break;
case TRUE:
case FALSE:
case NULL:
t = F.at(pos).Ident(S.name);
break;
default:
assert false;
}
S.nextToken();
return t;
}
boolean isZero(String s) {
char[] cs = s.toCharArray();
int i = 0;
while (i < cs.length && (cs[i] == '0' || cs[i] == '.'))
i++;
return !(i < cs.length && ('1' <= cs[i] && cs[i] <= '9'));
}
String strval(Name prefix) {
String s = S.stringVal();
return (prefix.len == 0) ? s : prefix + s;
}
/**
* terms can be either expressions or types.
*/
Tree expression() {
return term(EXPR);
}
Tree type() {
return term(TYPE);
}
Tree term(int newmode) {
int prevmode = mode;
mode = newmode;
Tree t = term();
lastmode = mode;
mode = prevmode;
return t;
}
/**
* Expression = Expression1 [ExpressionRest]
* ExpressionRest = [AssignmentOperator Expression1]
* AssignmentOperator = "=" | "+=" | "-=" | "*=" | "/=" | "&=" | "|=" | "^=" |
* "%=" | "<<=" | ">>=" | ">>>="
* Type = Type1
* TypeNoParams = TypeNoParams1
* StatementExpression = Expression
* ConstantExpression = Expression
*/
Tree term() {
Tree t = term1();
if ((mode & EXPR) != 0 && S.token == EQ || PLUSEQ <= S.token &&
S.token <= GTGTGTEQ)
return termRest(t);
else
return t;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -