Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Unified Diff: tools/gn/parser.cc

Issue 1015063003: tools/gn: add "gn help grammar" with formal grammar (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/gn/parser.h ('k') | tools/gn/parser_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/gn/parser.cc
diff --git a/tools/gn/parser.cc b/tools/gn/parser.cc
index 2a037fb24fa3a8275d3a05ae8327da902fbabe3c..88907035ade0f4c5725de2e16f6c18647f94dbbe 100644
--- a/tools/gn/parser.cc
+++ b/tools/gn/parser.cc
@@ -9,14 +9,106 @@
#include "tools/gn/operators.h"
#include "tools/gn/token.h"
-// grammar:
-//
-// file := (statement)*
-// statement := block | if | assignment
-// block := '{' statement* '}'
-// if := 'if' '(' expr ')' statement [ else ]
-// else := 'else' (if | statement)*
-// assignment := ident {'=' | '+=' | '-='} expr
+const char kSyntax_Help[] =
+ "GN build language syntax\n"
+ "\n"
+ " This help topic defines the syntax of the GN build language.\n"
+ "\n"
+ "Tokens\n"
+ "\n"
+ " GN build files are read as sequences of tokens. While splitting the\n"
+ " file into tokens, the next token is the longest sequence of characters\n"
+ " that form a valid token.\n"
+ "\n"
+ "White space and comments\n"
+ "\n"
+ " White space is comprised of spaces (U+0020), horizontal tabs (U+0009),\n"
+ " carriage returns (U+000D), and newlines (U+000A).\n"
+ "\n"
+ " Comments start at the character \"#\" and stop at the end of the line.\n"
Dirk Pranke 2015/03/26 01:29:47 If you wanted to be picky, how is the "end of the
+ "\n"
+ " White space and comments are ignored except that they may separate\n"
+ " tokens that would otherwise combine into a single token.\n"
+ "\n"
+ "Identifiers\n"
+ "\n"
+ " Identifiers name variables and functions.\n"
+ "\n"
+ " identifier = letter { letter | digit } .\n"
+ " letter = \"A\" ... \"Z\" | \"a\" ... \"z\" | \"_\" .\n"
+ " digit = \"0\" ... \"9\" .\n"
+ "\n"
+ "Keywords\n"
+ "\n"
+ " The following keywords are reserved and may not be used as\n"
+ " identifiers:\n"
+ "\n"
+ " else false if true\n"
+ "\n"
+ "Integer literals\n"
+ "\n"
+ " An integer literal represents a decimal integer value.\n"
+ "\n"
+ " integer = [ \"-\" ] digit { digit } .\n"
+ "\n"
+ "String literals\n"
+ "\n"
+ " A string literal represents a string value consisting of the quoted\n"
+ " characters with possible escape sequences and variable expansions.\n"
+ "\n"
+ " string = `\"` { char | escape | expansion } `\"` .\n"
+ " escape = `\\` ( \"$\" | `\"` | char ) .\n"
+ " expansion = \"$\" ( identifier | \"{\" identifier \"}\" ) .\n"
+ " char = /* any character except \"$\", `\"`, or newline */ .\n"
+ "\n"
+ " After a backslash, certain sequences represent special characters:\n"
+ "\n"
+ " \\\" U+0022 quotation mark\n"
+ " \\$ U+0024 dollar sign\n"
+ " \\\\ U+005c backslash\n"
+ "\n"
+ " All other backslashes represent themselves.\n"
+ "\n"
+ "Punctuation\n"
+ "\n"
+ " The following character sequences represent punctuation:\n"
+ "\n"
+ " + += == != ( )\n"
+ " - -= < <= [ ]\n"
+ " ! = > >= { }\n"
+ " && || . ,\n"
+ "\n"
+ "Grammar\n"
+ "\n"
+ " The input tokens form a syntax tree following a context-free grammar:\n"
+ "\n"
+ " File = StatementList .\n"
+ "\n"
+ " Statement = Assignment | Call | Condition .\n"
+ " Assignment = identifier AssignOp Expr .\n"
+ " Call = identifier \"(\" ExprList \")\" [ Block ] .\n"
+ " Condition = \"if\" \"(\" Expr \")\" Block\n"
+ " [ \"else\" ( Condition | Block ) ] .\n"
+ " Block = \"{\" StatementList \"}\" .\n"
+ " StatementList = { Statement } .\n"
+ "\n"
+ " Expr = UnaryExpr | Expr BinaryOp Expr .\n"
+ " UnaryExpr = PrimaryExpr | UnaryOp UnaryExpr .\n"
+ " PrimaryExpr = identifier | integer | string | Call\n"
+ " | identifier \"[\" Expr \"]\"\n"
+ " | identifier \".\" identifier\n"
+ " | \"(\" Expr \")\" | \"[\" ExprList \"] .\n"
+ " ExprList = [ Expr { \",\" Expr } [ \",\" ] ] .\n"
+ "\n"
+ " AssignOp = \"=\" | \"+=\" | \"-=\" .\n"
+ " UnaryOp = \"!\" .\n"
+ " BinaryOp = \"+\" | \"-\" // highest priority\n"
+ " | \"<\" | \"<=\" | \">\" | \">=\"\n"
+ " | \"==\" | \"!=\"\n"
+ " | \"&&\"\n"
+ " | \"||\" . // lowest priority\n"
+ "\n"
+ " All binary operators are left-associative.\n";
enum Precedence {
PRECEDENCE_ASSIGNMENT = 1, // Lowest precedence.
@@ -257,7 +349,7 @@ scoped_ptr<ParseNode> Parser::Not(Token token) {
}
scoped_ptr<ParseNode> Parser::List(Token node) {
- scoped_ptr<ParseNode> list(ParseList(node, Token::RIGHT_BRACKET, true));
+ scoped_ptr<ParseNode> list(ParseList(node, Token::RIGHT_BRACKET));
if (!has_error() && !at_end())
Consume(Token::RIGHT_BRACKET, "Expected ']'");
return list.Pass();
@@ -294,7 +386,7 @@ scoped_ptr<ParseNode> Parser::IdentifierOrCall(scoped_ptr<ParseNode> left,
if (Match(Token::RIGHT_PAREN)) {
// Nothing, just an empty call.
} else {
- list = ParseList(start_token, Token::RIGHT_PAREN, false);
+ list = ParseList(start_token, Token::RIGHT_PAREN);
if (has_error())
return scoped_ptr<ParseNode>();
Consume(Token::RIGHT_PAREN, "Expected ')' after call");
@@ -378,8 +470,7 @@ scoped_ptr<ParseNode> Parser::DotOperator(scoped_ptr<ParseNode> left,
// Does not Consume the start or end token.
scoped_ptr<ListNode> Parser::ParseList(Token start_token,
- Token::Type stop_before,
- bool allow_trailing_comma) {
+ Token::Type stop_before) {
scoped_ptr<ListNode> list(new ListNode);
list->set_begin_token(start_token);
bool just_got_comma = false;
@@ -408,15 +499,11 @@ scoped_ptr<ListNode> Parser::ParseList(Token start_token,
if (list->contents().back()->AsBlockComment()) {
// If there was a comment inside the list, we don't need a comma to the
// next item, so pretend we got one, if we're expecting one.
- just_got_comma = allow_trailing_comma;
+ just_got_comma = true;
} else {
just_got_comma = Match(Token::COMMA);
}
}
- if (just_got_comma && !allow_trailing_comma) {
- *err_ = Err(cur_token(), "Trailing comma");
- return scoped_ptr<ListNode>();
- }
list->set_end(make_scoped_ptr(new EndNode(cur_token())));
return list.Pass();
}
« no previous file with comments | « tools/gn/parser.h ('k') | tools/gn/parser_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698