github.com/k14s/starlark-go@v0.0.0-20200720175618-3a5c849cc368/syntax/grammar.txt (about) 1 2 Grammar of Starlark 3 ================== 4 5 File = {Statement | newline} eof . 6 7 Statement = DefStmt | IfStmt | ForStmt | WhileStmt | SimpleStmt . 8 9 DefStmt = 'def' identifier '(' [Parameters [',']] ')' ':' Suite . 10 11 Parameters = Parameter {',' Parameter}. 12 13 Parameter = identifier | identifier '=' Test | '*' | '*' identifier | '**' identifier . 14 15 IfStmt = 'if' Test ':' Suite {'elif' Test ':' Suite} ['else' ':' Suite] . 16 17 ForStmt = 'for' LoopVariables 'in' Expression ':' Suite . 18 19 WhileStmt = 'while' Test ':' Suite . 20 21 Suite = [newline indent {Statement} outdent] | SimpleStmt . 22 23 SimpleStmt = SmallStmt {';' SmallStmt} [';'] '\n' . 24 # NOTE: '\n' optional at EOF 25 26 SmallStmt = ReturnStmt 27 | BreakStmt | ContinueStmt | PassStmt 28 | AssignStmt 29 | ExprStmt 30 | LoadStmt 31 . 32 33 ReturnStmt = 'return' [Expression] . 34 BreakStmt = 'break' . 35 ContinueStmt = 'continue' . 36 PassStmt = 'pass' . 37 AssignStmt = Expression ('=' | '+=' | '-=' | '*=' | '/=' | '//=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>>=') Expression . 38 ExprStmt = Expression . 39 40 LoadStmt = 'load' '(' string {',' [identifier '='] string} [','] ')' . 41 42 Test = LambdaExpr 43 | IfExpr 44 | PrimaryExpr 45 | UnaryExpr 46 | BinaryExpr 47 . 48 49 LambdaExpr = 'lambda' [Parameters] ':' Test . 50 51 IfExpr = Test 'if' Test 'else' Test . 52 53 PrimaryExpr = Operand 54 | PrimaryExpr DotSuffix 55 | PrimaryExpr CallSuffix 56 | PrimaryExpr SliceSuffix 57 . 58 59 Operand = identifier 60 | int | float | string 61 | ListExpr | ListComp 62 | DictExpr | DictComp 63 | '(' [Expression [',']] ')' 64 | ('-' | '+') PrimaryExpr 65 . 66 67 DotSuffix = '.' identifier . 68 CallSuffix = '(' [Arguments [',']] ')' . 69 SliceSuffix = '[' [Expression] [':' Test [':' Test]] ']' . 70 71 # A CallSuffix does not allow a trailing comma 72 # if the last argument is '*' Test or '**' Test. 73 74 Arguments = Argument {',' Argument} . 75 Argument = Test | identifier '=' Test | '*' Test | '**' Test . 76 77 ListExpr = '[' [Expression [',']] ']' . 78 ListComp = '[' Test {CompClause} ']'. 79 80 DictExpr = '{' [Entries [',']] '}' . 81 DictComp = '{' Entry {CompClause} '}' . 82 Entries = Entry {',' Entry} . 83 Entry = Test ':' Test . 84 85 CompClause = 'for' LoopVariables 'in' Test | 'if' Test . 86 87 UnaryExpr = 'not' Test . 88 89 BinaryExpr = Test {Binop Test} . 90 91 Binop = 'or' 92 | 'and' 93 | '==' | '!=' | '<' | '>' | '<=' | '>=' | 'in' | 'not' 'in' 94 | '|' 95 | '^' 96 | '&' 97 | '-' | '+' 98 | '*' | '%' | '/' | '//' 99 . 100 101 Expression = Test {',' Test} . 102 # NOTE: trailing comma permitted only when within [...] or (...). 103 104 LoopVariables = PrimaryExpr {',' PrimaryExpr} . 105 106 107 # Notation (similar to Go spec): 108 - lowercase and 'quoted' items are lexical tokens. 109 - Capitalized names denote grammar productions. 110 - (...) implies grouping 111 - x | y means either x or y. 112 - [x] means x is optional 113 - {x} means x is repeated zero or more times 114 - The end of each declaration is marked with a period. 115 116 # Tokens 117 - spaces: newline, eof, indent, outdent. 118 - identifier. 119 - literals: string, int, float. 120 - plus all quoted tokens such as '+=', 'return'. 121 122 # Notes: 123 - Ambiguity is resolved using operator precedence. 124 - The grammar does not enforce the legal order of params and args, 125 nor that the first compclause must be a 'for'. 126 127 TODO: 128 - explain how the lexer generates indent, outdent, and newline tokens. 129 - why is unary NOT separated from unary - and +? 130 - the grammar is (mostly) in LL(1) style so, for example, 131 dot expressions are formed suffixes, not complete expressions, 132 which makes the spec harder to read. Reorganize into non-LL(1) form?