src.org.python.antlr.GrammarActions Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jython-standalone Show documentation
Show all versions of jython-standalone Show documentation
Jython is an implementation of the high-level, dynamic, object-oriented
language Python written in 100% Pure Java, and seamlessly integrated with
the Java platform. It thus allows you to run Python on any Java platform.
package org.python.antlr;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.antlr.runtime.Token;
import org.python.antlr.ast.Attribute;
import org.python.antlr.ast.BinOp;
import org.python.antlr.ast.BoolOp;
import org.python.antlr.ast.Call;
import org.python.antlr.ast.Context;
import org.python.antlr.ast.DictComp;
import org.python.antlr.ast.ExtSlice;
import org.python.antlr.ast.For;
import org.python.antlr.ast.FunctionDef;
import org.python.antlr.ast.GeneratorExp;
import org.python.antlr.ast.IfExp;
import org.python.antlr.ast.Index;
import org.python.antlr.ast.Lambda;
import org.python.antlr.ast.ListComp;
import org.python.antlr.ast.Name;
import org.python.antlr.ast.Num;
import org.python.antlr.ast.Repr;
import org.python.antlr.ast.SetComp;
import org.python.antlr.ast.Slice;
import org.python.antlr.ast.Str;
import org.python.antlr.ast.TryExcept;
import org.python.antlr.ast.TryFinally;
import org.python.antlr.ast.Tuple;
import org.python.antlr.ast.UnaryOp;
import org.python.antlr.ast.While;
import org.python.antlr.ast.With;
import org.python.antlr.ast.Yield;
import org.python.antlr.ast.alias;
import org.python.antlr.ast.arguments;
import org.python.antlr.ast.boolopType;
import org.python.antlr.ast.cmpopType;
import org.python.antlr.ast.expr_contextType;
import org.python.antlr.ast.keyword;
import org.python.antlr.ast.operatorType;
import org.python.antlr.ast.unaryopType;
import org.python.antlr.base.excepthandler;
import org.python.antlr.base.expr;
import org.python.antlr.base.slice;
import org.python.antlr.base.stmt;
import org.python.core.Py;
import org.python.core.PyComplex;
import org.python.core.PyFloat;
import org.python.core.PyInteger;
import org.python.core.PyLong;
import org.python.core.PyString;
import org.python.core.PyUnicode;
import org.python.core.codecs;
import org.python.core.util.StringUtil;
public class GrammarActions {
private ErrorHandler errorHandler = null;
public GrammarActions() {
}
public void setErrorHandler(ErrorHandler eh) {
this.errorHandler = eh;
}
String makeFromText(List dots, List names) {
StringBuilder d = new StringBuilder();
d.append(PythonTree.dottedNameListToString(names));
return d.toString();
}
List makeModuleNameNode(List dots, List names) {
List result = new ArrayList();
if (dots != null) {
for (Object o : dots) {
Token tok = (Token)o;
result.add(new Name(tok, tok.getText(), expr_contextType.Load));
}
}
if (null != names) {
result.addAll(names);
}
return result;
}
List makeDottedName(Token top, List attrs) {
List result = new ArrayList();
result.add(new Name(top, top.getText(), expr_contextType.Load));
if (attrs != null) {
for (PythonTree attr : attrs) {
Token token = attr.getToken();
result.add(new Name(token, token.getText(), expr_contextType.Load));
}
}
return result;
}
int makeLevel(List lev) {
if (lev == null) {
return 0;
}
return lev.size();
}
List makeStarAlias(Token t) {
List result = new ArrayList();
result.add(new alias(t, "*", null));
return result;
}
List makeAliases(List atypes) {
if (atypes == null) {
return new ArrayList();
}
return atypes;
}
List makeBases(expr etype) {
List result = new ArrayList();
if (etype != null) {
if (etype instanceof Tuple) {
return ((Tuple)etype).getInternalElts();
}
result.add(etype);
}
return result;
}
List makeNames(List names) {
List s = new ArrayList();
for(Token name : names) {
s.add(name.getText());
}
return s;
}
Name makeNameNode(Token t) {
if (t == null) {
return null;
}
return new Name(t, t.getText(), expr_contextType.Load);
}
List makeNameNodes(List names) {
List s = new ArrayList();
for(Token name : names) {
s.add(makeNameNode(name));
}
return s;
}
void errorGenExpNotSoleArg(PythonTree t) {
errorHandler.error("Generator expression must be parenthesized if not sole argument", t);
}
expr castExpr(Object o) {
if (o instanceof expr) {
return (expr)o;
}
if (o instanceof PythonTree) {
return errorHandler.errorExpr((PythonTree)o);
}
return null;
}
List castExprs(List exprs) {
return castExprs(exprs, 0);
}
List castExprs(List exprs, int start) {
List result = new ArrayList();
if (exprs != null) {
for (int i=start; i makeElse(List elseSuite, PythonTree elif) {
if (elseSuite != null) {
return castStmts(elseSuite);
} else if (elif == null) {
return new ArrayList();
}
List s = new ArrayList();
s.add(castStmt(elif));
return s;
}
stmt castStmt(Object o) {
if (o instanceof stmt) {
return (stmt)o;
} else if (o instanceof PythonParser.stmt_return) {
return (stmt)((PythonParser.stmt_return)o).tree;
} else if (o instanceof PythonTree) {
return errorHandler.errorStmt((PythonTree)o);
}
return null;
}
List castStmts(PythonTree t) {
stmt s = (stmt)t;
List stmts = new ArrayList();
stmts.add(s);
return stmts;
}
List castStmts(List stmts) {
if (stmts != null) {
List result = new ArrayList();
for (Object o:stmts) {
result.add(castStmt(o));
}
return result;
}
return new ArrayList();
}
expr makeDottedAttr(Token nameToken, List attrs) {
expr current = new Name(nameToken, nameToken.getText(), expr_contextType.Load);
for (Object o: attrs) {
Token t = (Token)o;
current = new Attribute(t, current, cantBeNoneName(t),
expr_contextType.Load);
}
return current;
}
stmt makeWhile(Token t, expr test, List body, List orelse) {
if (test == null) {
return errorHandler.errorStmt(new PythonTree(t));
}
List o = castStmts(orelse);
List b = castStmts(body);
return new While(t, test, b, o);
}
stmt makeWith(Token t, List items, List body) {
int last = items.size() - 1;
With result = null;
for (int i = last; i>=0; i--) {
With current = items.get(i);
if (i != last) {
body = new ArrayList();
body.add(result);
}
result = new With(current.getToken(), current.getInternalContext_expr(), current.getInternalOptional_vars(), body);
}
return result;
}
stmt makeFor(Token t, expr target, expr iter, List body, List orelse) {
if (target == null || iter == null) {
return errorHandler.errorStmt(new PythonTree(t));
}
cantBeNone(target);
List o = castStmts(orelse);
List b = castStmts(body);
return new For(t, target, iter, b, o);
}
stmt makeTryExcept(Token t, List body, List handlers, List orelse, List finBody) {
List b = castStmts(body);
List e = handlers;
List o = castStmts(orelse);
stmt te = new TryExcept(t, b, e, o);
if (finBody == null) {
return te;
}
List f = castStmts(finBody);
List mainBody = new ArrayList();
mainBody.add(te);
return new TryFinally(t, mainBody, f);
}
TryFinally makeTryFinally(Token t, List body, List finBody) {
List b = castStmts(body);
List f = castStmts(finBody);
return new TryFinally(t, b, f);
}
stmt makeFuncdef(Token t, Token nameToken, arguments args, List funcStatements, List decorators) {
if (nameToken == null) {
return errorHandler.errorStmt(new PythonTree(t));
}
Name n = cantBeNoneName(nameToken);
arguments a;
if (args != null) {
a = args;
} else {
a = new arguments(t, new ArrayList(), (Name)null, null, new ArrayList());
}
List s = castStmts(funcStatements);
List d = castExprs(decorators);
return new FunctionDef(t, n, a, s, d);
}
List makeAssignTargets(expr lhs, List rhs) {
List e = new ArrayList();
checkAssign(lhs);
e.add(lhs);
for(int i=0;i p = castExprs(params);
List d = castExprs(defaults);
Name s;
Name k;
if (snameToken == null) {
s = null;
} else {
s = cantBeNoneName(snameToken);
}
if (knameToken == null) {
k = null;
} else {
k = cantBeNoneName(knameToken);
}
return new arguments(t, p, s, k, d);
}
List extractArgs(List args) {
return castExprs(args);
}
List makeKeywords(List args) {
List keywords = new ArrayList();
if (args != null) {
for (Object o : args) {
List e = (List)o;
Object k = e.get(0);
Object v = e.get(1);
checkAssign(castExpr(k));
if (k instanceof Name) {
Name arg = (Name)k;
keywords.add(new keyword(arg, arg.getInternalId(), castExpr(v)));
} else {
errorHandler.error("keyword must be a name", (PythonTree)k);
}
}
}
return keywords;
}
Object makeFloat(Token t) {
return Py.newFloat(Double.valueOf(t.getText()));
}
Object makeComplex(Token t) {
String s = t.getText();
s = s.substring(0, s.length() - 1);
return Py.newImaginary(Double.valueOf(s));
}
//XXX: needs to handle NumberFormatException (on input like 0b2) and needs
// a better long guard than ndigits > 11 (this is much to short for
// binary for example)
Object makeInt(Token t) {
String s = t.getText();
int radix = 10;
if (s.startsWith("0x") || s.startsWith("0X")) {
radix = 16;
s = s.substring(2, s.length());
} else if (s.startsWith("0o") || s.startsWith("0O")) {
radix = 8;
s = s.substring(2, s.length());
} else if (s.startsWith("0b") || s.startsWith("0B")) {
radix = 2;
s = s.substring(2, s.length());
} else if (s.startsWith("0")) {
radix = 8;
}
if (s.endsWith("L") || s.endsWith("l")) {
s = s.substring(0, s.length()-1);
return Py.newLong(new BigInteger(s, radix));
}
int ndigits = s.length();
int i=0;
while (i < ndigits && s.charAt(i) == '0') {
i++;
}
if ((ndigits - i) > 11) {
return Py.newLong(new BigInteger(s, radix));
}
long l = Long.valueOf(s, radix).longValue();
if (l > 0xffffffffl || (l > Integer.MAX_VALUE)) {
return Py.newLong(new BigInteger(s, radix));
}
return Py.newInteger((int) l);
}
class StringPair {
private String s;
private boolean unicode;
StringPair(String s, boolean unicode) {
this.s = s;
this.unicode = unicode;
}
String getString() {
return s;
}
boolean isUnicode() {
return unicode;
}
}
PyString extractStrings(List s, String encoding, boolean unicodeLiterals) {
boolean ustring = false;
Token last = null;
StringBuffer sb = new StringBuffer();
Iterator iter = s.iterator();
while (iter.hasNext()) {
last = (Token)iter.next();
StringPair sp = extractString(last, encoding, unicodeLiterals);
if (sp.isUnicode()) {
ustring = true;
}
sb.append(sp.getString());
}
if (ustring) {
return new PyUnicode(sb.toString());
}
return new PyString(sb.toString());
}
StringPair extractString(Token t, String encoding, boolean unicodeLiterals) {
String string = t.getText();
char quoteChar = string.charAt(0);
int start = 0;
int end;
boolean ustring = unicodeLiterals;
if (quoteChar == 'u' || quoteChar == 'U') {
ustring = true;
start++;
}
if (quoteChar == 'b' || quoteChar == 'B') {
// In 2.x this is just a str, and the parser prevents a 'u' and a
// 'b' in the same identifier, so just advance start.
ustring = false;
start++;
}
quoteChar = string.charAt(start);
boolean raw = false;
if (quoteChar == 'r' || quoteChar == 'R') {
raw = true;
start++;
}
int quotes = 3;
if (string.length() - start == 2) {
quotes = 1;
}
if (string.charAt(start) != string.charAt(start+1)) {
quotes = 1;
}
start = quotes + start;
end = string.length() - quotes;
// string is properly decoded according to the source encoding
// XXX: No need to re-encode when the encoding is iso-8859-1, but ParserFacade
// needs to normalize the encoding name
if (!ustring && encoding != null) {
// The parser used a non-latin encoding: re-encode chars to bytes.
Charset cs = Charset.forName(encoding);
ByteBuffer decoded = cs.encode(string.substring(start, end));
string = StringUtil.fromBytes(decoded);
if (!raw) {
// Handle escapes in non-raw strs
string = PyString.decode_UnicodeEscape(string, 0, string.length(), "strict",
ustring);
}
} else if (raw) {
// Raw str without an encoding or raw unicode
string = string.substring(start, end);
if (ustring) {
// Raw unicode: handle unicode escapes
string = codecs.PyUnicode_DecodeRawUnicodeEscape(string, "strict");
}
} else {
// Plain unicode: already decoded, just handle escapes
string = PyString.decode_UnicodeEscape(string, start, end, "strict", ustring);
}
return new StringPair(string, ustring);
}
Token extractStringToken(List s) {
return (Token)s.get(0);
//return (Token)s.get(s.size() - 1);
}
expr makeCall(Token t, expr func) {
return makeCall(t, func, null, null, null, null);
}
expr makeCall(Token t, expr func, List args, List keywords, expr starargs, expr kwargs) {
if (func == null) {
return errorHandler.errorExpr(new PythonTree(t));
}
List k = makeKeywords(keywords);
List a = castExprs(args);
return new Call(t, func, a, k, starargs, kwargs);
}
expr negate(Token t, expr o) {
return negate(new PythonTree(t), o);
}
expr negate(PythonTree t, expr o) {
if (o instanceof Num) {
Num num = (Num)o;
if (num.getInternalN() instanceof PyInteger) {
int v = ((PyInteger)num.getInternalN()).getValue();
if (v >= 0) {
num.setN(new PyInteger(-v));
return num;
}
} else if (num.getInternalN() instanceof PyLong) {
BigInteger v = ((PyLong)num.getInternalN()).getValue();
if (v.compareTo(BigInteger.ZERO) == 1) {
num.setN(new PyLong(v.negate()));
return num;
}
} else if (num.getInternalN() instanceof PyFloat) {
double v = ((PyFloat)num.getInternalN()).getValue();
if (v >= 0) {
num.setN(new PyFloat(-v));
return num;
}
} else if (num.getInternalN() instanceof PyComplex) {
double v = ((PyComplex)num.getInternalN()).imag;
if (v >= 0) {
num.setN(new PyComplex(0,-v));
return num;
}
}
}
return new UnaryOp(t, unaryopType.USub, o);
}
String cantBeNone(Token t) {
if (t == null || t.getText().equals("None")) {
errorHandler.error("can't be None", new PythonTree(t));
}
return t.getText();
}
Name cantBeNoneName(Token t) {
if (t == null || t.getText().equals("None")) {
errorHandler.error("can't be None", new PythonTree(t));
}
return new Name(t, t.getText(), expr_contextType.Load);
}
void cantBeNone(PythonTree e) {
if (e.getText().equals("None")) {
errorHandler.error("can't be None", e);
}
}
private void checkGenericAssign(expr e) {
if (e instanceof Name && ((Name)e).getInternalId().equals("None")) {
errorHandler.error("assignment to None", e);
} else if (e instanceof GeneratorExp) {
errorHandler.error("can't assign to generator expression", e);
} else if (e instanceof Num) {
errorHandler.error("can't assign to number", e);
} else if (e instanceof Str) {
errorHandler.error("can't assign to string", e);
} else if (e instanceof Yield) {
errorHandler.error("can't assign to yield expression", e);
} else if (e instanceof BinOp) {
errorHandler.error("can't assign to operator", e);
} else if (e instanceof BoolOp) {
errorHandler.error("can't assign to operator", e);
} else if (e instanceof Lambda) {
errorHandler.error("can't assign to lambda", e);
} else if (e instanceof Call) {
errorHandler.error("can't assign to function call", e);
} else if (e instanceof Repr) {
errorHandler.error("can't assign to repr", e);
} else if (e instanceof IfExp) {
errorHandler.error("can't assign to conditional expression", e);
} else if (e instanceof ListComp) {
errorHandler.error("can't assign to list comprehension", e);
} else if (e instanceof SetComp) {
errorHandler.error("can't assign to set comprehension", e);
} else if (e instanceof DictComp) {
errorHandler.error("can't assign to dict comprehension", e);
}
}
void checkAugAssign(expr e) {
checkGenericAssign(e);
if (e instanceof Tuple) {
errorHandler.error("assignment to tuple illegal for augmented assignment", e);
} else if (e instanceof org.python.antlr.ast.List) {
errorHandler.error("assignment to list illegal for augmented assignment", e);
}
}
void checkAssign(expr e) {
checkGenericAssign(e);
if (e instanceof Tuple) {
//XXX: performance problem? Any way to do this better?
List elts = ((Tuple)e).getInternalElts();
if (elts.size() == 0) {
errorHandler.error("can't assign to ()", e);
}
for (int i=0;i elts = ((org.python.antlr.ast.List)e).getInternalElts();
for (int i=0;i makeDeleteList(List deletes) {
List exprs = castExprs(deletes);
for(expr e : exprs) {
checkDelete(e);
}
return exprs;
}
void checkDelete(expr e) {
if (e instanceof Call) {
errorHandler.error("can't delete function call", e);
} else if (e instanceof Num) {
errorHandler.error("can't delete number", e);
} else if (e instanceof Str) {
errorHandler.error("can't delete string", e);
} else if (e instanceof Tuple) {
//XXX: performance problem? Any way to do this better?
List elts = ((Tuple)e).getInternalElts();
if (elts.size() == 0) {
errorHandler.error("can't delete ()", e);
}
for (int i=0;i elts = ((org.python.antlr.ast.List)e).getInternalElts();
for (int i=0;i makeCmpOps(List cmps) {
List result = new ArrayList();
if (cmps != null) {
for (Object o: cmps) {
result.add((cmpopType)o);
}
}
return result;
}
BoolOp makeBoolOp(Token t, PythonTree left, boolopType op, List right) {
List values = new ArrayList();
values.add(left);
values.addAll(right);
return new BoolOp(t, op, castExprs(values));
}
BinOp makeBinOp(Token t, PythonTree left, operatorType op, List rights) {
BinOp current = new BinOp(t, castExpr(left), op, castExpr(rights.get(0)));
for (int i = 1; i< rights.size(); i++) {
expr right = castExpr(rights.get(i));
current = new BinOp(left, current, op, right);
}
return current;
}
BinOp makeBinOp(Token t, PythonTree left, List ops, List rights, List toks) {
BinOp current = new BinOp(t, castExpr(left), (operatorType)ops.get(0), castExpr(rights.get(0)));
for (int i = 1; i< rights.size(); i++) {
expr right = castExpr(rights.get(i));
operatorType op = (operatorType)ops.get(i);
current = new BinOp((Token)toks.get(i), current, op, right);
}
return current;
}
List castSlices(List slices) {
List result = new ArrayList();
if (slices != null) {
for (Object o:slices) {
result.add(castSlice(o));
}
}
return result;
}
slice castSlice(Object o) {
if (o instanceof slice) {
return (slice)o;
}
return errorHandler.errorSlice((PythonTree)o);
}
slice makeSliceType(Token begin, Token c1, Token c2, List sltypes) {
boolean isTuple = false;
if (c1 != null || c2 != null) {
isTuple = true;
}
slice s = null;
boolean extslice = false;
if (isTuple) {
List st;
List etypes = new ArrayList();
for (Object o : sltypes) {
if (o instanceof Index) {
Index i = (Index)o;
etypes.add(i.getInternalValue());
} else {
extslice = true;
break;
}
}
if (!extslice) {
expr t = new Tuple(begin, etypes, expr_contextType.Load);
s = new Index(begin, t);
}
} else if (sltypes.size() == 1) {
s = castSlice(sltypes.get(0));
} else if (sltypes.size() != 0) {
extslice = true;
}
if (extslice) {
List st = castSlices(sltypes);
s = new ExtSlice(begin, st);
}
return s;
}
}