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
|
module Numbers
imports Base
lexical sorts
lexical syntax
= [0-9]+
lexical restrictions
// Ensure greedy matching for lexicals
IntConst -/- [0-9]
context-free syntax
.Int = IntConst
. = [- [Exp]]
. = [[Exp] * [Exp]] {left}
. = [[Exp] / [Exp]] {left}
.Plus = [[Exp] + [Exp]] {left}
.Minus = [[Exp] - [Exp]] {left}
.Eq = [[Exp] = [Exp]] {non-assoc}
.Neq = [[Exp] <> [Exp]] {non-assoc}
.Gt = [[Exp] > [Exp]] {non-assoc}
.Lt = [[Exp] < [Exp]] {non-assoc}
.Geq = [[Exp] >= [Exp]] {non-assoc}
.Leq = [[Exp] <= [Exp]] {non-assoc}
.And = [[Exp] & [Exp]] {left}
. = [[Exp] | [Exp]] {left}
//Exp = [([Exp])] {bracket, avoid}
context-free priorities
// Precedence of operators: Unary minus has the highest
// precedence. The operators *, / have the next highest
// (tightest binding) precedence, followed by +, -, then
// by =, <>, >, <, >=, <=, then by &, then by |.
// Associativity of operators: The operators *, /, +, -
// are all left associative. The comparison operators do
// not associate, so a = b = c is not a legal expression,
// a = (b = c) is legal.
{Exp.Uminus}
> {left :
Exp.Times
Exp.Divide}
> {left :
Exp.Plus
Exp.Minus}
> {non-assoc :
Exp.Eq
Exp.Neq
Exp.Gt
Exp.Lt
Exp.Geq
Exp.Leq}
> Exp.And
> Exp.Or
|