Index: tools/gn/parser.cc |
diff --git a/tools/gn/parser.cc b/tools/gn/parser.cc |
index 5fe9506d4528bd9cbd94fefd69b9a591d634788d..18e1ea12a50960013b0dc14b6b26c69783115a2f 100644 |
--- a/tools/gn/parser.cc |
+++ b/tools/gn/parser.cc |
@@ -13,210 +13,208 @@ |
#include "tools/gn/token.h" |
const char kGrammar_Help[] = |
- "Language and grammar for GN build files\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" |
- " Leading zeros and negative zero are disallowed.\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" |
- " BracketExpansion = \"{\" ( identifier | ArrayAccess | ScopeAccess " |
- ") \"}\" .\n" |
- " Hex = \"0x\" [0-9A-Fa-f][0-9A-Fa-f]\n" |
- " expansion = \"$\" ( identifier | BracketExpansion | Hex ) .\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" |
- " To insert an arbitrary byte value, use $0xFF. For example, to\n" |
- " insert a newline character: \"Line one$0x0ALine two\".\n" |
- "\n" |
- " An expansion will evaluate the variable following the '$' and insert\n" |
- " a stringified version of it into the result. For example, to concat\n" |
- " two path components with a slash separating them:\n" |
- " \"$var_one/$var_two\"\n" |
- " Use the \"${var_one}\" format to be explicitly deliniate the variable\n" |
- " for otherwise-ambiguous cases.\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" |
- " LValue = identifier | ArrayAccess | ScopeAccess .\n" |
- " Assignment = LValue AssignOp Expr .\n" |
- " Call = identifier \"(\" [ ExprList ] \")\" [ Block ] .\n" |
- " Condition = \"if\" \"(\" Expr \")\" Block\n" |
- " [ \"else\" ( Condition | Block ) ] .\n" |
- " Block = \"{\" StatementList \"}\" .\n" |
- " StatementList = { Statement } .\n" |
- "\n" |
- " ArrayAccess = identifier \"[\" Expr \"]\" .\n" |
- " ScopeAccess = identifier \".\" identifier .\n" |
- " Expr = UnaryExpr | Expr BinaryOp Expr .\n" |
- " UnaryExpr = PrimaryExpr | UnaryOp UnaryExpr .\n" |
- " PrimaryExpr = identifier | integer | string | Call\n" |
- " | ArrayAccess | ScopeAccess | Block\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" |
- "\n" |
- "Types\n" |
- "\n" |
- " The GN language is dynamically typed. The following types are used:\n" |
- "\n" |
- " - Boolean: Uses the keywords \"true\" and \"false\". There is no\n" |
- " implicit conversion between booleans and integers.\n" |
- "\n" |
- " - Integers: All numbers in GN are signed 64-bit integers.\n" |
- "\n" |
- " - Strings: Strings are 8-bit with no enforced encoding. When a string\n" |
- " is used to interact with other systems with particular encodings\n" |
- " (like the Windows and Mac filesystems) it is assumed to be UTF-8.\n" |
- " See \"String literals\" above for more.\n" |
- "\n" |
- " - Lists: Lists are arbitrary-length ordered lists of values. See\n" |
- " \"Lists\" below for more.\n" |
- "\n" |
- " - Scopes: Scopes are like dictionaries that use variable names for\n" |
- " keys. See \"Scopes\" below for more.\n" |
- "\n" |
- "Lists\n" |
- "\n" |
- " Lists are created with [] and using commas to separate items:\n" |
- "\n" |
- " mylist = [ 0, 1, 2, \"some string\" ]\n" |
- "\n" |
- " A comma after the last item is optional. Lists are dereferenced using\n" |
- " 0-based indexing:\n" |
- "\n" |
- " mylist[0] += 1\n" |
- " var = mylist[2]\n" |
- "\n" |
- " Lists can be concatenated using the '+' and '+=' operators. Bare\n" |
- " values can not be concatenated with lists, to add a single item,\n" |
- " it must be put into a list of length one.\n" |
- "\n" |
- " Items can be removed from lists using the '-' and '-=' operators.\n" |
- " This will remove all occurrences of every item in the right-hand list\n" |
- " from the left-hand list. It is an error to remove an item not in the\n" |
- " list. This is to prevent common typos and to detect dead code that\n" |
- " is removing things that no longer apply.\n" |
- "\n" |
- " It is an error to use '=' to replace a nonempty list with another\n" |
- " nonempty list. This is to prevent accidentally overwriting data\n" |
- " when in most cases '+=' was intended. To overwrite a list on purpose,\n" |
- " first assign it to the empty list:\n" |
- "\n" |
- " mylist = []\n" |
- " mylist = otherlist\n" |
- "\n" |
- " When assigning to a list named 'sources' using '=' or '+=', list\n" |
- " items may be automatically filtered out.\n" |
- " See \"gn help set_sources_assignment_filter\" for more.\n" |
- "\n" |
- "Scopes\n" |
- "\n" |
- " All execution happens in the context of a scope which holds the\n" |
- " current state (like variables). With the exception of loops and\n" |
- " conditions, '{' introduces a new scope that has a parent reference to\n" |
- " the old scope.\n" |
- "\n" |
- " Variable reads recursively search all nested scopes until the\n" |
- " variable is found or there are no more scopes. Variable writes always\n" |
- " go into the current scope. This means that after the closing '}'\n" |
- " (again excepting loops and conditions), all local variables will be\n" |
- " restored to the previous values. This also means that \"foo = foo\"\n" |
- " can do useful work by copying a variable into the current scope that\n" |
- " was defined in a containing scope.\n" |
- "\n" |
- " Scopes can also be assigned to variables. Such scopes can be created\n" |
- " by functions like exec_script, when invoking a template (the template\n" |
- " code refers to the variables set by the invoking code by the\n" |
- " implicitly-created \"invoker\" scope), or explicitly like:\n" |
- "\n" |
- " empty_scope = {}\n" |
- " myvalues = {\n" |
- " foo = 21\n" |
- " bar = \"something\"\n" |
- " }\n" |
- "\n" |
- " Inside such a scope definition can be any GN code including\n" |
- " conditionals and function calls. After the close of the scope, it will\n" |
- " contain all variables explicitly set by the code contained inside it.\n" |
- " After this, the values can be read, modified, or added to:\n" |
- "\n" |
- " myvalues.foo += 2\n" |
- " empty_scope.new_thing = [ 1, 2, 3 ]\n"; |
+ R"*(Language and grammar for GN build files |
+ |
+Tokens |
+ |
+ GN build files are read as sequences of tokens. While splitting the file |
+ into tokens, the next token is the longest sequence of characters that form a |
+ valid token. |
+ |
+White space and comments |
+ |
+ White space is comprised of spaces (U+0020), horizontal tabs (U+0009), |
+ carriage returns (U+000D), and newlines (U+000A). |
+ |
+ Comments start at the character "#" and stop at the next newline. |
+ |
+ White space and comments are ignored except that they may separate tokens |
+ that would otherwise combine into a single token. |
+ |
+Identifiers |
+ |
+ Identifiers name variables and functions. |
+ |
+ identifier = letter { letter | digit } . |
+ letter = "A" ... "Z" | "a" ... "z" | "_" . |
+ digit = "0" ... "9" . |
+ |
+Keywords |
+ |
+ The following keywords are reserved and may not be used as identifiers: |
+ |
+ else false if true |
+ |
+Integer literals |
+ |
+ An integer literal represents a decimal integer value. |
+ |
+ integer = [ "-" ] digit { digit } . |
+ |
+ Leading zeros and negative zero are disallowed. |
+ |
+String literals |
+ |
+ A string literal represents a string value consisting of the quoted |
+ characters with possible escape sequences and variable expansions. |
+ |
+ string = `"` { char | escape | expansion } `"` . |
+ escape = `\` ( "$" | `"` | char ) . |
+ BracketExpansion = "{" ( identifier | ArrayAccess | ScopeAccess " |
+ ") "}" . |
+ Hex = "0x" [0-9A-Fa-f][0-9A-Fa-f] |
+ expansion = "$" ( identifier | BracketExpansion | Hex ) . |
+ char = /* any character except "$", `"`, or newline " |
+ "*/ . |
+ |
+ After a backslash, certain sequences represent special characters: |
+ |
+ \" U+0022 quotation mark |
+ \$ U+0024 dollar sign |
+ \\ U+005C backslash |
+ |
+ All other backslashes represent themselves. |
+ |
+ To insert an arbitrary byte value, use $0xFF. For example, to insert a |
+ newline character: "Line one$0x0ALine two". |
+ |
+ An expansion will evaluate the variable following the '$' and insert a |
+ stringified version of it into the result. For example, to concat two path |
+ components with a slash separating them: |
+ "$var_one/$var_two" |
+ Use the "${var_one}" format to be explicitly deliniate the variable for |
+ otherwise-ambiguous cases. |
+ |
+Punctuation |
+ |
+ The following character sequences represent punctuation: |
+ |
+ + += == != ( ) |
+ - -= < <= [ ] |
+ ! = > >= { } |
+ && || . , |
+ |
+Grammar |
+ |
+ The input tokens form a syntax tree following a context-free grammar: |
+ |
+ File = StatementList . |
+ |
+ Statement = Assignment | Call | Condition . |
+ LValue = identifier | ArrayAccess | ScopeAccess . |
+ Assignment = LValue AssignOp Expr . |
+ Call = identifier "(" [ ExprList ] ")" [ Block ] . |
+ Condition = "if" "(" Expr ")" Block |
+ [ "else" ( Condition | Block ) ] . |
+ Block = "{" StatementList "}" . |
+ StatementList = { Statement } . |
+ |
+ ArrayAccess = identifier "[" Expr "]" . |
+ ScopeAccess = identifier "." identifier . |
+ Expr = UnaryExpr | Expr BinaryOp Expr . |
+ UnaryExpr = PrimaryExpr | UnaryOp UnaryExpr . |
+ PrimaryExpr = identifier | integer | string | Call |
+ | ArrayAccess | ScopeAccess | Block |
+ | "(" Expr ")" |
+ | "[" [ ExprList [ "," ] ] "]" . |
+ ExprList = Expr { "," Expr } . |
+ |
+ AssignOp = "=" | "+=" | "-=" . |
+ UnaryOp = "!" . |
+ BinaryOp = "+" | "-" // highest priority |
+ | "<" | "<=" | ">" | ">=" |
+ | "==" | "!=" |
+ | "&&" |
+ | "||" . // lowest priority |
+ |
+ All binary operators are left-associative. |
+ |
+Types |
+ |
+ The GN language is dynamically typed. The following types are used: |
+ |
+ - Boolean: Uses the keywords "true" and "false". There is no implicit |
+ conversion between booleans and integers. |
+ |
+ - Integers: All numbers in GN are signed 64-bit integers. |
+ |
+ - Strings: Strings are 8-bit with no enforced encoding. When a string is |
+ used to interact with other systems with particular encodings (like the |
+ Windows and Mac filesystems) it is assumed to be UTF-8. See "String |
+ literals" above for more. |
+ |
+ - Lists: Lists are arbitrary-length ordered lists of values. See "Lists" |
+ below for more. |
+ |
+ - Scopes: Scopes are like dictionaries that use variable names for keys. See |
+ "Scopes" below for more. |
+ |
+Lists |
+ |
+ Lists are created with [] and using commas to separate items: |
+ |
+ mylist = [ 0, 1, 2, "some string" ] |
+ |
+ A comma after the last item is optional. Lists are dereferenced using 0-based |
+ indexing: |
+ |
+ mylist[0] += 1 |
+ var = mylist[2] |
+ |
+ Lists can be concatenated using the '+' and '+=' operators. Bare values can |
+ not be concatenated with lists, to add a single item, it must be put into a |
+ list of length one. |
+ |
+ Items can be removed from lists using the '-' and '-=' operators. This will |
+ remove all occurrences of every item in the right-hand list from the |
+ left-hand list. It is an error to remove an item not in the list. This is to |
+ prevent common typos and to detect dead code that is removing things that no |
+ longer apply. |
+ |
+ It is an error to use '=' to replace a nonempty list with another nonempty |
+ list. This is to prevent accidentally overwriting data when in most cases |
+ '+=' was intended. To overwrite a list on purpose, first assign it to the |
+ empty list: |
+ |
+ mylist = [] |
+ mylist = otherlist |
+ |
+ When assigning to a list named 'sources' using '=' or '+=', list items may be |
+ automatically filtered out. See "gn help set_sources_assignment_filter" for |
+ more. |
+ |
+Scopes |
+ |
+ All execution happens in the context of a scope which holds the current state |
+ (like variables). With the exception of loops and conditions, '{' introduces |
+ a new scope that has a parent reference to the old scope. |
+ |
+ Variable reads recursively search all nested scopes until the variable is |
+ found or there are no more scopes. Variable writes always go into the current |
+ scope. This means that after the closing '}' (again excepting loops and |
+ conditions), all local variables will be restored to the previous values. |
+ This also means that "foo = foo" can do useful work by copying a variable |
+ into the current scope that was defined in a containing scope. |
+ |
+ Scopes can also be assigned to variables. Such scopes can be created by |
+ functions like exec_script, when invoking a template (the template code |
+ refers to the variables set by the invoking code by the implicitly-created |
+ "invoker" scope), or explicitly like: |
+ |
+ empty_scope = {} |
+ myvalues = { |
+ foo = 21 |
+ bar = "something" |
+ } |
+ |
+ Inside such a scope definition can be any GN code including conditionals and |
+ function calls. After the close of the scope, it will contain all variables |
+ explicitly set by the code contained inside it. After this, the values can be |
+ read, modified, or added to: |
+ |
+ myvalues.foo += 2 |
+ empty_scope.new_thing = [ 1, 2, 3 ] |
+)*"; |
enum Precedence { |
PRECEDENCE_ASSIGNMENT = 1, // Lowest precedence. |