| 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.
|
|
|