blob: 7f5dfc811b028e38170ec3a79941007e489573e5 [file] [log] [blame]
Alan Donovan312d1a52017-10-02 10:10:28 -04001
Alan Donovane3deafe2018-10-23 11:05:09 -04002Grammar of Starlark
Alan Donovan312d1a52017-10-02 10:10:28 -04003==================
4
5File = {Statement | newline} eof .
6
Alessandro Arzilli678bafe2018-12-07 17:28:35 +01007Statement = DefStmt | IfStmt | ForStmt | WhileStmt | SimpleStmt .
Alan Donovan312d1a52017-10-02 10:10:28 -04008
9DefStmt = 'def' identifier '(' [Parameters [',']] ')' ':' Suite .
10
11Parameters = Parameter {',' Parameter}.
12
Alan Donovan52153852019-02-13 19:18:15 -050013Parameter = identifier | identifier '=' Test | '*' | '*' identifier | '**' identifier .
Alan Donovan312d1a52017-10-02 10:10:28 -040014
15IfStmt = 'if' Test ':' Suite {'elif' Test ':' Suite} ['else' ':' Suite] .
16
17ForStmt = 'for' LoopVariables 'in' Expression ':' Suite .
18
Alessandro Arzilli678bafe2018-12-07 17:28:35 +010019WhileStmt = 'while' Test ':' Suite .
20
Laurent Le Bruna0e5de72018-02-09 18:30:29 +010021Suite = [newline indent {Statement} outdent] | SimpleStmt .
Alan Donovan312d1a52017-10-02 10:10:28 -040022
23SimpleStmt = SmallStmt {';' SmallStmt} [';'] '\n' .
24# NOTE: '\n' optional at EOF
25
26SmallStmt = ReturnStmt
27 | BreakStmt | ContinueStmt | PassStmt
28 | AssignStmt
29 | ExprStmt
alandonovan6696fc32017-10-20 10:55:17 -040030 | LoadStmt
Alan Donovan312d1a52017-10-02 10:10:28 -040031 .
32
Laurent Le Bruna0e5de72018-02-09 18:30:29 +010033ReturnStmt = 'return' [Expression] .
Alan Donovan312d1a52017-10-02 10:10:28 -040034BreakStmt = 'break' .
35ContinueStmt = 'continue' .
36PassStmt = 'pass' .
Hittorp0a5e39a2018-08-09 15:02:30 +030037AssignStmt = Expression ('=' | '+=' | '-=' | '*=' | '/=' | '//=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>>=') Expression .
Alan Donovan312d1a52017-10-02 10:10:28 -040038ExprStmt = Expression .
39
alandonovan6696fc32017-10-20 10:55:17 -040040LoadStmt = 'load' '(' string {',' [identifier '='] string} [','] ')' .
41
Alan Donovan312d1a52017-10-02 10:10:28 -040042Test = LambdaExpr
43 | IfExpr
44 | PrimaryExpr
45 | UnaryExpr
46 | BinaryExpr
47 .
48
49LambdaExpr = 'lambda' [Parameters] ':' Test .
50
51IfExpr = Test 'if' Test 'else' Test .
52
53PrimaryExpr = Operand
54 | PrimaryExpr DotSuffix
55 | PrimaryExpr CallSuffix
56 | PrimaryExpr SliceSuffix
57 .
58
59Operand = identifier
60 | int | float | string
61 | ListExpr | ListComp
62 | DictExpr | DictComp
63 | '(' [Expression [',']] ')'
64 | ('-' | '+') PrimaryExpr
65 .
66
67DotSuffix = '.' identifier .
68CallSuffix = '(' [Arguments [',']] ')' .
69SliceSuffix = '[' [Expression] [':' Test [':' Test]] ']' .
70
71Arguments = Argument {',' Argument} .
alandonovanae01c0c2018-03-06 16:35:26 -050072Argument = Test | identifier '=' Test | '*' Test | '**' Test .
Alan Donovan312d1a52017-10-02 10:10:28 -040073
74ListExpr = '[' [Expression [',']] ']' .
75ListComp = '[' Test {CompClause} ']'.
76
77DictExpr = '{' [Entries [',']] '}' .
78DictComp = '{' Entry {CompClause} '}' .
79Entries = Entry {',' Entry} .
80Entry = Test ':' Test .
81
82CompClause = 'for' LoopVariables 'in' Test | 'if' Test .
83
84UnaryExpr = 'not' Test .
85
86BinaryExpr = Test {Binop Test} .
87
88Binop = 'or'
89 | 'and'
90 | '==' | '!=' | '<' | '>' | '<=' | '>=' | 'in' | 'not' 'in'
91 | '|'
Hittorp0a5e39a2018-08-09 15:02:30 +030092 | '^'
Alan Donovan312d1a52017-10-02 10:10:28 -040093 | '&'
94 | '-' | '+'
95 | '*' | '%' | '/' | '//'
96 .
97
98Expression = Test {',' Test} .
99# NOTE: trailing comma permitted only when within [...] or (...).
100
101LoopVariables = PrimaryExpr {',' PrimaryExpr} .
102
103
104# Notation (similar to Go spec):
105- lowercase and 'quoted' items are lexical tokens.
106- Capitalized names denote grammar productions.
107- (...) implies grouping
108- x | y means either x or y.
109- [x] means x is optional
110- {x} means x is repeated zero or more times
111- The end of each declaration is marked with a period.
112
113# Tokens
114- spaces: newline, eof, indent, outdent.
115- identifier.
116- literals: string, int, float.
117- plus all quoted tokens such as '+=', 'return'.
118
119# Notes:
Alan Donovan312d1a52017-10-02 10:10:28 -0400120- Ambiguity is resolved using operator precedence.
121- The grammar does not enforce the legal order of params and args,
122 nor that the first compclause must be a 'for'.
123
124TODO:
125- explain how the lexer generates indent, outdent, and newline tokens.
126- why is unary NOT separated from unary - and +?
127- the grammar is (mostly) in LL(1) style so, for example,
128 dot expressions are formed suffixes, not complete expressions,
129 which makes the spec harder to read. Reorganize into non-LL(1) form?