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