parsing Python 3 set comprehensions

This commit is contained in:
Dmitry Jemerov
2010-01-22 18:43:10 +03:00
parent 38cd9c6e67
commit a927e91a46
9 changed files with 75 additions and 6 deletions
@@ -97,6 +97,7 @@ public interface PyElementTypes {
PyElementType YIELD_EXPRESSION = new PyElementType("YIELD_EXPRESSION", PyYieldExpressionImpl.class);
PyElementType SET_LITERAL_EXPRESSION = new PyElementType("SET_LITERAL_EXPRESSION", PySetLiteralExpressionImpl.class);
PyElementType SET_COMP_EXPRESSION = new PyElementType("SET_COMP_EXPRESSION", PySetCompExpressionImpl.class);
TokenSet EXPRESSIONS = TokenSet.create(EMPTY_EXPRESSION, REFERENCE_EXPRESSION, INTEGER_LITERAL_EXPRESSION, FLOAT_LITERAL_EXPRESSION,
IMAGINARY_LITERAL_EXPRESSION, STRING_LITERAL_EXPRESSION, PARENTHESIZED_EXPRESSION,
@@ -105,7 +106,7 @@ public interface PyElementTypes {
LAMBDA_EXPRESSION, LIST_COMP_EXPRESSION, DICT_LITERAL_EXPRESSION, KEY_VALUE_EXPRESSION,
REPR_EXPRESSION, GENERATOR_EXPRESSION, CONDITIONAL_EXPRESSION, YIELD_EXPRESSION,
TARGET_EXPRESSION, NONE_LITERAL_EXPRESSION, BOOL_LITERAL_EXPRESSION,
SET_LITERAL_EXPRESSION);
SET_LITERAL_EXPRESSION, SET_COMP_EXPRESSION);
TokenSet LIST_LIKE_EXPRESSIONS = TokenSet.create(LIST_LITERAL_EXPRESSION, LIST_COMP_EXPRESSION, TUPLE_EXPRESSION);
@@ -89,7 +89,7 @@ public class ExpressionParsing extends Parsing {
builder.error(message("PARSE.expected.expression"));
}
if (builder.getTokenType() == PyTokenTypes.FOR_KEYWORD) {
parseListCompExpression(expr, PyTokenTypes.RBRACKET, PyElementTypes.LIST_COMP_EXPRESSION);
parseComprehension(expr, PyTokenTypes.RBRACKET, PyElementTypes.LIST_COMP_EXPRESSION);
}
else {
while (builder.getTokenType() != PyTokenTypes.RBRACKET) {
@@ -106,7 +106,7 @@ public class ExpressionParsing extends Parsing {
}
}
private void parseListCompExpression(PsiBuilder.Marker expr,
private void parseComprehension(PsiBuilder.Marker expr,
final IElementType endToken,
final IElementType exprType) {
assertCurrentToken(PyTokenTypes.FOR_KEYWORD);
@@ -163,6 +163,10 @@ public class ExpressionParsing extends Parsing {
firstExprMarker.drop();
parseSetLiteralTail(expr);
}
else if (myBuilder.getTokenType() == PyTokenTypes.FOR_KEYWORD) {
firstExprMarker.drop();
parseComprehension(expr, PyTokenTypes.RBRACE, PyElementTypes.SET_COMP_EXPRESSION);
}
else {
myBuilder.error("expression expected");
firstExprMarker.drop();
@@ -230,7 +234,7 @@ public class ExpressionParsing extends Parsing {
else {
parseYieldOrTupleExpression(builder, isTargetExpression);
if (builder.getTokenType() == PyTokenTypes.FOR_KEYWORD) {
parseListCompExpression(expr, PyTokenTypes.RPAR, PyElementTypes.GENERATOR_EXPRESSION);
parseComprehension(expr, PyTokenTypes.RPAR, PyElementTypes.GENERATOR_EXPRESSION);
}
else {
checkMatches(PyTokenTypes.RPAR, message("PARSE.expected.rpar"));
@@ -360,7 +364,7 @@ public class ExpressionParsing extends Parsing {
argNumber++;
if (argNumber > 1) {
if (argNumber == 2 && myBuilder.getTokenType() == PyTokenTypes.FOR_KEYWORD && genexpr != null) {
parseListCompExpression(genexpr, PyTokenTypes.RPAR, PyElementTypes.GENERATOR_EXPRESSION);
parseComprehension(genexpr, PyTokenTypes.RPAR, PyElementTypes.GENERATOR_EXPRESSION);
needBracket = false;
break;
}
@@ -0,0 +1,9 @@
package com.jetbrains.python.psi;
/**
* Set comprehension: {x for x in range(10)}
*
* @author yole
*/
public interface PySetCompExpression extends PyExpression, NameDefiner {
}
@@ -0,0 +1,19 @@
package com.jetbrains.python.psi.impl;
import com.intellij.lang.ASTNode;
import com.jetbrains.python.psi.PySetCompExpression;
import com.jetbrains.python.psi.types.PyType;
/**
* @author yole
*/
public class PySetCompExpressionImpl extends PyComprehensionElementImpl implements PySetCompExpression {
public PySetCompExpressionImpl(ASTNode astNode) {
super(astNode);
}
public PyType getType() {
// TODO
return null;
}
}
+1
View File
@@ -0,0 +1 @@
{x for x in range(10)}
+23
View File
@@ -0,0 +1,23 @@
PyFile:SetComprehension.py
PyExpressionStatement
PySetCompExpression
PsiElement(Py:LBRACE)('{')
PyReferenceExpression: x
PsiElement(Py:IDENTIFIER)('x')
PsiWhiteSpace(' ')
PsiElement(Py:FOR_KEYWORD)('for')
PsiWhiteSpace(' ')
PyTargetExpression: x
PsiElement(Py:IDENTIFIER)('x')
PsiWhiteSpace(' ')
PsiElement(Py:IN_KEYWORD)('in')
PsiWhiteSpace(' ')
PyCallExpression: range
PyReferenceExpression: range
PsiElement(Py:IDENTIFIER)('range')
PyArgumentList
PsiElement(Py:LPAR)('(')
PyNumericLiteralExpression
PsiElement(Py:INTEGER_LITERAL)('10')
PsiElement(Py:RPAR)(')')
PsiElement(Py:RBRACE)('}')
+1
View File
@@ -1 +1,2 @@
{1, 2}
{1}
+8 -1
View File
@@ -8,4 +8,11 @@ PyFile:SetLiteral.py
PsiWhiteSpace(' ')
PyNumericLiteralExpression
PsiElement(Py:INTEGER_LITERAL)('2')
PsiElement(Py:RBRACE)('}')
PsiElement(Py:RBRACE)('}')
PsiWhiteSpace('\n')
PyExpressionStatement
PySetLiteralExpression
PsiElement(Py:LBRACE)('{')
PyNumericLiteralExpression
PsiElement(Py:INTEGER_LITERAL)('1')
PsiElement(Py:RBRACE)('}')
@@ -146,6 +146,10 @@ public class PythonParsingTest extends ParsingTestCase {
doTest(LanguageLevel.PYTHON30);
}
public void testSetComprehension() throws Exception {
doTest(LanguageLevel.PYTHON30);
}
public void doTest() throws Exception {
doTest(LanguageLevel.PYTHON25);
}