Guest User

Untitled

a guest
Jun 21st, 2018
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.10 KB | None | 0 0
  1. // Parses a small subset of Common Lisp as used in AGraph Prolog queries.
  2.  
  3. LispParser = Editor.Parser = (function() {
  4. function wordRegexp(words) {
  5. return new RegExp("^(?:" + words.join("|") + ")$", "i");
  6. }
  7. var specialForms = wordRegexp(["select", "select-distinct", "select0-distinct", "select0", "<-", "<--"]);
  8. var symbolChars = /[^\s\u00a0\(\)#!<]/;
  9.  
  10. var tokenizeLisp = (function() {
  11. function normal(source, setState) {
  12. var ch = source.next();
  13. if (/[\(\)!\^]/.test(ch)) {
  14. return "punctuation";
  15. }
  16. else if (ch == "/" && source.equals("/")) {
  17. while (!source.endOfLine()) source.next();
  18. return "comment";
  19. }
  20. else if (ch == "!" && source.equals("<")) {
  21. source.nextWhile(matcher(/[^\s\u00a0>]/));
  22. if (source.equals(">")) source.next();
  23. return "uri";
  24. }
  25. else if (ch == "\"") {
  26. setState(inString);
  27. return null;
  28. }
  29. else {
  30. source.nextWhile(matcher(symbolChars));
  31. if (ch == "?") return "var";
  32. var word = source.get();
  33. if (specialForms.test(word))
  34. return {style: "special", content: word};
  35. else
  36. return {style: "symbol", content: word};
  37. }
  38. }
  39.  
  40. function inString(source, setState) {
  41. var escaped = false;
  42. while (!source.endOfLine()) {
  43. var ch = source.next();
  44. if (ch == "\"" && !escaped) {
  45. setState(normal);
  46. break;
  47. }
  48. escaped = ch == "\\";
  49. }
  50. return "string";
  51. };
  52.  
  53. return function(source, startState) {
  54. return tokenizer(source, startState || normal);
  55. };
  56. })();
  57.  
  58. function indentLisp(context) {
  59. return function() {return context.indent;};
  60. }
  61.  
  62. function parseLisp(source) {
  63. var tokens = tokenizeLisp(source);
  64. var context = {indent: 0, prev: null, typed: null}, col = 0;
  65. function pushContext() {
  66. context = {prev: context, indent: col, typed: false};
  67. }
  68. function popContext() {
  69. if (context.prev) context = context.prev;
  70. }
  71.  
  72. var iter = {
  73. next: function() {
  74. var token = tokens.next(), type = token.style, content = token.content;
  75.  
  76. if (content == "\n") {
  77. token.indentation = indentLisp(context);
  78. col = 0;
  79. }
  80. else {
  81. col += token.value.length;
  82. }
  83.  
  84. if (content == "(")
  85. pushContext();
  86. else if (content == ")")
  87. popContext();
  88. else if (context.typed == false) {
  89. if (type == "special") {
  90. context.typed = true;
  91. context.indent = context.indent + 1;
  92. }
  93. else if (type != "newline" && type != "comment" && type != "whitespace") {
  94. context.typed = true;
  95. context.indent = col;
  96. }
  97. }
  98. return token;
  99. },
  100.  
  101. copy: function() {
  102. var _context = context, _col = col, _tokenState = tokens.state;
  103. return function(source) {
  104. tokens = tokenizeLisp(source, _tokenState);
  105. context = _context;
  106. col = _col;
  107. return iter;
  108. };
  109. }
  110. };
  111. return iter;
  112. }
  113.  
  114. return {make: parseLisp};
  115. })();
Add Comment
Please, Sign In to add comment