parser.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. var assert = require("assert.js").ok;
  2. var Errors = require("errors.js");
  3. var Lexer = require("lexer.js");
  4. exports.and = function(/*...*/){
  5. var args = arguments;
  6. assert(args.length >= 2);
  7. return function(stream, context){
  8. for(var i = 0; i < args.length; ++i){
  9. if (i != 0)
  10. Lexer.skipSpaces(stream, context);
  11. var p = args[i];
  12. if (typeof p == "string")
  13. p = Lexer.literal(p);
  14. if (!p(stream, context))
  15. return false;
  16. }
  17. return true;
  18. }
  19. }
  20. exports.or = function(/*...*/){
  21. var args = arguments;
  22. assert(args.length >= 2);
  23. return function(stream, context){
  24. for(var i = 0; i < args.length; ++i){
  25. var p = args[i];
  26. if (typeof p == "string")
  27. p = Lexer.literal(p);
  28. var savePos = stream.pos();
  29. if (p(stream, context))
  30. return true;
  31. stream.setPos(savePos);
  32. }
  33. return false;
  34. }
  35. }
  36. exports.repeat = function(p){
  37. return function(stream, context){
  38. var savePos = stream.pos();
  39. while (!stream.eof() && p(stream, context)){
  40. Lexer.skipSpaces(stream, context);
  41. savePos = stream.pos();
  42. }
  43. stream.setPos(savePos);
  44. return true;
  45. }
  46. }
  47. exports.optional = function(p){
  48. assert(arguments.length == 1);
  49. if (typeof(p) === "string")
  50. p = Lexer.literal(p);
  51. return function(stream, context){
  52. var savePos = stream.pos();
  53. if ( !p(stream, context))
  54. stream.setPos(savePos);
  55. return true;
  56. }
  57. }
  58. exports.required = function(parser, error){
  59. if (typeof(parser) === "string")
  60. parser = Lexer.literal(parser);
  61. return function(stream, context){
  62. if (!parser(stream, context))
  63. throw new Errors.Error(error);
  64. return true;
  65. }
  66. }
  67. exports.context = function(parser, contextFactory){
  68. return function(stream, context){
  69. var context = new contextFactory(context);
  70. if (!parser(stream, context))
  71. return false;
  72. if (context.endParse)
  73. return context.endParse() !== false;
  74. return true;
  75. }
  76. }
  77. exports.emit = function(parser, action){
  78. assert(action);
  79. if (typeof(parser) === "string")
  80. parser = Lexer.literal(parser);
  81. return function(stream, context){
  82. if (!parser(stream, context))
  83. return false;
  84. action(context);
  85. return true;
  86. }
  87. }