/media/editors/codemirror/js/parsesparql.js

https://bitbucket.org/eternaware/joomus · JavaScript · 162 lines · 149 code · 13 blank · 0 comment · 95 complexity · 425eb2da0b2eecfbda0b5374ed4958cc MD5 · raw file

  1. var SparqlParser = Editor.Parser = (function() {
  2. function wordRegexp(words) {
  3. return new RegExp("^(?:" + words.join("|") + ")$", "i");
  4. }
  5. var ops = wordRegexp(["str", "lang", "langmatches", "datatype", "bound", "sameterm", "isiri", "isuri",
  6. "isblank", "isliteral", "union", "a"]);
  7. var keywords = wordRegexp(["base", "prefix", "select", "distinct", "reduced", "construct", "describe",
  8. "ask", "from", "named", "where", "order", "limit", "offset", "filter", "optional",
  9. "graph", "by", "asc", "desc"]);
  10. var operatorChars = /[*+\-<>=&|]/;
  11. var tokenizeSparql = (function() {
  12. function normal(source, setState) {
  13. var ch = source.next();
  14. if (ch == "$" || ch == "?") {
  15. source.nextWhileMatches(/[\w\d]/);
  16. return "sp-var";
  17. }
  18. else if (ch == "<" && !source.matches(/[\s\u00a0=]/)) {
  19. source.nextWhileMatches(/[^\s\u00a0>]/);
  20. if (source.equals(">")) source.next();
  21. return "sp-uri";
  22. }
  23. else if (ch == "\"" || ch == "'") {
  24. setState(inLiteral(ch));
  25. return null;
  26. }
  27. else if (/[{}\(\),\.;\[\]]/.test(ch)) {
  28. return "sp-punc";
  29. }
  30. else if (ch == "#") {
  31. while (!source.endOfLine()) source.next();
  32. return "sp-comment";
  33. }
  34. else if (operatorChars.test(ch)) {
  35. source.nextWhileMatches(operatorChars);
  36. return "sp-operator";
  37. }
  38. else if (ch == ":") {
  39. source.nextWhileMatches(/[\w\d\._\-]/);
  40. return "sp-prefixed";
  41. }
  42. else {
  43. source.nextWhileMatches(/[_\w\d]/);
  44. if (source.equals(":")) {
  45. source.next();
  46. source.nextWhileMatches(/[\w\d_\-]/);
  47. return "sp-prefixed";
  48. }
  49. var word = source.get(), type;
  50. if (ops.test(word))
  51. type = "sp-operator";
  52. else if (keywords.test(word))
  53. type = "sp-keyword";
  54. else
  55. type = "sp-word";
  56. return {style: type, content: word};
  57. }
  58. }
  59. function inLiteral(quote) {
  60. return function(source, setState) {
  61. var escaped = false;
  62. while (!source.endOfLine()) {
  63. var ch = source.next();
  64. if (ch == quote && !escaped) {
  65. setState(normal);
  66. break;
  67. }
  68. escaped = !escaped && ch == "\\";
  69. }
  70. return "sp-literal";
  71. };
  72. }
  73. return function(source, startState) {
  74. return tokenizer(source, startState || normal);
  75. };
  76. })();
  77. function indentSparql(context) {
  78. return function(nextChars) {
  79. var firstChar = nextChars && nextChars.charAt(0);
  80. if (/[\]\}]/.test(firstChar))
  81. while (context && context.type == "pattern") context = context.prev;
  82. var closing = context && firstChar == matching[context.type];
  83. if (!context)
  84. return 0;
  85. else if (context.type == "pattern")
  86. return context.col;
  87. else if (context.align)
  88. return context.col - (closing ? context.width : 0);
  89. else
  90. return context.indent + (closing ? 0 : indentUnit);
  91. }
  92. }
  93. function parseSparql(source) {
  94. var tokens = tokenizeSparql(source);
  95. var context = null, indent = 0, col = 0;
  96. function pushContext(type, width) {
  97. context = {prev: context, indent: indent, col: col, type: type, width: width};
  98. }
  99. function popContext() {
  100. context = context.prev;
  101. }
  102. var iter = {
  103. next: function() {
  104. var token = tokens.next(), type = token.style, content = token.content, width = token.value.length;
  105. if (content == "\n") {
  106. token.indentation = indentSparql(context);
  107. indent = col = 0;
  108. if (context && context.align == null) context.align = false;
  109. }
  110. else if (type == "whitespace" && col == 0) {
  111. indent = width;
  112. }
  113. else if (type != "sp-comment" && context && context.align == null) {
  114. context.align = true;
  115. }
  116. if (content != "\n") col += width;
  117. if (/[\[\{\(]/.test(content)) {
  118. pushContext(content, width);
  119. }
  120. else if (/[\]\}\)]/.test(content)) {
  121. while (context && context.type == "pattern")
  122. popContext();
  123. if (context && content == matching[context.type])
  124. popContext();
  125. }
  126. else if (content == "." && context && context.type == "pattern") {
  127. popContext();
  128. }
  129. else if ((type == "sp-word" || type == "sp-prefixed" || type == "sp-uri" || type == "sp-var" || type == "sp-literal") &&
  130. context && /[\{\[]/.test(context.type)) {
  131. pushContext("pattern", width);
  132. }
  133. return token;
  134. },
  135. copy: function() {
  136. var _context = context, _indent = indent, _col = col, _tokenState = tokens.state;
  137. return function(source) {
  138. tokens = tokenizeSparql(source, _tokenState);
  139. context = _context;
  140. indent = _indent;
  141. col = _col;
  142. return iter;
  143. };
  144. }
  145. };
  146. return iter;
  147. }
  148. return {make: parseSparql, electricChars: "}]"};
  149. })();