Chromium Code Reviews| Index: tools/gn/parser.cc |
| diff --git a/tools/gn/parser.cc b/tools/gn/parser.cc |
| index 5fe9506d4528bd9cbd94fefd69b9a591d634788d..3dbdb20628d2f6eddca5166b16b4e2a69725ba89 100644 |
| --- a/tools/gn/parser.cc |
| +++ b/tools/gn/parser.cc |
| @@ -13,210 +13,207 @@ |
| #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 ])*"; |
|
scottmg
2016/11/08 01:01:46
here
|
| enum Precedence { |
| PRECEDENCE_ASSIGNMENT = 1, // Lowest precedence. |