-
Notifications
You must be signed in to change notification settings - Fork 0
/
grammar.txt
101 lines (70 loc) · 2.62 KB
/
grammar.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# There is no place in the Lox grammer where either a statement _or_ an
# expression is allowed; the two syntaxes are disjoint (except for, possibly,
# in the initializer of a `for` statement).
# Updated grammer avoids ambiguity by enforcing precedence rules, by design.
# Each rule in the grammer below creates a new level of precedence—with earlier
# rules taking a lower leve of precedence compared to later rules. The `primary`
# rule (bottom) is the rule with highest precedence.
program -> declaration* EOF ;
#
# Declaration rules.
#
declaration -> classDeclaration
| funcDeclaration
| varDeclaration
| statement ;
classDeclaration -> "class" IDENTIFIER ( "<" IDENTIFIER )?
"{" function* "}" ;
funcDeclaration -> "fun" function ;
function -> IDENTIFIER "(" parameters? ")" block ;
parameters -> IDENTIFIER ( "," IDENTIFIER )* ;
varDeclaration -> "var" IDENTIFIER ( "=" expression )? ";" ;
#
# Statement rules.
#
statement -> exprStatement
| forStatement
| ifStatement
| printStatement
| returnStatement
| whileStatement
| block ;
exprStatement -> expression ";" ;
// Consists of optional initializer, optional condition, and optional increment.
forStatement -> "for" "(" ( varDeclaration | exprStatement | ";" )
expression? ";"
expression ")" statement ;
ifStatement -> "if" "(" expression ")" statement
( "else" statement)? ;
printStatement -> "print" expression ";" ;
returnStatement -> "return" expression? ";" ;
whileStatement -> "while" "(" expression ")" statement ;
block -> "{" declaration* "}"
#
# Expression rules.
#
# Non-recursive.
expression -> assignment ;
# Right-associative, right-recursive.
assignment -> ( call "." )? IDENTIFIER "=" assignment ;
| logic_or ;
logic_or -> logic_and ( "or" logic_and )* ;
logic_and -> equality ( "and" equality )* ;
# Left-associative, non-recursive.
equality -> comparison ( ("==" | "!=") comparison )* ;
# Left-associative, non-recursive.
comparison -> term ( (">" | ">=" | "<" | "<=") term )* ;
# Left-associative, non-recursive.
term -> factor ( ("-" | "+") factor )* ;
# Left-associative, non-recursive.
factor -> unary ( ("/" | "*") unary )* ;
# Right-associative, right-recursive.
unary -> ("!" | "-") unary | call
| primary;
call -> primary ( "(" arguments? ")" | "." IDENTIFIER )* ;
arguments -> expression ( "," expression )* ;
# Non-recursive (for literals and parenthesized expressions).
primary -> NUMBER | STRING | "true" | "false" | "nil"
| "(" expression ")"
| IDENTIFIER
| "super" "." IDENTIFIER;