-
Notifications
You must be signed in to change notification settings - Fork 303
/
Copy pathlevel10.grammar
118 lines (97 loc) · 2.98 KB
/
level10.grammar
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
@top Program { eol* (Command eol+)* Command? }
Command {
Assign | AssignList | Ask | Clear |Print | Turtle | Sleep | Add | Remove| If | Else | Repeat | For | ErrorInvalid
}
@local tokens {
singleQuoteStringEnd { "'" | "\n" }
@else singleQuoteStringContent
}
@skip {} {
singleQuotedString { "'" (singleQuoteStringContent)* singleQuoteStringEnd }
}
@local tokens {
doubleQuoteStringEnd { '"' | "\n" }
@else doubleQuoteStringContent
}
@skip {} {
doubleQuotedString { '"' (doubleQuoteStringContent)* doubleQuoteStringEnd }
}
String { doubleQuotedString | singleQuotedString }
Print { print ( String | ListAccess | Expression )+ }
Ask { Text (is+ | Op<"=">) ask+ ( String | ListAccess | Expression )+ }
AssignList { Text (is+ | Op<"=">) (Text+ | Int ) ~ambig (Comma (Text+ | Int ))+ } // comma doesn't really parse well if it is not separated by spaces
Assign { Text (is+ | Op<"=">) (Expression ~ambig | ListAccess)+ }
Sleep { sleep+ (Expression | ListAccess )? }
ListAccess { Text at+ (random+ | Text) }
Add { add+ Text toList+ Text }
Remove { remove+ Text from+ Text }
Clear { clear+ }
Turtle[@isGroup=turtle] {
Forward { forward+ (Expression | ListAccess ) } |
Turn { turn+ (Expression | ListAccess ) } |
Color { color+ (Expression | ListAccess) }
}
If { ifs+ Condition }
Else { elses+ }
Condition {
EqualityCheck { Text is+ (String | Expression | pressed+) } |
InListCheck { Text ins+ Text } |
NotInListCheck { Text not_in+ Text }
}
Repeat { repeat+ (Int | Text) times+ }
For { fors+ Text ins+ Text }
ErrorInvalid[@dynamicPrecedence=-10] { Text+ }
Op<expr> { expr }
binaryExpression {
Expression !times Op<"*" | "/"> Expression |
Expression !plus Op<"+" | "-"> Expression
}
Expression {
Int |
Text |
binaryExpression
}
@precedence {
times @left,
plus @right
}
@external specialize { Text } specializeKeyword from "./tokens" {
ask[@name="ask"],
at[@name="at"],
random[@name="random"],
ifs[@name="if"],
pressed[@name="pressed"],
elses[@name="else"]
}
@external extend { Text } extendKeyword from "./tokens" {
print[@name="print"],
forward[@name="forward"],
turn[@name="turn"],
color[@name="color"],
sleep[@name="sleep"],
is[@name="is"],
add[@name="add"],
from[@name="from"],
remove[@name="remove"],
toList[@name="toList"],
clear[@name="clear"],
ins[@name="in"],
not_in[@name="not_in"],
repeat[@name="repeat"],
times[@name="times"],
fors[@name="for"]
}
@tokens {
@precedence {
Int,
Text
}
Comment { "#" ![\n]* }
eol { "\n" }
Comma { $[,،,、] } // every language comma is valid here
Text { ![^\n,،,、 '"#+\-*/=]+ } // a little bit of a hack not to parse commas never, but lezer adds them as error nodes, so it still
space { " " }
digit { $[٠١٢٣٤٥٦٧٨٩۰۱۲۳۴۵۶۷۸۹0123456789] } // latin, arab and pa_PK (Panjabi) scripts
Int { digit+ }
}
@skip { Comment | space }