grammar.js 8.2 KB

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