Skip to content

Commit a8fe6ce

Browse files
committed
Regenerate parser files
1 parent b47b71a commit a8fe6ce

File tree

4 files changed

+1487
-1410
lines changed

4 files changed

+1487
-1410
lines changed

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: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ BOM=97
9898
UNKNOWN_CHAR=98
9999
INDENT=99
100100
DEDENT=100
101+
INDENT_ERROR=101
102+
TAB_ERROR=102
101103
'def'=2
102104
'return'=3
103105
'raise'=4

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

Lines changed: 57 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,21 @@ public Vocabulary getVocabulary() {
171171

172172
// new version with semantic actions in parser
173173

174+
private static class Indent {
175+
public final int indent;
176+
public final int altindent;
177+
public static final Indent EMPTY = new Indent(0, 0);
178+
179+
public Indent(int indent, int altindent) {
180+
this.indent = indent;
181+
this.altindent = altindent;
182+
}
183+
}
184+
174185
// A queue where extra tokens are pushed on (see the NEWLINE lexer rule).
175186
private java.util.LinkedList<Token> tokens = new java.util.LinkedList<>();
176187
// The stack that keeps track of the indentation level.
177-
private java.util.Stack<Integer> indents = new java.util.Stack<>();
188+
private java.util.Stack<Indent> indents = new java.util.Stack<>();
178189
// The amount of opened braces, brackets and parenthesis.
179190
private int opened = 0;
180191
// The most recently produced token.
@@ -298,6 +309,20 @@ private Token createDedent() {
298309
return dedent;
299310
}
300311

312+
private Token createIndentError(int type) {
313+
// For some reason, CPython sets the error position to the end of line
314+
int cur = getCharIndex();
315+
String s;
316+
do {
317+
s = _input.getText(new Interval(cur, cur));
318+
cur++;
319+
} while (!s.isEmpty() && s.charAt(0) != '\n');
320+
cur--;
321+
CommonToken error = new CommonToken(this._tokenFactorySourcePair, type, DEFAULT_TOKEN_CHANNEL, cur, cur);
322+
error.setLine(this.lastToken.getLine());
323+
return error;
324+
}
325+
301326
private CommonToken commonToken(int type, String text) {
302327
int stop = Math.max(this.getCharIndex() - 1, 0);
303328
int start = Math.max(text.isEmpty() ? stop : stop - text.length() + 1, 0);
@@ -311,9 +336,14 @@ private CommonToken commonToken(int type, String text) {
311336
// such that the total number of characters up to and including
312337
// the replacement is a multiple of eight [...]"
313338
//
339+
// Altindent is an alternative measure of spaces where tabs are
340+
// counted as one space. The purpose is to validate that the code
341+
// doesn't mix tabs and spaces in inconsistent way.
342+
//
314343
// -- https://docs.python.org/3.1/reference/lexical_analysis.html#indentation
315-
static int getIndentationCount(String spaces) {
316-
int count = 0;
344+
static Indent getIndentationCount(String spaces) {
345+
int indent = 0;
346+
int altindent = 0;
317347
for (char ch : spaces.toCharArray()) {
318348
switch (ch) {
319349
case '\r':
@@ -322,15 +352,17 @@ static int getIndentationCount(String spaces) {
322352
// ignore
323353
break;
324354
case '\t':
325-
count += 8 - (count % 8);
355+
indent += 8 - (indent % 8);
356+
altindent++;
326357
break;
327358
default:
328359
// A normal space char.
329-
count++;
360+
indent++;
361+
altindent++;
330362
}
331363
}
332364

333-
return count;
365+
return new Indent(indent, altindent);
334366
}
335367

336368
boolean atStartOfInput() {
@@ -405,28 +437,41 @@ private void NEWLINE_action(RuleContext _localctx, int actionIndex) {
405437
}
406438
else {
407439
emit(commonToken(NEWLINE, "\n"));
408-
int indent;
440+
Indent indent;
409441
if (next == EOF) {
410442
// don't add indents if we're going to finish
411-
indent = 0;
443+
indent = Indent.EMPTY;
412444
} else {
413445
indent = getIndentationCount(getText());
414446
}
415-
int previous = indents.isEmpty() ? 0 : indents.peek();
416-
if (indent == previous) {
447+
Indent previous = indents.isEmpty() ? Indent.EMPTY : indents.peek();
448+
if (indent.indent == previous.indent) {
449+
if (indent.altindent != previous.altindent) {
450+
this.emit(createIndentError(Python3Parser.TAB_ERROR));
451+
}
417452
// skip indents of the same size as the present indent-size
418453
skip();
419454
}
420-
else if (indent > previous) {
455+
else if (indent.indent > previous.indent) {
456+
if (indent.altindent <= previous.altindent) {
457+
this.emit(createIndentError(Python3Parser.TAB_ERROR));
458+
}
421459
indents.push(indent);
422460
emit(commonToken(Python3Parser.INDENT, ""));
423461
}
424462
else {
425463
// Possibly emit more than 1 DEDENT token.
426-
while(!indents.isEmpty() && indents.peek() > indent) {
464+
while (!indents.isEmpty() && indents.peek().indent > indent.indent) {
427465
this.emit(createDedent());
428466
indents.pop();
429467
}
468+
Indent expectedIndent = indents.isEmpty() ? Indent.EMPTY : indents.peek();
469+
if (expectedIndent.indent != indent.indent) {
470+
this.emit(createIndentError(Python3Parser.INDENT_ERROR));
471+
}
472+
if (expectedIndent.altindent != indent.altindent) {
473+
this.emit(createIndentError(Python3Parser.TAB_ERROR));
474+
}
430475
}
431476
}
432477

0 commit comments

Comments
 (0)