Commit 922fc336 authored by mdempsky's avatar mdempsky Committed by Commit bot

tools/gn: add "gn help grammar" with formal grammar

BUG=466847

Review URL: https://codereview.chromium.org/1015063003

Cr-Commit-Position: refs/heads/master@{#322314}
parent 255e39ce
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "tools/gn/functions.h" #include "tools/gn/functions.h"
#include "tools/gn/input_conversion.h" #include "tools/gn/input_conversion.h"
#include "tools/gn/label_pattern.h" #include "tools/gn/label_pattern.h"
#include "tools/gn/parser.h"
#include "tools/gn/setup.h" #include "tools/gn/setup.h"
#include "tools/gn/standard_out.h" #include "tools/gn/standard_out.h"
#include "tools/gn/substitution_writer.h" #include "tools/gn/substitution_writer.h"
...@@ -58,6 +59,7 @@ void PrintToplevelHelp() { ...@@ -58,6 +59,7 @@ void PrintToplevelHelp() {
OutputString("\nOther help topics:\n"); OutputString("\nOther help topics:\n");
PrintShortHelp("buildargs: How build arguments work."); PrintShortHelp("buildargs: How build arguments work.");
PrintShortHelp("dotfile: Info about the toplevel .gn file."); PrintShortHelp("dotfile: Info about the toplevel .gn file.");
PrintShortHelp("grammar: Formal grammar for GN build files.");
PrintShortHelp("label_pattern: Matching more than one label."); PrintShortHelp("label_pattern: Matching more than one label.");
PrintShortHelp( PrintShortHelp(
"input_conversion: Processing input from exec_script and read_file."); "input_conversion: Processing input from exec_script and read_file.");
...@@ -169,6 +171,10 @@ int RunHelp(const std::vector<std::string>& args) { ...@@ -169,6 +171,10 @@ int RunHelp(const std::vector<std::string>& args) {
PrintLongHelp(kDotfile_Help); PrintLongHelp(kDotfile_Help);
return 0; return 0;
} }
if (what == "grammar") {
PrintLongHelp(kGrammar_Help);
return 0;
}
if (what == "input_conversion") { if (what == "input_conversion") {
PrintLongHelp(kInputConversion_Help); PrintLongHelp(kInputConversion_Help);
return 0; return 0;
......
...@@ -9,14 +9,105 @@ ...@@ -9,14 +9,105 @@
#include "tools/gn/operators.h" #include "tools/gn/operators.h"
#include "tools/gn/token.h" #include "tools/gn/token.h"
// grammar: const char kGrammar_Help[] =
// "GN build language grammar\n"
// file := (statement)* "\n"
// statement := block | if | assignment "Tokens\n"
// block := '{' statement* '}' "\n"
// if := 'if' '(' expr ')' statement [ else ] " GN build files are read as sequences of tokens. While splitting the\n"
// else := 'else' (if | statement)* " file into tokens, the next token is the longest sequence of characters\n"
// assignment := ident {'=' | '+=' | '-='} expr " 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 next newline.\n"
"\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 \")\"\n"
" | \"[\" [ 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 { enum Precedence {
PRECEDENCE_ASSIGNMENT = 1, // Lowest precedence. PRECEDENCE_ASSIGNMENT = 1, // Lowest precedence.
......
...@@ -19,6 +19,8 @@ typedef scoped_ptr<ParseNode> (Parser::*PrefixFunc)(Token token); ...@@ -19,6 +19,8 @@ typedef scoped_ptr<ParseNode> (Parser::*PrefixFunc)(Token token);
typedef scoped_ptr<ParseNode> (Parser::*InfixFunc)(scoped_ptr<ParseNode> left, typedef scoped_ptr<ParseNode> (Parser::*InfixFunc)(scoped_ptr<ParseNode> left,
Token token); Token token);
extern const char kGrammar_Help[];
struct ParserHelper { struct ParserHelper {
PrefixFunc prefix; PrefixFunc prefix;
InfixFunc infix; InfixFunc infix;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment