umbriel1.atg 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. COMPILER Umbriel
  2. (* COCO/R - like Grammar for Umbriel
  3. Umbriel is a simple Modula-2 / Pascal like language
  4. This grammar is not LL(1), so a Coco/R generated parser will be incorrect
  5. The description here is intended to aid semantic understanding! *)
  6. CHARACTERS
  7. eol = CHR(13) .
  8. letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" .
  9. digit = "0123456789" .
  10. noQuote1 = ANY - "'" - eol .
  11. noQuote2 = ANY - '"' - eol .
  12. IGNORE
  13. CHR(9) .. CHR(13)
  14. COMMENTS FROM '(*' TO '*)' NESTED
  15. (* The language is case sensitive *)
  16. TOKENS
  17. identifier = letter { letter | digit } .
  18. char = "'" [ noQuote1 ] "'" | '"' [ noQuote2 ] '"' | digit {digit} "C" .
  19. (* The xxC variation uses decimal numbers, not the octal form of Wirth's other
  20. languages *)
  21. integer = digit { digit }
  22. | digit { digit } CONTEXT ("..") .
  23. real = digit { digit } "." { digit }
  24. [ ( "E" | "e" ) [ "+" | "-" ] digit { digit } ] .
  25. string = "'" { noQuote1 } "'" | '"' { noQuote2 } '"' .
  26. PRODUCTIONS
  27. Umbriel = "MODULE" ModuleIdentifier ";"
  28. Block ModuleIdentifier "." .
  29. ModuleIdentifier = identifier .
  30. (* The same identifier appears in both places *)
  31. Block = { NonVarDeclaration }
  32. { NonProcDeclaration }
  33. [ "BEGIN" StatementSequence ] "END" .
  34. NonVarDeclaration = "CONST" { ConstantDeclaration ";" }
  35. | "TYPE" { TypeDeclaration ";" }
  36. | ProcedureDeclaration ";" .
  37. NonProcDeclaration = "CONST" { ConstantDeclaration ";" }
  38. | "TYPE" { TypeDeclaration ";" }
  39. | "VAR" { VariableDeclaration ";" } .
  40. (* Declarations may be mixed in order, but for all identifiers
  41. declaration-before-use is required. The syntax prevents "global"
  42. variables from being seen in procedures directly *)
  43. ConstantDeclaration = ConstIdentifier "=" ConstExpression .
  44. ConstIdentifier = identifier .
  45. ConstExpression = Expression .
  46. (* A ConstExpression may only contain constants, literals, and some standard
  47. function calls *)
  48. TypeDeclaration = TypeIdentifier "=" Type .
  49. Type = TypeIdentifier | ArrayType | RecordType .
  50. TypeIdentifier = identifier .
  51. ArrayType = "ARRAY" IndexType { "," IndexType } "OF" Type .
  52. IndexType = "[" ConstExpression ".." ConstExpression "]" .
  53. (* The index type is an anonymous subrange type. It has to be declared like
  54. this; implicit subranges like CHAR and BOOLEAN may not be used by quoting
  55. the type names. *)
  56. RecordType = "RECORD" FieldListSequence "END" .
  57. FieldListSequence = FieldList { ";" FieldList } .
  58. FieldList = [ IdentList ":" Type ] .
  59. IdentList = VariableIdentifier { "," VariableIdentifier } .
  60. VariableIdentifier = identifier .
  61. (* The syntax allows the "permissive" use of extra ; symbols as in Modula-2,
  62. and also completely empty records, as in Wirth's other languages *)
  63. VariableDeclaration = IdentList ":" TypeIdentifier .
  64. (* Unlike Modula-2 and Pascal, a variable has to be declared in terms of a
  65. named type. This is to encourage simple abstraction. *)
  66. ProcedureDeclaration = ProperProcDeclaration | FunctionDeclaration .
  67. ProperProcDeclaration = "PROCEDURE" ProcedureIdentifier
  68. [ "(" [ FormalParameters ] ")" ]
  69. ";" Block ProcedureIdentifier .
  70. ProcedureIdentifier = identifier .
  71. FunctionDeclaration = "PROCEDURE" FunctionIdentifier
  72. "(" [ FormalParameters ] ")" ":" ResultType
  73. ";" Block FunctionIdentifier .
  74. FunctionIdentifier = identifier .
  75. ResultType = ScalarTypeIdentifier .
  76. ScalarTypeIdentifier = TypeIdentifier .
  77. (* Procedures may omit the ( brackets ) if there are no parameters.
  78. Functions may have no parameters, but require the ( brackets ),
  79. as in Modula-2.
  80. Functions may only return INTEGER, REAL, CHAR, COLORS or BOOLEAN values *)
  81. FormalParameters = FormalParameter { ";" FormalParameter } .
  82. FormalParameter = ValueSpecification | VariableSpecification .
  83. ValueSpecification = IdentList ":" TypeIdentifier .
  84. VariableSpecification = "VAR" IdentList ":" TypeIdentifier .
  85. StatementSequence = Statement { ";" Statement } .
  86. Statement = [ Assignment | ProcedureCall
  87. | IfStatement | CaseStatement
  88. | WhileStatement | RepeatStatement
  89. | ForStatement | LoopStatement
  90. | ExitStatement | ReturnStatement ] .
  91. (* The statements are as in Modula-2, other than WITH *)
  92. Assignment = VarDesignator ":=" Expression .
  93. VarDesignator = VariableIdentifier { Selector } .
  94. Selector = "." VariableIdentifier | "[" IndexList "]" .
  95. IndexList = OrdinalExpression { "," OrdinalExpression } .
  96. ProcedureCall = ProcedureIdentifier [ "(" [ ActualParameters ] ")" ] .
  97. ActualParameters = Expression [ FormatSpecifier ]
  98. { "," Expression [ FormatSpecifier ] } .
  99. FormatSpecifier = ":" IntegerExpression [ ":" IntegerExpression ] .
  100. (* FormatSpecifier is only allowed in calls to the standard procedures
  101. Write and WriteLn *)
  102. IfStatement = "IF" BooleanExpression "THEN" StatementSequence
  103. { "ELSIF" BooleanExpression
  104. "THEN" StatementSequence }
  105. [ "ELSE" StatementSequence ]
  106. "END" .
  107. CaseStatement = "CASE" Expression "OF"
  108. Case
  109. { "|" Case }
  110. [ "ELSE" StatementSequence ]
  111. "END" .
  112. Case = [ CaseLabelList ":" StatementSequence ] .
  113. CaseLabelList = CaseLabels { "," CaseLabels } .
  114. CaseLabels = ConstExpression [ ".." ConstExpression ] .
  115. (* The syntax allows the "permissive" use of extra | symbols as in Modula-2 *)
  116. WhileStatement = "WHILE" BooleanExpression "DO"
  117. StatementSequence
  118. "END" .
  119. RepeatStatement = "REPEAT"
  120. StatementSequence
  121. "UNTIL" BooleanExpression .
  122. ForStatement = "FOR" VariableIdentifier ":=" OrdinalExpression
  123. "TO" OrdinalExpression [ "BY" ConstExpression ] "DO"
  124. StatementSequence
  125. "END" .
  126. (* The BY step requires a constant expression so that the compiler can decide
  127. at compile time whether it is a "to" or "downto" loop. The control
  128. variable must be declared locally, and the implementation tries to detect
  129. situations where it would be threatened (changed in the body of the loop) *)
  130. LoopStatement = "LOOP" StatementSequence "END" .
  131. ExitStatement = "EXIT" .
  132. (* An ExitStatement is only allowed within the StatementSequence of a
  133. LoopStatement. It transfers control out of the closest enclosing
  134. LoopStatement. *)
  135. ReturnStatement = "RETURN" [ Expression ] .
  136. (* A ReturnStatement within a function must incorporate an Expression; within
  137. a regular procedure or a program block it must not incorporate an
  138. Expression. *)
  139. BooleanExpression = Expression .
  140. OrdinalExpression = Expression .
  141. IntegerExpression = Expression .
  142. Expression = SimpleExpression [ Relation SimpleExpression ] .
  143. SimpleExpression = [ "+" | "-" ] Term { AddOperator Term } .
  144. Term = Factor { MulOperator Factor } .
  145. Factor = ConstantLiteral
  146. | ConstIdentifier
  147. | VarDesignator
  148. | FunctionCall
  149. | NotOperator Factor
  150. | "(" Expression ")" .
  151. ConstantLiteral = integer | char | real | string .
  152. FunctionCall = FunctionIdentifier "(" [ ActualParameters ] ")" .
  153. NotOperator = "NOT" | "~" (* synonyms *) .
  154. MulOperator = "*" | "/" | "DIV" | "MOD" | AndOperator .
  155. AndOperator = "AND" | "&" (* synonyms *) .
  156. AddOperator = "+" | "-" | "OR" .
  157. Relation = "=" | "#" | "<>" | "<" | "<=" | ">" | ">=" .
  158. END Umbriel.