1 /**
2  * This module was given by Bjoern Lietz-Spendig
3  **/
4 module pegged.examples.oberon2;
5 
6 
7 /*
8  *
9  * PEG Grammar for Oberon-2
10  * A detailed language report is available at
11  * http://www-vs.informatik.uni-ulm.de:81/projekte/Oberon-2.Report/index.html
12  */
13 
14 /*
15 The remarkable short syntax of Oberon-2 in --- Wirth EBNF ---
16 
17 Module  =   MODULE ident ";" [ImportList] DeclSeq [BEGIN StatementSeq] END ident ".".
18 ImportList   =   IMPORT [ident ":="] ident {"," [ident ":="] ident} ";".
19 DeclSeq   =   { CONST {ConstDecl ";" } | TYPE {TypeDecl ";"} | VAR {VarDecl ";"}} {ProcDecl ";" | ForwardDecl ";"}.
20 ConstDecl  =   IdentDef "=" ConstExpr.
21 TypeDecl  =   IdentDef "=" Type.
22 VarDecl  =   IdentList ":" Type.
23 ProcDecl   =   PROCEDURE [Receiver] IdentDef [FormalPars] ";" DeclSeq [BEGIN StatementSeq] END ident.
24 ForwardDecl  =   PROCEDURE "^" [Receiver] IdentDef [FormalPars].
25 FormalPars   =   "(" [FPSection {";" FPSection}] ")" [":" Qualident].
26 FPSection   =   [VAR] ident {"," ident} ":" Type.
27 Receiver  =   "(" [VAR] ident ":" ident ")".
28 Type   =   Qualident
29   |   ARRAY [ConstExpr {"," ConstExpr}] OF Type
30   |   RECORD ["("Qualident")"] FieldList {";" FieldList} END
31   |   POINTER TO Type
32   |   PROCEDURE [FormalPars].
33 FieldList   =   [IdentList ":" Type].
34 StatementSeq  =   Statement {";" Statement}.
35 Statement   =  [ Designator ":=" Expr
36   |   Designator ["(" [ExprList] ")"]
37   |   IF Expr THEN StatementSeq {ELSIF Expr THEN StatementSeq} [ELSE StatementSeq] END
38   |   CASE Expr OF Case {"|" Case} [ELSE StatementSeq] END
39   |   WHILE Expr DO StatementSeq END
40   |   REPEAT StatementSeq UNTIL Expr
41   |   FOR ident ":=" Expr TO Expr [BY ConstExpr] DO StatementSeq END
42   |   LOOP StatementSeq END
43   |   WITH Guard DO StatementSeq {"|" Guard DO StatementSeq} [ELSE StatementSeq] END
44   |   EXIT
45   |   RETURN [Expr]
46      ].
47 Case   =   [CaseLabels {"," CaseLabels} ":" StatementSeq].
48 CaseLabels   =   ConstExpr [".." ConstExpr].
49 Guard  =   Qualident ":" Qualident.
50 ConstExpr  =   Expr.
51 Expr   =   SimpleExpr [Relation SimpleExpr].
52 SimpleExpr  =   ["+" | "-"] Term {AddOp Term}.
53 Term   =   Factor {MulOp Factor}.
54 Factor   =   Designator ["(" [ExprList] ")"] | number | character | string | NIL | Set | "(" Expr ")" | " ~ " Factor.
55 Set  =   "{" [Element {"," Element}] "}".
56 Element   =   Expr [".." Expr].
57 Relation   =   "=" | "#" | "<" | "<=" | ">" | ">=" | IN | IS.
58 AddOp   =   "+" | "-" | OR.
59 MulOp   =   " * " | "/" | DIV | MOD | "&".
60 Designator   =   Qualident {"." ident | "[" ExprList "]" | " ^ " | "(" Qualident ")"}.
61 ExprList   =   Expr {"," Expr}.
62 IdentList   =   IdentDef {"," IdentDef}.
63 Qualident   =   [ident "."] ident.
64 IdentDef   =   ident [" * " | "-"].
65 */
66 
67 
68 /*
69 FOUR SIMPLE EBNF TO PEGGED TRANFORMATION RULES
70 Pegged                Wirth EBNF
71 
72 Sequence
73 A <- B C            A = B C.
74 
75 B or C
76 A <- B / C            A = B|C.
77 
78 Zero or one B
79 A <- B?                A = [B].
80 
81 Zero or more Bs
82 A <- B*                A = {B}.
83 
84 List of comma (or otherwise) separated Bs
85 A <- List(B, ',')   A = B {"," B}.
86 
87 */
88 
89 /// The Oberon-2 PEG grammar (Finally!)
90 enum string Oberon2Grammar =  `
91 Oberon2:
92 
93 Module             <- "MODULE" Identifier ";" ImportList? DeclSeq ("BEGIN" StatementSeq)? "END" Identifier "."
94 
95 ImportList         <- "IMPORT" (Identifier ":=")? Identifier ("," (Identifier ":=")? Identifier)* ";"
96 
97 DeclSeq         <- "CONST" (ConstDecl ";")*
98                  / "TYPE" (TypeDecl ";")*
99                  / "VAR" (VarDecl ";")* (ProcDecl ";" / ForwardDecl ";")*
100 
101 ConstDecl          <-  IdentDef "=" ConstExpr
102 TypeDecl          <-  IdentDef "=" Type
103 VarDecl          <-  IdentList ":" Type
104 ProcDecl           <-  "PROCEDURE" Receiver? IdentDef FormalPars? ";" DeclSeq ("BEGIN" StatementSeq)? "END" Identifier
105 ForwardDecl      <-  "PROCEDURE" "^" Receiver? IdentDef FormalPars?
106 FormalPars       <-  "(" (FPSection (";" FPSection)*)? ")" (":" Qualident)?
107 FPSection       <-   "VAR"? Identifier ("," Identifier)? ":" Type
108 Receiver          <-   "(" "VAR"? Identifier ":" Identifier ")"
109 
110 Type               <-  Qualident
111                  / "ARRAY" (ConstExpr ("," ConstExpr)*)? "OF" Type
112                  / "RECORD" ("("Qualident")")? FieldList (";" FieldList)* "END"
113                  / "POINTER" "TO" Type
114                  / "PROCEDURE" (FormalPars)?
115 
116 FieldList       <-  (IdentList ":" Type)?
117 
118 #
119 StatementSeq      <-  Statement (";" Statement)* # List( Statement, ';')
120 
121 Statement       <-  ( Designator ":=" Expr
122                       / Designator ("(" (ExprList)? ")")
123                       / IfStatement
124                       / CaseStatement
125                       / WhileStatement
126                       / RepeatStatement
127                       / ForStatement
128                       / LoopStatement
129                       / WithStatement
130                       / ExitStatement
131                       / ReturnStatement
132                       )?
133 
134 IfStatement        <-  "IF" Expr "THEN" StatementSeq ("ELSIF" Expr "THEN" StatementSeq)* ("ELSE" StatementSeq)? "END"
135 CaseStatement    <-    "CASE" Expr "OF" Case ("|" Case)* ("ELSE" StatementSeq) "END"
136 WhileStatement     <-    "WHILE" Expr "DO" StatementSeq "END"
137 RepeatStatement    <-    "REPEAT" StatementSeq "UNTIL" Expr
138 ForStatement    <-    "FOR" Identifier ":=" Expr "TO" Expr ("BY" ConstExpr)? "DO" StatementSeq "END"
139 LoopStatement    <-    "LOOP" StatementSeq "END"
140 WithStatement    <-  "WITH" Guard "DO" StatementSeq ("|" Guard "DO" StatementSeq)* ("ELSE" StatementSeq)? "END"
141 ExitStatement    <-     "EXIT"
142 ReturnStatement <-  "RETURN" Expr?
143 
144 Case              <-  (CaseLabels ("," CaseLabels)* ":" StatementSeq)?
145 CaseLabels       <-  ConstExpr (".." ConstExpr)?
146 Guard              <-  Qualident ":" Qualident
147 ConstExpr          <-  Expr
148 Expr               <-  SimpleExpr (Relation SimpleExpr)?
149 SimpleExpr      <-  ("+" / "-")? Term (AddOp Term)*
150 Term               <-  Factor (MulOp Factor)*
151 Factor           <-     Designator ("(" ExprList? ")")?
152                      / Number
153                     / Character
154                     / String
155                     / "NIL"
156                     / Set
157                     / "(" Expr ")"
158                     / " ~ " Factor
159 
160 Set              <-  "{" (Element ("," Element)*)? "}"
161 Element           <-   Expr (".." Expr)?
162 
163 Relation           <-  "IN" / "IS" / "<=" / ">=" / "=" / "#" / "<" / ">"
164 AddOp           <-  "OR" / "+" / "-"
165 MulOp           <-  "DIV" / "MOD" / "*" / "/" / "&"
166 Designator       <-  Qualident ("." Identifier / "[" ExprList "]" / " ^ " / "(" Qualident ")")*
167 List(E,S)       <-  E (S E)*
168 ExprList           <-  Expr (',' Expr)*
169 IdentList       <-  IdentDef (',' IdentDef)*
170 Qualident       <-  (Identifier ".")? Identifier
171 IdentDef           <-  Identifier (" * " / "-")?
172 
173 #Numbers
174 Number            <- Integer / Real
175 Integer            <- Digit Digit* / Digit HexDigit* "H"
176 Real            <- Digit Digit* "." Digit* ScaleFactor?
177 ScaleFactor        <- ("E" / "D") / ("+" / "-")? Digit Digit*
178 HexDigit        <- [0-9A-F]
179 Digit            <- [0-9]
180 
181 #Number Examples
182 # 1991            INTEGER        1991
183 # 0DH            SHORTINT    13
184 # 12.3            REAL        12.3
185 # 4.567E8        REAL        456700000
186 # 0.57712566D-6    LONGREAL    0.00000057712566
187 
188 String              <- DoubleQuotedString / SingleQuotedString
189 DoubleQuotedString  <- doublequote DQChar* doublequote
190 SingleQuotedString  <- quote SQChar* quote
191 
192 DQChar          <- EscapeSequence
193                 / !doublequote .
194 
195 SQChar          <- EscapeSequence
196                 / !quote .
197 
198 EscapeSequence  <- backslash ( quote
199                             / doublequote
200                             / backslash
201                             / [abfnrtv]
202                             / 'x' HexDigit HexDigit
203                             / 'u' HexDigit HexDigit HexDigit HexDigit
204                             / 'U' HexDigit HexDigit HexDigit HexDigit HexDigit HexDigit HexDigit HexDigit
205                             )
206 
207 Character       <- quote (!quote (EscapeSequence / .)) quote
208 
209 #Oberon-2 comments look like (* Some Text *)
210 Comment <- '(*' (!'*)' .)* '*)'
211 
212 # I had to add it. Otherwise, keywords are recognized as identifiers. Note that Oberon does not allow '_'
213 Identifier         <~ !Keyword [a-zA-Z] [a-zA-Z0-9]*
214 
215 Keyword         <- "ARRAY" / "ABS"/ "ASH" / "BOOLEAN" / "BEGIN" / "BY"
216                 /  "CASE" / "CHAR" / "CONST" / "COPY" / "CAP"/ "CHR"
217                 /  "DEC" / "DIV" / "DO" / "ELSIF" / "ELSE" / "ENTIER" / "EXCL" / "EXIT" / "END"
218                 /  "FALSE" / "FOR" / "HALT" / "INTEGER" / "IMPORT" / "INCL" / "INC" / "IF" / "IN" /"IS"
219                 /  "LONGREAL" / "LONGINT" / "LONG" / "LOOP" / "LEN"
220                 /  "MODULE" / "MOD" / "MIN" / "MAX"/ "NIL" /"NEW"
221                 /  "ODD" / "ORD" / "OF" / "OR" / "PROCEDURE" / "REAL"
222                 /  "SET" / "SHORTINT" / "SHORT" / "SIZE" / "TRUE"
223                 /  "POINTER" / "RECORD" / "REPEAT" / "RETURN" / "THEN" / "TYPE" / "TO" / "UNTIL" / "VAR"
224                 /  "WHILE" / "WITH"
225 
226 `;