aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build
diff options
context:
space:
mode:
authorGravatar Laurent Le Brun <laurentlb@google.com>2015-05-28 08:44:51 +0000
committerGravatar Laszlo Csomor <laszlocsomor@google.com>2015-05-28 14:33:19 +0000
commit9be852e2e9622a87d9b145fe6fe4218e23343d66 (patch)
treeb7427c615358a91d13d913dc2497b14a8b7eb826 /src/main/java/com/google/devtools/build
parent9e0ef3ca87f566d6d83cc78b9e202d019afce9f4 (diff)
Parser cleanup: Introduce an enum instead of the booleans
-- MOS_MIGRATED_REVID=94649435
Diffstat (limited to 'src/main/java/com/google/devtools/build')
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/Parser.java76
1 files changed, 46 insertions, 30 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Parser.java b/src/main/java/com/google/devtools/build/lib/syntax/Parser.java
index 67e13e537c..c2642597a3 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Parser.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Parser.java
@@ -14,6 +14,10 @@
package com.google.devtools.build.lib.syntax;
+import static com.google.devtools.build.lib.syntax.Parser.ParsingMode.BUILD;
+import static com.google.devtools.build.lib.syntax.Parser.ParsingMode.PYTHON;
+import static com.google.devtools.build.lib.syntax.Parser.ParsingMode.SKYLARK;
+
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.base.Supplier;
@@ -66,8 +70,20 @@ class Parser {
}
}
+ /**
+ * ParsingMode is used to select which features the parser should accept.
+ */
+ public enum ParsingMode {
+ /** Used for parsing BUILD files */
+ BUILD,
+ /** Used for parsing .bzl files */
+ SKYLARK,
+ /** Used for syntax checking, ignoring all Python blocks (e.g. def, class, try) */
+ PYTHON,
+ }
+
private static final EnumSet<TokenKind> STATEMENT_TERMINATOR_SET =
- EnumSet.of(TokenKind.EOF, TokenKind.NEWLINE);
+ EnumSet.of(TokenKind.EOF, TokenKind.NEWLINE);
private static final EnumSet<TokenKind> LIST_TERMINATOR_SET =
EnumSet.of(TokenKind.EOF, TokenKind.RBRACKET, TokenKind.SEMI);
@@ -99,9 +115,7 @@ class Parser {
private final Lexer lexer;
private final EventHandler eventHandler;
private final List<Comment> comments;
- private final boolean parsePython;
- /** Whether advanced language constructs are allowed */
- private boolean skylarkMode = false;
+ private final ParsingMode parsingMode;
private static final Map<TokenKind, Operator> binaryOperators =
new ImmutableMap.Builder<TokenKind, Operator>()
@@ -147,11 +161,14 @@ class Parser {
private List<Path> includedFiles;
- private Parser(Lexer lexer, EventHandler eventHandler, CachingPackageLocator locator,
- boolean parsePython) {
+ private Parser(
+ Lexer lexer,
+ EventHandler eventHandler,
+ CachingPackageLocator locator,
+ ParsingMode parsingMode) {
this.lexer = lexer;
this.eventHandler = eventHandler;
- this.parsePython = parsePython;
+ this.parsingMode = parsingMode;
this.tokens = lexer.getTokens().iterator();
this.comments = new ArrayList<>();
this.locator = locator;
@@ -161,12 +178,7 @@ class Parser {
}
private Parser(Lexer lexer, EventHandler eventHandler, CachingPackageLocator locator) {
- this(lexer, eventHandler, locator, false /* parsePython */);
- }
-
- public Parser setSkylarkMode(boolean skylarkMode) {
- this.skylarkMode = skylarkMode;
- return this;
+ this(lexer, eventHandler, locator, BUILD);
}
/**
@@ -174,12 +186,12 @@ class Parser {
* encountered during parsing are reported via "reporter".
*/
public static ParseResult parseFile(
- Lexer lexer, EventHandler eventHandler, CachingPackageLocator locator,
- boolean parsePython) {
- Parser parser = new Parser(lexer, eventHandler, locator, parsePython);
+ Lexer lexer, EventHandler eventHandler, CachingPackageLocator locator, boolean parsePython) {
+ ParsingMode parsingMode = parsePython ? PYTHON : BUILD;
+ Parser parser = new Parser(lexer, eventHandler, locator, parsingMode);
List<Statement> statements = parser.parseFileInput();
- return new ParseResult(statements, parser.comments,
- parser.errorsCount > 0 || lexer.containsErrors());
+ return new ParseResult(
+ statements, parser.comments, parser.errorsCount > 0 || lexer.containsErrors());
}
/**
@@ -188,9 +200,11 @@ class Parser {
* that are not part of the core BUILD language.
*/
public static ParseResult parseFileForSkylark(
- Lexer lexer, EventHandler eventHandler, CachingPackageLocator locator,
+ Lexer lexer,
+ EventHandler eventHandler,
+ CachingPackageLocator locator,
ValidationEnvironment validationEnvironment) {
- Parser parser = new Parser(lexer, eventHandler, locator).setSkylarkMode(true);
+ Parser parser = new Parser(lexer, eventHandler, locator, SKYLARK);
List<Statement> statements = parser.parseFileInput();
boolean hasSemanticalErrors = false;
try {
@@ -328,7 +342,7 @@ class Parser {
TokenKind.TRY, TokenKind.WITH, TokenKind.WHILE, TokenKind.YIELD);
private void checkForbiddenKeywords(Token token) {
- if (parsePython || !FORBIDDEN_KEYWORDS.contains(token.kind)) {
+ if (parsingMode == PYTHON || !FORBIDDEN_KEYWORDS.contains(token.kind)) {
return;
}
String error;
@@ -415,7 +429,7 @@ class Parser {
final int start = token.left;
// parse **expr
if (token.kind == TokenKind.STAR_STAR) {
- if (!skylarkMode) {
+ if (parsingMode != SKYLARK) {
reportError(
lexer.createLocation(token.left, token.right),
"**kwargs arguments are not allowed in BUILD files");
@@ -426,7 +440,7 @@ class Parser {
}
// parse *expr
if (token.kind == TokenKind.STAR) {
- if (!skylarkMode) {
+ if (parsingMode != SKYLARK) {
reportError(
lexer.createLocation(token.left, token.right),
"*args arguments are not allowed in BUILD files");
@@ -617,8 +631,8 @@ class Parser {
// Insert call to the mocksubinclude function to get the dependencies right.
list.add(mocksubincludeExpression(labelName, file.toString(), location));
- Lexer lexer = new Lexer(inputSource, eventHandler, parsePython);
- Parser parser = new Parser(lexer, eventHandler, locator, parsePython);
+ Lexer lexer = new Lexer(inputSource, eventHandler, parsingMode == PYTHON);
+ Parser parser = new Parser(lexer, eventHandler, locator, parsingMode);
parser.addIncludedFiles(this.includedFiles);
list.addAll(parser.parseFileInput());
} catch (Label.SyntaxException e) {
@@ -1092,7 +1106,9 @@ class Parser {
Token identToken = token;
Ident ident = parseIdent();
- if (ident.getName().equals("include") && token.kind == TokenKind.LPAREN && !skylarkMode) {
+ if (ident.getName().equals("include")
+ && token.kind == TokenKind.LPAREN
+ && parsingMode == BUILD) {
expect(TokenKind.LPAREN);
if (token.kind == TokenKind.STRING) {
include((String) token.value, list, lexer.createLocation(start, token.right));
@@ -1366,15 +1382,15 @@ class Parser {
// stmt ::= simple_stmt
// | compound_stmt
private void parseStatement(List<Statement> list, boolean isTopLevel) {
- if (token.kind == TokenKind.DEF && skylarkMode) {
+ if (token.kind == TokenKind.DEF && parsingMode == SKYLARK) {
if (!isTopLevel) {
reportError(lexer.createLocation(token.left, token.right),
"nested functions are not allowed. Move the function to top-level");
}
parseFunctionDefStatement(list);
- } else if (token.kind == TokenKind.IF && skylarkMode) {
+ } else if (token.kind == TokenKind.IF && parsingMode == SKYLARK) {
list.add(parseIfStatement());
- } else if (token.kind == TokenKind.FOR && skylarkMode) {
+ } else if (token.kind == TokenKind.FOR && parsingMode == SKYLARK) {
if (isTopLevel) {
reportError(lexer.createLocation(token.left, token.right),
"for loops are not allowed on top-level. Put it into a function");
@@ -1405,7 +1421,7 @@ class Parser {
int start = token.left;
Token blockToken = token;
syncTo(EnumSet.of(TokenKind.COLON, TokenKind.EOF)); // skip over expression or name
- if (!parsePython) {
+ if (parsingMode == BUILD) {
reportError(lexer.createLocation(start, token.right), "syntax error at '"
+ blockToken + "': This Python-style construct is not supported. "
+ Constants.PARSER_ERROR_EXTENSION_NEEDED);