parser.js 2.1 KB

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