forked from hedyorg/hedy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlevel5-Additions.lark
46 lines (34 loc) · 3.69 KB
/
level5-Additions.lark
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
program: _empty_program | _non_empty_program
_empty_program: (_EOL | _SPACE)*
_non_empty_program: _EOL* (command | error_invalid) _SPACE* (_EOL+ command _SPACE*)* _EOL* //lines may end on spaces and might be separated by many newlines
//placing assign after print means print is will print 'is' and print is Felienne will print 'is Felienne'
command:+= assign_button | ifpressed_else | error_ifpressed_missing_else | ifelse | ifs -= error_invalid > assign
_if_less_command: print | ask | turtle | assign_button | assign_list | add | remove | sleep | error_print_no_quotes | assign
// error_invalid is moved from to command to program, so that command rules have priority over error_invalid
error_invalid: textwithoutspaces _SPACE* (quoted_text | textwithspaces)?
//todo: list_access_var can be merged with var? would simplify rewriting a bit, some duplication now in processing
list_access_var: var _IS var _AT (INT | random)
assign_button: NAME _IS _BUTTON
assign_list: var _IS textwithspaces (_COMMA textwithspaces)+
assign: var _IS (list_access | textwithspaces)
error_print_no_quotes: _PRINT (textwithoutspaces | list_access | var_access) (_SPACE (textwithoutspaces | list_access | var_access))* -> error_print_nq
// new commands for level 5
ifpressed_else: _IF (LETTER_OR_NUMERAL | var) _IS _PRESSED _EOL* _if_less_command (_SPACE+ _EOL* | _SPACE* _EOL+) _ELSE (_SPACE+ _EOL* | _SPACE* _EOL+) _if_less_command
error_ifpressed_missing_else: _IF (LETTER_OR_NUMERAL | var) _IS _PRESSED _EOL* _if_less_command
_if_clause: _IF (condition (_SPACE+ _EOL* | _SPACE* _EOL+) | condition_spaces _SPACE* _EOL+ | error_condition) _if_less_command
error_condition: condition_spaces _SPACE
ifelse: _if_clause (_SPACE+ _EOL* | _SPACE* _EOL+) _ELSE (_SPACE+ _EOL* | _SPACE* _EOL+) _if_less_command
ifs: _if_clause // 'if' is a reserved word in Python, hence the name of the rule is 'ifs'
condition_spaces: textwithoutspaces _IS textwithoutspaces (_SPACE textwithoutspaces)+
condition: equality_check | in_list_check | not_in_list_check
equality_check: (textwithoutspaces | INT) _IS (quoted_text | textwithoutspaces | INT) //TODO FH nov 2021: not super pretty that this is textwithoutquotes for both a var and also a textual constant, level 12 handles this nicer now, could be done here too
in_list_check: textwithoutspaces _IN var_access
not_in_list_check: textwithoutspaces _NOT_IN var_access
nospace: /[^\n, ]/
textwithspaces: /(?:[^#\n،,,、 ]| (?!else|başka|faese|अन्यथा|否则|muuten|muidu|senão|ellers|alie|altfel|иначе|altrimenti|інакше|arall|annars|anders|ndryshe|inaczej|sinon|ไม่อย่างนั้น|sonst|లేకపోతే|sino|ورنہ|وکھرا|אחרת|وإلا))+/ -> text //anything can be parsed except for a newline and a comma for list separators
//a space is allowed, but it may not be followed by an else. The part " (?!else))" means space not followed by (negative look ahead) else
//That is because allowing else in strings leads to issue #303
textwithoutspaces: /(?:[^#\n،,,、 *+\-\/eiіиలేไamfnsbअ否אو]|א(?!חרת )|و(?!إلا |کھرا |رنہ)|否(?!则 )|अ(?!न्यथा )|и(?!наче )|m(?!uidu |uuten )|b(?!aşka )|n(?!dryshe )|ไ(?!ม่อย่างนั้น )|f(?!aese )|e(?!lse |llers )|s(?!inon |enão |ino |onst )|і(?!накше )|i(?!naczej )|లే (?!కపోతే )|a(?!nders |lie |ltfel |ltrimenti |nnars |rall ))+/ -> text //anything can be parsed except for spaces (plus: a newline and a comma for list separators)
//the part e(?!lse)|i(?!f)) means e not followed by lse, and i not followed by f
// this is because allowing else and if in invalid leads to ambiguity in the grammar
// note that the i's look similar but are not: inaczej versus інакше!