pig.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. // CodeMirror, copyright (c) by Marijn Haverbeke and others
  2. // Distributed under an MIT license: http://codemirror.net/LICENSE
  3. /*
  4. * Pig Latin Mode for CodeMirror 2
  5. * @author Prasanth Jayachandran
  6. * @link https://github.com/prasanthj/pig-codemirror-2
  7. * This implementation is adapted from PL/SQL mode in CodeMirror 2.
  8. */
  9. (function(mod) {
  10. if (typeof exports == "object" && typeof module == "object") // CommonJS
  11. mod(require("../../lib/codemirror"));
  12. else if (typeof define == "function" && define.amd) // AMD
  13. define(["../../lib/codemirror"], mod);
  14. else // Plain browser env
  15. mod(CodeMirror);
  16. })(function(CodeMirror) {
  17. "use strict";
  18. CodeMirror.defineMode("pig", function(_config, parserConfig) {
  19. var keywords = parserConfig.keywords,
  20. builtins = parserConfig.builtins,
  21. types = parserConfig.types,
  22. multiLineStrings = parserConfig.multiLineStrings;
  23. var isOperatorChar = /[*+\-%<>=&?:\/!|]/;
  24. function chain(stream, state, f) {
  25. state.tokenize = f;
  26. return f(stream, state);
  27. }
  28. var type;
  29. function ret(tp, style) {
  30. type = tp;
  31. return style;
  32. }
  33. function tokenComment(stream, state) {
  34. var isEnd = false;
  35. var ch;
  36. while(ch = stream.next()) {
  37. if(ch == "/" && isEnd) {
  38. state.tokenize = tokenBase;
  39. break;
  40. }
  41. isEnd = (ch == "*");
  42. }
  43. return ret("comment", "comment");
  44. }
  45. function tokenString(quote) {
  46. return function(stream, state) {
  47. var escaped = false, next, end = false;
  48. while((next = stream.next()) != null) {
  49. if (next == quote && !escaped) {
  50. end = true; break;
  51. }
  52. escaped = !escaped && next == "\\";
  53. }
  54. if (end || !(escaped || multiLineStrings))
  55. state.tokenize = tokenBase;
  56. return ret("string", "error");
  57. };
  58. }
  59. function tokenBase(stream, state) {
  60. var ch = stream.next();
  61. // is a start of string?
  62. if (ch == '"' || ch == "'")
  63. return chain(stream, state, tokenString(ch));
  64. // is it one of the special chars
  65. else if(/[\[\]{}\(\),;\.]/.test(ch))
  66. return ret(ch);
  67. // is it a number?
  68. else if(/\d/.test(ch)) {
  69. stream.eatWhile(/[\w\.]/);
  70. return ret("number", "number");
  71. }
  72. // multi line comment or operator
  73. else if (ch == "/") {
  74. if (stream.eat("*")) {
  75. return chain(stream, state, tokenComment);
  76. }
  77. else {
  78. stream.eatWhile(isOperatorChar);
  79. return ret("operator", "operator");
  80. }
  81. }
  82. // single line comment or operator
  83. else if (ch=="-") {
  84. if(stream.eat("-")){
  85. stream.skipToEnd();
  86. return ret("comment", "comment");
  87. }
  88. else {
  89. stream.eatWhile(isOperatorChar);
  90. return ret("operator", "operator");
  91. }
  92. }
  93. // is it an operator
  94. else if (isOperatorChar.test(ch)) {
  95. stream.eatWhile(isOperatorChar);
  96. return ret("operator", "operator");
  97. }
  98. else {
  99. // get the while word
  100. stream.eatWhile(/[\w\$_]/);
  101. // is it one of the listed keywords?
  102. if (keywords && keywords.propertyIsEnumerable(stream.current().toUpperCase())) {
  103. if (stream.eat(")") || stream.eat(".")) {
  104. //keywords can be used as variables like flatten(group), group.$0 etc..
  105. }
  106. else {
  107. return ("keyword", "keyword");
  108. }
  109. }
  110. // is it one of the builtin functions?
  111. if (builtins && builtins.propertyIsEnumerable(stream.current().toUpperCase()))
  112. {
  113. return ("keyword", "variable-2");
  114. }
  115. // is it one of the listed types?
  116. if (types && types.propertyIsEnumerable(stream.current().toUpperCase()))
  117. return ("keyword", "variable-3");
  118. // default is a 'variable'
  119. return ret("variable", "pig-word");
  120. }
  121. }
  122. // Interface
  123. return {
  124. startState: function() {
  125. return {
  126. tokenize: tokenBase,
  127. startOfLine: true
  128. };
  129. },
  130. token: function(stream, state) {
  131. if(stream.eatSpace()) return null;
  132. var style = state.tokenize(stream, state);
  133. return style;
  134. }
  135. };
  136. });
  137. (function() {
  138. function keywords(str) {
  139. var obj = {}, words = str.split(" ");
  140. for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
  141. return obj;
  142. }
  143. // builtin funcs taken from trunk revision 1303237
  144. var pBuiltins = "ABS ACOS ARITY ASIN ATAN AVG BAGSIZE BINSTORAGE BLOOM BUILDBLOOM CBRT CEIL "
  145. + "CONCAT COR COS COSH COUNT COUNT_STAR COV CONSTANTSIZE CUBEDIMENSIONS DIFF DISTINCT DOUBLEABS "
  146. + "DOUBLEAVG DOUBLEBASE DOUBLEMAX DOUBLEMIN DOUBLEROUND DOUBLESUM EXP FLOOR FLOATABS FLOATAVG "
  147. + "FLOATMAX FLOATMIN FLOATROUND FLOATSUM GENERICINVOKER INDEXOF INTABS INTAVG INTMAX INTMIN "
  148. + "INTSUM INVOKEFORDOUBLE INVOKEFORFLOAT INVOKEFORINT INVOKEFORLONG INVOKEFORSTRING INVOKER "
  149. + "ISEMPTY JSONLOADER JSONMETADATA JSONSTORAGE LAST_INDEX_OF LCFIRST LOG LOG10 LOWER LONGABS "
  150. + "LONGAVG LONGMAX LONGMIN LONGSUM MAX MIN MAPSIZE MONITOREDUDF NONDETERMINISTIC OUTPUTSCHEMA "
  151. + "PIGSTORAGE PIGSTREAMING RANDOM REGEX_EXTRACT REGEX_EXTRACT_ALL REPLACE ROUND SIN SINH SIZE "
  152. + "SQRT STRSPLIT SUBSTRING SUM STRINGCONCAT STRINGMAX STRINGMIN STRINGSIZE TAN TANH TOBAG "
  153. + "TOKENIZE TOMAP TOP TOTUPLE TRIM TEXTLOADER TUPLESIZE UCFIRST UPPER UTF8STORAGECONVERTER ";
  154. // taken from QueryLexer.g
  155. var pKeywords = "VOID IMPORT RETURNS DEFINE LOAD FILTER FOREACH ORDER CUBE DISTINCT COGROUP "
  156. + "JOIN CROSS UNION SPLIT INTO IF OTHERWISE ALL AS BY USING INNER OUTER ONSCHEMA PARALLEL "
  157. + "PARTITION GROUP AND OR NOT GENERATE FLATTEN ASC DESC IS STREAM THROUGH STORE MAPREDUCE "
  158. + "SHIP CACHE INPUT OUTPUT STDERROR STDIN STDOUT LIMIT SAMPLE LEFT RIGHT FULL EQ GT LT GTE LTE "
  159. + "NEQ MATCHES TRUE FALSE DUMP";
  160. // data types
  161. var pTypes = "BOOLEAN INT LONG FLOAT DOUBLE CHARARRAY BYTEARRAY BAG TUPLE MAP ";
  162. CodeMirror.defineMIME("text/x-pig", {
  163. name: "pig",
  164. builtins: keywords(pBuiltins),
  165. keywords: keywords(pKeywords),
  166. types: keywords(pTypes)
  167. });
  168. CodeMirror.registerHelper("hintWords", "pig", (pBuiltins + pTypes + pKeywords).split(" "));
  169. }());
  170. });