Parsing of '@' and '@=' operators (PY-15390)

We have to introduce a new lexeme '@=' and re-define '@' to become a
binary operator as well as the prefix of the decorator.
This commit is contained in:
Andrey Vlasovskikh
2015-03-24 17:40:42 +03:00
parent 8d3dd98d6d
commit e7db2ff39c
7 changed files with 645 additions and 494 deletions
File diff suppressed because it is too large Load Diff
@@ -128,6 +128,7 @@ public class PyTokenTypes {
public static final PyElementType PLUSEQ = new PyElementType("PLUSEQ");// +=
public static final PyElementType MINUSEQ = new PyElementType("MINUSEQ");// -=
public static final PyElementType MULTEQ = new PyElementType("MULTEQ");// *=
public static final PyElementType ATEQ = new PyElementType("ATEQ"); // @=
public static final PyElementType DIVEQ = new PyElementType("DIVEQ"); // /=
public static final PyElementType FLOORDIVEQ = new PyElementType("FLOORDIVEQ"); // //=
public static final PyElementType PERCEQ = new PyElementType("PERCEQ");// %=
@@ -139,10 +140,10 @@ public class PyTokenTypes {
public static final PyElementType EXPEQ = new PyElementType("EXPEQ");// **=
public static final TokenSet OPERATIONS = TokenSet.create(
PLUS, MINUS, MULT, EXP, DIV, FLOORDIV, PERC, LTLT, GTGT, AND, OR,
PLUS, MINUS, MULT, AT, EXP, DIV, FLOORDIV, PERC, LTLT, GTGT, AND, OR,
XOR, TILDE, LT, GT, LE, GE, EQEQ, NE, NE_OLD, AT, COLON, TICK, EQ,
PLUSEQ, MINUSEQ,
MULTEQ, DIVEQ, FLOORDIVEQ, PERCEQ, ANDEQ, OREQ, XOREQ, LTLTEQ, GTGTEQ,
MULTEQ, ATEQ, DIVEQ, FLOORDIVEQ, PERCEQ, ANDEQ, OREQ, XOREQ, LTLTEQ, GTGTEQ,
EXPEQ);
public static final TokenSet COMPARISON_OPERATIONS = TokenSet.create(
@@ -150,8 +151,8 @@ public class PyTokenTypes {
public static final TokenSet SHIFT_OPERATIONS = TokenSet.create(LTLT, GTGT);
public static final TokenSet ADDITIVE_OPERATIONS = TokenSet.create(PLUS, MINUS);
public static final TokenSet MULTIPLICATIVE_OPERATIONS = TokenSet.create(MULT, FLOORDIV, DIV, PERC);
public static final TokenSet MULTIPLICATIVE_OR_EXP = TokenSet.create(MULT, FLOORDIV, DIV, PERC, EXP);
public static final TokenSet MULTIPLICATIVE_OPERATIONS = TokenSet.create(MULT, AT, FLOORDIV, DIV, PERC);
public static final TokenSet MULTIPLICATIVE_OR_EXP = TokenSet.create(MULT, AT, FLOORDIV, DIV, PERC, EXP);
public static final TokenSet UNARY_OPERATIONS = TokenSet.create(PLUS, MINUS, TILDE);
public static final TokenSet BITWISE_OPERATIONS = TokenSet.create(AND, OR, XOR);
public static final TokenSet EQUALITY_OPERATIONS = TokenSet.create(EQEQ, NE, NE_OLD);
@@ -162,7 +163,7 @@ public class PyTokenTypes {
public static final TokenSet OPEN_BRACES = TokenSet.create(LBRACKET, LBRACE, LPAR);
public static final TokenSet CLOSE_BRACES = TokenSet.create(RBRACKET, RBRACE, RPAR);
public static final TokenSet AUG_ASSIGN_OPERATIONS = TokenSet.create(PLUSEQ, MINUSEQ, MULTEQ, DIVEQ,
public static final TokenSet AUG_ASSIGN_OPERATIONS = TokenSet.create(PLUSEQ, MINUSEQ, MULTEQ, ATEQ, DIVEQ,
PERCEQ, EXPEQ, GTGTEQ, LTLTEQ, ANDEQ, OREQ, XOREQ, FLOORDIVEQ);
public static final PyElementType BACKSLASH = new PyElementType("BACKSLASH");
@@ -127,7 +127,8 @@ public interface PyElementTypes {
PyTokenTypes.OR, PyTokenTypes.XOR, PyTokenTypes.AND, PyTokenTypes.LTLT, PyTokenTypes.GTGT,
PyTokenTypes.EQEQ, PyTokenTypes.GE, PyTokenTypes.LE, PyTokenTypes.NE, PyTokenTypes.NE_OLD,
PyTokenTypes.IN_KEYWORD, PyTokenTypes.IS_KEYWORD, PyTokenTypes.NOT_KEYWORD, PyTokenTypes.PLUS,
PyTokenTypes.MINUS, PyTokenTypes.MULT, PyTokenTypes.FLOORDIV, PyTokenTypes.DIV, PyTokenTypes.PERC, PyTokenTypes.EXP);
PyTokenTypes.MINUS, PyTokenTypes.MULT, PyTokenTypes.AT, PyTokenTypes.FLOORDIV, PyTokenTypes.DIV,
PyTokenTypes.PERC, PyTokenTypes.EXP);
TokenSet UNARY_OPS = TokenSet.create(PyTokenTypes.NOT_KEYWORD, PyTokenTypes.PLUS, PyTokenTypes.MINUS, PyTokenTypes.TILDE);
@@ -160,6 +160,7 @@ return PyTokenTypes.DOCSTRING; }
"-=" { return PyTokenTypes.MINUSEQ; }
"**=" { return PyTokenTypes.EXPEQ; }
"*=" { return PyTokenTypes.MULTEQ; }
"@=" { return PyTokenTypes.ATEQ; }
"//=" { return PyTokenTypes.FLOORDIVEQ; }
"/=" { return PyTokenTypes.DIVEQ; }
"%=" { return PyTokenTypes.PERCEQ; }
+5
View File
@@ -0,0 +1,5 @@
x @ y
x @ y @ z
x @ y * z
x + y @ z
z @= x
+67
View File
@@ -0,0 +1,67 @@
PyFile:MatMul.py
PyExpressionStatement
PyBinaryExpression
PyReferenceExpression: x
PsiElement(Py:IDENTIFIER)('x')
PsiWhiteSpace(' ')
PsiElement(Py:AT)('@')
PsiWhiteSpace(' ')
PyReferenceExpression: y
PsiElement(Py:IDENTIFIER)('y')
PsiWhiteSpace('\n')
PyExpressionStatement
PyBinaryExpression
PyBinaryExpression
PyReferenceExpression: x
PsiElement(Py:IDENTIFIER)('x')
PsiWhiteSpace(' ')
PsiElement(Py:AT)('@')
PsiWhiteSpace(' ')
PyReferenceExpression: y
PsiElement(Py:IDENTIFIER)('y')
PsiWhiteSpace(' ')
PsiElement(Py:AT)('@')
PsiWhiteSpace(' ')
PyReferenceExpression: z
PsiElement(Py:IDENTIFIER)('z')
PsiWhiteSpace('\n')
PyExpressionStatement
PyBinaryExpression
PyBinaryExpression
PyReferenceExpression: x
PsiElement(Py:IDENTIFIER)('x')
PsiWhiteSpace(' ')
PsiElement(Py:AT)('@')
PsiWhiteSpace(' ')
PyReferenceExpression: y
PsiElement(Py:IDENTIFIER)('y')
PsiWhiteSpace(' ')
PsiElement(Py:MULT)('*')
PsiWhiteSpace(' ')
PyReferenceExpression: z
PsiElement(Py:IDENTIFIER)('z')
PsiWhiteSpace('\n')
PyExpressionStatement
PyBinaryExpression
PyReferenceExpression: x
PsiElement(Py:IDENTIFIER)('x')
PsiWhiteSpace(' ')
PsiElement(Py:PLUS)('+')
PsiWhiteSpace(' ')
PyBinaryExpression
PyReferenceExpression: y
PsiElement(Py:IDENTIFIER)('y')
PsiWhiteSpace(' ')
PsiElement(Py:AT)('@')
PsiWhiteSpace(' ')
PyReferenceExpression: z
PsiElement(Py:IDENTIFIER)('z')
PsiWhiteSpace('\n')
PyAugAssignmentStatement
PyReferenceExpression: z
PsiElement(Py:IDENTIFIER)('z')
PsiWhiteSpace(' ')
PsiElement(Py:ATEQ)('@=')
PsiWhiteSpace(' ')
PyReferenceExpression: x
PsiElement(Py:IDENTIFIER)('x')
@@ -468,6 +468,11 @@ public class PythonParsingTest extends ParsingTestCase {
doTest();
}
// PY-15390
public void testMatMul() {
doTest(LanguageLevel.PYTHON35);
}
public void doTest(LanguageLevel languageLevel) {
LanguageLevel prev = myLanguageLevel;
myLanguageLevel = languageLevel;