-
Notifications
You must be signed in to change notification settings - Fork 0
/
grammar.bnf
116 lines (82 loc) · 4.24 KB
/
grammar.bnf
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
program = globalDeclaration* EOF ;
# --------------- Declarations ---------------
globalDeclaration = recordDecl
| classDecl
| subDecl
| declaration ;
recordDecl = "RECORD" IDENTIFER "IS" "{" parameters "}" SEPARATOR? ;
classDecl = "CLASS" IDENTIFER ( ( "INHERITS" IDENTIFER ( "WITH" "{" parameters "}" )? ) | ( "IS" "{" parameters "}" ) )? SEPARATOR?
( "METHODS" SEPARATOR? ( classConstructor | "OVERRIDE"? subDecl )* )?
"END" "CLASS" SEPARATOR? ;
classConstructor = "CONSTRUCTOR" "(" parameters? ")" body "END" "CONSTRUCTOR" SEPARATOR? ;
subDecl = procDecl | funcDecl ;
procDecl = "PROCEDURE" procedure "END" "PROCEDURE" SEPARATOR? ;
funcDecl = "FUNCTION" function "END" "FUNCTION" SEPARATOR? ;
declaration = varDecl | statement ;
varDecl = "DECLARE" ( IDENTIFER | ( "THIS" "." IDENTIFER ) ) ( "AS" TYPE_DECL )? "INITIALLY" ( ( "FROM" SYS_ENTITY ) | expression ) SEPARATOR ;
# --------------- Statements ---------------
statement = ifStmt
| whileStmt | untilStmt
| forStmt | forEachStmt
| setStmt
| createStmt | openStmt | closeStmt
| sendStmt | receiveStmt
| returnStmt
| exprStmt ;
ifStmt = "IF" expression "THEN" body ( ( "ELSE" body )? "END" "IF" ) | ( "ELSE" ifStmt ) SEPARATOR? ;
whileStmt = "WHILE" expression "DO" body "END" "WHILE" SEPARATOR? ;
untilStmt = "REPEAT" body "UNTIL" expression SEPARATOR ;
forStmt = "FOR" IDENTIFER "FROM" expression "TO" expression ( "STEP" expression )? "DO" body "END" "FOR" SEPARATOR? ;
forEachStmt = "FOR" "EACH" IDENTIFER "FROM" expression "DO" body "END" "FOR" "EACH" SEPARATOR? ;
setStmt = "SET" expression "TO" expression SEPARATOR ;
createStmt = "CREATE" FILE SEPARATOR ;
openStmt = "OPEN" FILE SEPARATOR ;
closeStmt = "CLOSE" FILE SEPARATOR ;
sendStmt = "SEND" expression "TO" SYS_ENTITY SEPARATOR ;
receiveStmt = "RECEIVE" expression "FROM" SYS_ENTITY SEPARATOR ;
returnStmt = "RETURN" expression? SEPARATOR;
exprStmt = expression SEPARATOR ;
# --------------- Expressions ---------------
expression = logic_or ;
logic_or = logic_and ( "OR" logic_and )* ;
logic_and = logic_not ( "AND" logic_not )* ;
logic_not = ( "NOT" ) logic_not | equality ;
equality = comparison ( ( "≠" | "=" ) comparison )* ;
comparison = concatenation ( ( ">" | "≥" | "<" | "≤" ) concatenation )* ;
concatenation = term ( ( "&" ) term )* ;
term = factor ( ( "-" | "+" ) factor )* ;
factor = exponent ( ( "/" | "*" | "MOD" ) exponent )* ;
exponent = unary ( ( "^" ) unary )* ;
unary = ( "-" ) unary | call ;
call = primary ( "(" arguments? ")" | "." IDENTIFIER | "[" expression "]" )* ;
primary = TYPE | IDENTIFIER
| "(" expression ")"
| "THIS" ;
# --------------- Types ---------------
TYPE = INTEGER | REAL | BOOLEAN | CHARACTER | STRING | ARRAY | RECORD ;
INTEGER = DIGIT+ ;
REAL = DIGIT+ ( "." DIGIT+ ) ;
BOOLEAN = "true" | "false" ;
CHARACTER = "'" <any char except "'"> "'" ;
STRING = "\"" <any char except "\"">* "\"" ;
ARRAY = "[" arguments? "]" ( "*" INTEGER )? ;
RECORD = "{" IDENTIFER "=" expression ( "," IDENTIFER "=" expression)* "}" ; # RECORD expression
IDENTIFER = ALPHA ( ALPHA | DIGIT )* ;
SYS_ENTITY = "DISPLAY" | "KEYBOARD" | FILE ;
FILE = <file path or URL> ;
ALPHA = "a" ... "z" | "A" ... "Z" | "_" ;
DIGIT = "0" ... "9" ;
# --------------- Type Declarations ---------------
TYPE_DECL = INTEGER_TYPE | REAL_TYPE | CHARACTER_TYPE | STRING_TYPE | ARRAY_TYPE | IDENTIFER ;
INTEGER_TYPE = "INTEGER" ;
REAL_TYPE = "REAL" ;
STRING_TYPE = "CHARACTER" ;
STRING_TYPE = "STRING" ;
ARRAY_TYPE = "ARRAY OF" TYPE_DECL ;
# --------------- Utility Rules ---------------
procedure = IDENTIFER "(" parameters? ")" body ;
function = IDENTIFER "(" parameters? ")" "RETURNS" TYPE_DECL body ;
body = SEPARATOR? declaration* ;
parameters = SEPARATOR? TYPE_DECL IDENTIFIER ( "," SEPARATOR? TYPE_DECL IDENTIFIER )* SEPARATOR? ;
arguments = SEPARATOR? expression ( "," SEPARATOR? expression)* SEPARATOR? ;
SEPARATOR = ( "\n" ) ;