PageRenderTime 80ms CodeModel.GetById 50ms app.highlight 20ms RepoModel.GetById 5ms app.codeStats 0ms

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

https://bitbucket.org/eternaware/joomus
JavaScript | 162 lines | 160 code | 2 blank | 0 comment | 36 complexity | 425eb2da0b2eecfbda0b5374ed4958cc MD5 | raw file
Possible License(s): LGPL-2.1
  1var 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
 12  var tokenizeSparql = (function() {
 13    function normal(source, setState) {
 14      var ch = source.next();
 15      if (ch == "$" || ch == "?") {
 16        source.nextWhileMatches(/[\w\d]/);
 17        return "sp-var";
 18      }
 19      else if (ch == "<" && !source.matches(/[\s\u00a0=]/)) {
 20        source.nextWhileMatches(/[^\s\u00a0>]/);
 21        if (source.equals(">")) source.next();
 22        return "sp-uri";
 23      }
 24      else if (ch == "\"" || ch == "'") {
 25        setState(inLiteral(ch));
 26        return null;
 27      }
 28      else if (/[{}\(\),\.;\[\]]/.test(ch)) {
 29        return "sp-punc";
 30      }
 31      else if (ch == "#") {
 32        while (!source.endOfLine()) source.next();
 33        return "sp-comment";
 34      }
 35      else if (operatorChars.test(ch)) {
 36        source.nextWhileMatches(operatorChars);
 37        return "sp-operator";
 38      }
 39      else if (ch == ":") {
 40        source.nextWhileMatches(/[\w\d\._\-]/);
 41        return "sp-prefixed";
 42      }
 43      else {
 44        source.nextWhileMatches(/[_\w\d]/);
 45        if (source.equals(":")) {
 46          source.next();
 47          source.nextWhileMatches(/[\w\d_\-]/);
 48          return "sp-prefixed";
 49        }
 50        var word = source.get(), type;
 51        if (ops.test(word))
 52          type = "sp-operator";
 53        else if (keywords.test(word))
 54          type = "sp-keyword";
 55        else
 56          type = "sp-word";
 57        return {style: type, content: word};
 58      }
 59    }
 60
 61    function inLiteral(quote) {
 62      return function(source, setState) {
 63        var escaped = false;
 64        while (!source.endOfLine()) {
 65          var ch = source.next();
 66          if (ch == quote && !escaped) {
 67            setState(normal);
 68            break;
 69          }
 70          escaped = !escaped && ch == "\\";
 71        }
 72        return "sp-literal";
 73      };
 74    }
 75
 76    return function(source, startState) {
 77      return tokenizer(source, startState || normal);
 78    };
 79  })();
 80
 81  function indentSparql(context) {
 82    return function(nextChars) {
 83      var firstChar = nextChars && nextChars.charAt(0);
 84      if (/[\]\}]/.test(firstChar))
 85        while (context && context.type == "pattern") context = context.prev;
 86
 87      var closing = context && firstChar == matching[context.type];
 88      if (!context)
 89        return 0;
 90      else if (context.type == "pattern")
 91        return context.col;
 92      else if (context.align)
 93        return context.col - (closing ? context.width : 0);
 94      else
 95        return context.indent + (closing ? 0 : indentUnit);
 96    }
 97  }
 98
 99  function parseSparql(source) {
100    var tokens = tokenizeSparql(source);
101    var context = null, indent = 0, col = 0;
102    function pushContext(type, width) {
103      context = {prev: context, indent: indent, col: col, type: type, width: width};
104    }
105    function popContext() {
106      context = context.prev;
107    }
108
109    var iter = {
110      next: function() {
111        var token = tokens.next(), type = token.style, content = token.content, width = token.value.length;
112
113        if (content == "\n") {
114          token.indentation = indentSparql(context);
115          indent = col = 0;
116          if (context && context.align == null) context.align = false;
117        }
118        else if (type == "whitespace" && col == 0) {
119          indent = width;
120        }
121        else if (type != "sp-comment" && context && context.align == null) {
122          context.align = true;
123        }
124
125        if (content != "\n") col += width;
126
127        if (/[\[\{\(]/.test(content)) {
128          pushContext(content, width);
129        }
130        else if (/[\]\}\)]/.test(content)) {
131          while (context && context.type == "pattern")
132            popContext();
133          if (context && content == matching[context.type])
134            popContext();
135        }
136        else if (content == "." && context && context.type == "pattern") {
137          popContext();
138        }
139        else if ((type == "sp-word" || type == "sp-prefixed" || type == "sp-uri" || type == "sp-var" || type == "sp-literal") &&
140                 context && /[\{\[]/.test(context.type)) {
141          pushContext("pattern", width);
142        }
143
144        return token;
145      },
146
147      copy: function() {
148        var _context = context, _indent = indent, _col = col, _tokenState = tokens.state;
149        return function(source) {
150          tokens = tokenizeSparql(source, _tokenState);
151          context = _context;
152          indent = _indent;
153          col = _col;
154          return iter;
155        };
156      }
157    };
158    return iter;
159  }
160
161  return {make: parseSparql, electricChars: "}]"};
162})();