pig.js 5.8 KB

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