Skip to content

Commit 82d08f9

Browse files
committed
string and backslash continuation
1 parent 78786c7 commit 82d08f9

File tree

8 files changed

+413
-321
lines changed

8 files changed

+413
-321
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/parser/antlr/DescriptiveBailErrorListener.java

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
package com.oracle.graal.python.parser.antlr;
4242

4343
import org.antlr.v4.runtime.BaseErrorListener;
44+
import org.antlr.v4.runtime.CharStream;
4445
import org.antlr.v4.runtime.ParserRuleContext;
4546
import org.antlr.v4.runtime.RecognitionException;
4647
import org.antlr.v4.runtime.Recognizer;
@@ -78,7 +79,7 @@ public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol,
7879
}
7980
}
8081
if (isInteractive(recognizer)) {
81-
PIncompleteSourceException handleRecognitionException = handleInteractiveException(recognizer);
82+
PIncompleteSourceException handleRecognitionException = handleInteractiveException(recognizer, offendingSymbol);
8283
if (handleRecognitionException != null) {
8384
throw handleRecognitionException;
8485
}
@@ -96,8 +97,8 @@ private static PIncompleteSourceException handleRecognitionException(IntervalSet
9697
return null;
9798
}
9899

99-
private static PIncompleteSourceException handleInteractiveException(Recognizer<?, ?> recognizer) {
100-
if (isOpened(((Python3Parser) recognizer).getTokenStream())) {
100+
private static PIncompleteSourceException handleInteractiveException(Recognizer<?, ?> recognizer, Object offendingSymbol) {
101+
if (isOpened(((Python3Parser) recognizer).getTokenStream()) || isBackslash(offendingSymbol)) {
101102
return new PIncompleteSourceException("", null, -1);
102103
}
103104
return null;
@@ -130,6 +131,18 @@ private static boolean isOpened(TokenStream input) {
130131
return lexer.isOpened();
131132
}
132133

134+
private static final int BACKSLASH = '\\';
135+
136+
private static boolean isBackslash(Object offendingSymbol) {
137+
if (offendingSymbol instanceof Token) {
138+
CharStream cs = ((Token) offendingSymbol).getInputStream();
139+
if (cs.size() > 2 && cs.LA(-2) == BACKSLASH) {
140+
return true;
141+
}
142+
}
143+
return false;
144+
}
145+
133146
private static class EmptyRecognitionException extends RecognitionException {
134147
private static final long serialVersionUID = 1L;
135148
private Token offendingToken;

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/parser/antlr/Python3.g4

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ tokens { INDENT, DEDENT }
5151
// wether we have expanded EOF to include necessary DEDENTS and a NEWLINE
5252
private boolean expandedEOF = false;
5353
54+
private boolean longQuote1 = false; // """
55+
private boolean longQuote2 = false; // '''
56+
5457
@Override
5558
public void emit(Token t) {
5659
super.setToken(t);
@@ -93,7 +96,19 @@ tokens { INDENT, DEDENT }
9396
}
9497

9598
public boolean isOpened() {
96-
return opened > 0;
99+
return this.opened > 0 || this.longQuote1 || this.longQuote2;
100+
}
101+
102+
private void usedQuote1() {
103+
if (!this.longQuote2){
104+
this.longQuote1 = !this.longQuote1;
105+
}
106+
}
107+
108+
private void usedQuote2() {
109+
if (!this.longQuote1){
110+
this.longQuote2 = !this.longQuote2;
111+
}
97112
}
98113

99114
private Token createDedent() {
@@ -1801,6 +1816,8 @@ LEFT_SHIFT_ASSIGN : '<<=';
18011816
RIGHT_SHIFT_ASSIGN : '>>=';
18021817
POWER_ASSIGN : '**=';
18031818
IDIV_ASSIGN : '//=';
1819+
LONG_QUOTES1 : '"""' {usedQuote1();};
1820+
LONG_QUOTES2 : '\'\'\'' {usedQuote2();};
18041821

18051822
SKIP_
18061823
: ( SPACES | COMMENT | LINE_JOINING ) -> skip

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/parser/antlr/Python3.interp

Lines changed: 5 additions & 1 deletion
Large diffs are not rendered by default.

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/parser/antlr/Python3.tokens

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,12 @@ LEFT_SHIFT_ASSIGN=90
9191
RIGHT_SHIFT_ASSIGN=91
9292
POWER_ASSIGN=92
9393
IDIV_ASSIGN=93
94-
SKIP_=94
95-
UNKNOWN_CHAR=95
96-
INDENT=96
97-
DEDENT=97
94+
LONG_QUOTES1=94
95+
LONG_QUOTES2=95
96+
SKIP_=96
97+
UNKNOWN_CHAR=97
98+
INDENT=98
99+
DEDENT=99
98100
'def'=2
99101
'return'=3
100102
'raise'=4
@@ -177,3 +179,5 @@ DEDENT=97
177179
'>>='=91
178180
'**='=92
179181
'//='=93
182+
'"""'=94
183+
'\'\'\''=95

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/parser/antlr/Python3Lexer.interp

Lines changed: 7 additions & 1 deletion
Large diffs are not rendered by default.

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/parser/antlr/Python3Lexer.java

Lines changed: 345 additions & 301 deletions
Large diffs are not rendered by default.

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/parser/antlr/Python3Lexer.tokens

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,10 @@ LEFT_SHIFT_ASSIGN=90
9191
RIGHT_SHIFT_ASSIGN=91
9292
POWER_ASSIGN=92
9393
IDIV_ASSIGN=93
94-
SKIP_=94
95-
UNKNOWN_CHAR=95
94+
LONG_QUOTES1=94
95+
LONG_QUOTES2=95
96+
SKIP_=96
97+
UNKNOWN_CHAR=97
9698
'def'=2
9799
'return'=3
98100
'raise'=4
@@ -175,3 +177,5 @@ UNKNOWN_CHAR=95
175177
'>>='=91
176178
'**='=92
177179
'//='=93
180+
'"""'=94
181+
'\'\'\''=95

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/parser/antlr/Python3Parser.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ public class Python3Parser extends Parser {
8484
EQUALS=74, GT_EQ=75, LT_EQ=76, NOT_EQ_1=77, NOT_EQ_2=78, AT=79, ARROW=80,
8585
ADD_ASSIGN=81, SUB_ASSIGN=82, MULT_ASSIGN=83, AT_ASSIGN=84, DIV_ASSIGN=85,
8686
MOD_ASSIGN=86, AND_ASSIGN=87, OR_ASSIGN=88, XOR_ASSIGN=89, LEFT_SHIFT_ASSIGN=90,
87-
RIGHT_SHIFT_ASSIGN=91, POWER_ASSIGN=92, IDIV_ASSIGN=93, SKIP_=94, UNKNOWN_CHAR=95,
88-
INDENT=96, DEDENT=97;
87+
RIGHT_SHIFT_ASSIGN=91, POWER_ASSIGN=92, IDIV_ASSIGN=93, LONG_QUOTES1=94,
88+
LONG_QUOTES2=95, SKIP_=96, UNKNOWN_CHAR=97, INDENT=98, DEDENT=99;
8989
public static final int
9090
RULE_single_input = 0, RULE_file_input = 1, RULE_eval_input = 2, RULE_decorator = 3,
9191
RULE_decorators = 4, RULE_decorated = 5, RULE_async_funcdef = 6, RULE_funcdef = 7,
@@ -142,7 +142,7 @@ private static String[] makeLiteralNames() {
142142
"'|'", "'^'", "'&'", "'<<'", "'>>'", "'+'", "'-'", "'/'", "'%'", "'//'",
143143
"'~'", "'{'", "'}'", "'<'", "'>'", "'=='", "'>='", "'<='", "'<>'", "'!='",
144144
"'@'", "'->'", "'+='", "'-='", "'*='", "'@='", "'/='", "'%='", "'&='",
145-
"'|='", "'^='", "'<<='", "'>>='", "'**='", "'//='"
145+
"'|='", "'^='", "'<<='", "'>>='", "'**='", "'//='", "'\"\"\"'", "'''''"
146146
};
147147
}
148148
private static final String[] _LITERAL_NAMES = makeLiteralNames();
@@ -161,8 +161,8 @@ private static String[] makeSymbolicNames() {
161161
"GREATER_THAN", "EQUALS", "GT_EQ", "LT_EQ", "NOT_EQ_1", "NOT_EQ_2", "AT",
162162
"ARROW", "ADD_ASSIGN", "SUB_ASSIGN", "MULT_ASSIGN", "AT_ASSIGN", "DIV_ASSIGN",
163163
"MOD_ASSIGN", "AND_ASSIGN", "OR_ASSIGN", "XOR_ASSIGN", "LEFT_SHIFT_ASSIGN",
164-
"RIGHT_SHIFT_ASSIGN", "POWER_ASSIGN", "IDIV_ASSIGN", "SKIP_", "UNKNOWN_CHAR",
165-
"INDENT", "DEDENT"
164+
"RIGHT_SHIFT_ASSIGN", "POWER_ASSIGN", "IDIV_ASSIGN", "LONG_QUOTES1",
165+
"LONG_QUOTES2", "SKIP_", "UNKNOWN_CHAR", "INDENT", "DEDENT"
166166
};
167167
}
168168
private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames();
@@ -8371,7 +8371,7 @@ public final Yield_exprContext yield_expr() throws RecognitionException {
83718371
}
83728372

83738373
public static final String _serializedATN =
8374-
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3c\u0657\4\2\t\2\4"+
8374+
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3e\u0657\4\2\t\2\4"+
83758375
"\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t"+
83768376
"\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+
83778377
"\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+
@@ -8771,8 +8771,8 @@ public final Yield_exprContext yield_expr() throws RecognitionException {
87718771
"d\63\2\u03c4\u03c5\b\62\1\2\u03c5\u03c7\3\2\2\2\u03c6\u03be\3\2\2\2\u03c6"+
87728772
"\u03c2\3\2\2\2\u03c7\u03c8\3\2\2\2\u03c8\u03c9\b\62\1\2\u03c9c\3\2\2\2"+
87738773
"\u03ca\u03d5\b\63\1\2\u03cb\u03d6\5&\24\2\u03cc\u03cd\7\'\2\2\u03cd\u03cf"+
8774-
"\7b\2\2\u03ce\u03d0\5$\23\2\u03cf\u03ce\3\2\2\2\u03d0\u03d1\3\2\2\2\u03d1"+
8775-
"\u03cf\3\2\2\2\u03d1\u03d2\3\2\2\2\u03d2\u03d3\3\2\2\2\u03d3\u03d4\7c"+
8774+
"\7d\2\2\u03ce\u03d0\5$\23\2\u03cf\u03ce\3\2\2\2\u03d0\u03d1\3\2\2\2\u03d1"+
8775+
"\u03cf\3\2\2\2\u03d1\u03d2\3\2\2\2\u03d2\u03d3\3\2\2\2\u03d3\u03d4\7e"+
87768776
"\2\2\u03d4\u03d6\3\2\2\2\u03d5\u03cb\3\2\2\2\u03d5\u03cc\3\2\2\2\u03d6"+
87778777
"\u03d7\3\2\2\2\u03d7\u03d8\b\63\1\2\u03d8e\3\2\2\2\u03d9\u03da\5n8\2\u03da"+
87788778
"\u03e1\b\64\1\2\u03db\u03dc\7\r\2\2\u03dc\u03dd\5n8\2\u03dd\u03de\7\17"+

0 commit comments

Comments
 (0)