umbriel2.atg 7.6 KB

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