Index: tools/gn/parser.cc |
diff --git a/tools/gn/parser.cc b/tools/gn/parser.cc |
index 2a037fb24fa3a8275d3a05ae8327da902fbabe3c..1fa432e3a8061704d7cac1ea900948327140f582 100644 |
--- a/tools/gn/parser.cc |
+++ b/tools/gn/parser.cc |
@@ -9,14 +9,105 @@ |
#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 kGrammar_Help[] = |
+ "GN build language grammar\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 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 { |
PRECEDENCE_ASSIGNMENT = 1, // Lowest precedence. |