grammar.js 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. "use strict";
  2. var Context = require("context.js");
  3. var Lexer = require("lexer.js");
  4. var Parser = require("parser.js");
  5. var Class = require("rtl.js").Class;
  6. var character = Lexer.character;
  7. var literal = Lexer.literal;
  8. var digit = Lexer.digit;
  9. var hexDigit = Lexer.hexDigit;
  10. var ident = Lexer.ident;
  11. var point = Lexer.point;
  12. var separator = Lexer.separator;
  13. var and = Parser.and;
  14. var or = Parser.or;
  15. var optional = Parser.optional;
  16. var repeat = Parser.repeat;
  17. var context = Parser.context;
  18. var emit = Parser.emit;
  19. var required = Parser.required;
  20. var qualident = context(and(optional(and(ident, ".")), ident),
  21. Context.QualifiedIdentificator);
  22. var identdef = context(and(ident, optional("*")),
  23. Context.Identdef);
  24. var selector = or(and(point, ident)
  25. // break recursive declaration of expList
  26. , and("[", function(stream, context){return expList(stream, context);}, "]")
  27. , "^"
  28. , context(and("(", qualident, ")"), Context.TypeCast)
  29. );
  30. var designator = context(and(qualident, repeat(selector)), Context.Designator);
  31. var type = or(context(qualident, Context.Type),
  32. function(stream, context){return strucType(stream, context);} // break recursive declaration of strucType
  33. );
  34. var identList = and(identdef, repeat(and(",", identdef)));
  35. var variableDeclaration = context(and(identList, ":", type), Context.VariableDeclaration);
  36. var integer = or(context(and(digit, repeat(hexDigit), "H", separator), Context.HexInteger)
  37. , context(and(digit, repeat(digit), separator), Context.Integer));
  38. var scaleFactor = and(or("E", "D"), optional(or("+", "-")), digit, repeat(digit));
  39. var real = context(and(digit, repeat(digit), point, repeat(digit), optional(scaleFactor))
  40. , Context.Real);
  41. var number = or(real, integer);
  42. var string = or(context(Lexer.string, Context.String)
  43. , context(and(digit, repeat(hexDigit), "X"), Context.Char));
  44. var factor = context(
  45. or(string, number, "NIL", "TRUE", "FALSE"
  46. , function(stream, context){return set(stream, context);} // break recursive declaration of set
  47. , context(and(designator
  48. // break recursive declaration of actualParameters
  49. , optional(function(stream, context){return actualParameters(stream, context);})
  50. )
  51. , Context.ExpressionProcedureCall)
  52. , and("(", function(stream, context){return expression(stream, context);}
  53. , required(")", "no matched ')'"))
  54. , and("~", function(stream, context){
  55. return factor(stream, context);}) // break recursive declaration of factor
  56. )
  57. , Context.Factor);
  58. var addOperator = context(or("+", "-", "OR"), Context.AddOperator);
  59. var mulOperator = context(or("*", "/", "DIV", "MOD", "&"), Context.MulOperator);
  60. var term = context(and(factor, repeat(and(mulOperator, factor))), Context.Term);
  61. var simpleExpression = context(
  62. and(optional(or("+", "-"))
  63. , term
  64. , repeat(and(addOperator, term)))
  65. , Context.SimpleExpression);
  66. var relation = or("=", "#", "<=", "<", ">=", ">", "IN", "IS");
  67. var expression = context(and(simpleExpression, optional(and(relation, simpleExpression)))
  68. , Context.Expression);
  69. var constExpression = expression;
  70. var element = context(and(expression, optional(and("..", expression))), Context.SetElement);
  71. var set = and("{", context(optional(and(element, repeat(and(",", element)))), Context.Set)
  72. , "}");
  73. var expList = and(expression, repeat(and(",", expression)));
  74. var actualParameters = and("(", context(optional(expList), Context.ActualParameters), ")");
  75. var procedureCall = context(and(designator, optional(actualParameters))
  76. , Context.StatementProcedureCall);
  77. var assignment = context(and(designator, context(or(":=", "="), Context.CheckAssignment)
  78. , required(expression, "expression expected"))
  79. , Context.Assignment);
  80. var statement = optional(or(
  81. emit(assignment, Context.emitEndStatement)
  82. , emit(procedureCall, Context.emitEndStatement)
  83. // break recursive declaration of ifStatement/caseStatement/whileStatement/repeatStatement
  84. , function(stream, context){return ifStatement(stream, context);}
  85. , function(stream, context){return caseStatement(stream, context);}
  86. , function(stream, context){return whileStatement(stream, context);}
  87. , function(stream, context){return repeatStatement(stream, context);}
  88. , function(stream, context){return forStatement(stream, context);}
  89. ));
  90. var statementSequence = and(statement, repeat(and(";", statement)));
  91. var ifStatement = and("IF", context(expression, Context.If), "THEN", statementSequence
  92. , repeat(and("ELSIF", context(expression, Context.ElseIf), "THEN", statementSequence))
  93. , optional(and("ELSE", context(statementSequence, Context.Else)))
  94. , emit("END", Context.emitIfEnd));
  95. var label = or(integer, string, ident);
  96. var labelRange = context(and(label, optional(and("..", label))), Context.CaseRange);
  97. var caseLabelList = context(and(labelRange, repeat(and(",", labelRange))), Context.CaseLabelList);
  98. var caseParser = optional(context(and(caseLabelList, ":", statementSequence), Context.CaseLabel));
  99. var caseStatement = and("CASE", context(and(expression
  100. , "OF", caseParser, repeat(and("|", caseParser)), "END")
  101. , Context.Case));
  102. var whileStatement = and("WHILE", context(expression, Context.While), "DO", statementSequence
  103. , repeat(and("ELSIF", context(expression, Context.ElseIf), "DO", statementSequence))
  104. , emit("END", Context.emitWhileEnd)
  105. );
  106. var repeatStatement = and("REPEAT", context(statementSequence, Context.Repeat)
  107. , "UNTIL", context(expression, Context.Until));
  108. var forStatement = context(and("FOR", ident, ":=", expression, "TO", expression
  109. , optional(and("BY", constExpression))
  110. , emit("DO", Context.emitForBegin)
  111. , statementSequence, required("END", "END expected (FOR)"))
  112. , Context.For);
  113. var fieldList = context(and(identList, ":", type), Context.FieldListDeclaration);
  114. var fieldListSequence = and(fieldList, repeat(and(";", fieldList)));
  115. var arrayType = and("ARRAY", context(and(
  116. context(and(constExpression, repeat(and(",", constExpression)))
  117. , Context.ArrayDimensions)
  118. , "OF", type), Context.ArrayDecl));
  119. var baseType = context(qualident, Context.BaseType);
  120. var recordType = and("RECORD", context(and(optional(and("(", baseType, ")")), optional(fieldListSequence)
  121. , "END"), Context.RecordDecl));
  122. var pointerType = and("POINTER", "TO", context(type, Context.PointerDecl));
  123. var formalType = context(and(repeat(and("ARRAY", "OF")), qualident), Context.FormalType);
  124. var fpSection = and(optional(literal("VAR")), ident, repeat(and(",", ident)), ":", formalType);
  125. var formalParameters = and(
  126. "("
  127. , optional(context(and(fpSection, repeat(and(";", fpSection))), Context.ProcParams))
  128. , required( ")" )
  129. , optional(and(":", qualident)));
  130. var procedureType = and("PROCEDURE"
  131. , context(optional(formalParameters), Context.FormalParameters)
  132. );
  133. var strucType = or(arrayType, recordType, pointerType, procedureType);
  134. var typeDeclaration = context(and(identdef, "=", strucType), Context.TypeDeclaration);
  135. var procedureHeading = and("PROCEDURE"
  136. , identdef
  137. , context(optional(formalParameters), Context.FormalParametersProcDecl));
  138. var procedureDeclaration = context(
  139. and(procedureHeading, ";"
  140. // break recursive declaration of procedureBody
  141. , function(stream, context){return procedureBody(stream, context);}
  142. , ident)
  143. , Context.ProcDecl);
  144. var constantDeclaration = context(and(identdef, "=", constExpression), Context.ConstDecl);
  145. var declarationSequence = and(optional(and("CONST", repeat(and(constantDeclaration, required(";")))))
  146. , optional(and("TYPE", context(repeat(and(typeDeclaration, required(";"))), Context.TypeSection)))
  147. , optional(and("VAR", repeat(and(variableDeclaration, required(";")))))
  148. , repeat(and(procedureDeclaration, ";")));
  149. var procedureBody = and(declarationSequence
  150. , optional(and("BEGIN", statementSequence))
  151. , optional(context(and("RETURN", expression), Context.Return))
  152. , required("END", "END expected (PROCEDURE)"));
  153. var imprt = and(ident, optional(and(":=", ident)));
  154. var importList = and("IMPORT", imprt, repeat(and(",", imprt)));
  155. var modul = context(and("MODULE", ident, ";",
  156. context(optional(and(importList, ";")), Context.ModuleImport),
  157. declarationSequence,
  158. optional(and("BEGIN", statementSequence)),
  159. required("END", "END expected (MODULE)"), ident, point),
  160. Context.ModuleDeclaration);
  161. exports.declarationSequence = declarationSequence;
  162. exports.expression = expression;
  163. exports.ident = ident;
  164. exports.module = modul;
  165. exports.procedureBody = procedureBody;
  166. exports.procedureDeclaration = procedureDeclaration;
  167. exports.procedureHeading = procedureHeading;
  168. exports.statement = statement;
  169. exports.typeDeclaration = typeDeclaration;
  170. exports.variableDeclaration = variableDeclaration;