179 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			179 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
// CodeMirror, copyright (c) by Marijn Haverbeke and others
 | 
						|
// Distributed under an MIT license: https://codemirror.net/LICENSE
 | 
						|
 | 
						|
/*
 | 
						|
 *      Pig Latin Mode for CodeMirror 2
 | 
						|
 *      @author Prasanth Jayachandran
 | 
						|
 *      @link   https://github.com/prasanthj/pig-codemirror-2
 | 
						|
 *  This implementation is adapted from PL/SQL mode in CodeMirror 2.
 | 
						|
 */
 | 
						|
(function(mod) {
 | 
						|
  if (typeof exports == "object" && typeof module == "object") // CommonJS
 | 
						|
    mod(require("../../lib/codemirror"));
 | 
						|
  else if (typeof define == "function" && define.amd) // AMD
 | 
						|
    define(["../../lib/codemirror"], mod);
 | 
						|
  else // Plain browser env
 | 
						|
    mod(CodeMirror);
 | 
						|
})(function(CodeMirror) {
 | 
						|
"use strict";
 | 
						|
 | 
						|
CodeMirror.defineMode("pig", function(_config, parserConfig) {
 | 
						|
  var keywords = parserConfig.keywords,
 | 
						|
  builtins = parserConfig.builtins,
 | 
						|
  types = parserConfig.types,
 | 
						|
  multiLineStrings = parserConfig.multiLineStrings;
 | 
						|
 | 
						|
  var isOperatorChar = /[*+\-%<>=&?:\/!|]/;
 | 
						|
 | 
						|
  function chain(stream, state, f) {
 | 
						|
    state.tokenize = f;
 | 
						|
    return f(stream, state);
 | 
						|
  }
 | 
						|
 | 
						|
  function tokenComment(stream, state) {
 | 
						|
    var isEnd = false;
 | 
						|
    var ch;
 | 
						|
    while(ch = stream.next()) {
 | 
						|
      if(ch == "/" && isEnd) {
 | 
						|
        state.tokenize = tokenBase;
 | 
						|
        break;
 | 
						|
      }
 | 
						|
      isEnd = (ch == "*");
 | 
						|
    }
 | 
						|
    return "comment";
 | 
						|
  }
 | 
						|
 | 
						|
  function tokenString(quote) {
 | 
						|
    return function(stream, state) {
 | 
						|
      var escaped = false, next, end = false;
 | 
						|
      while((next = stream.next()) != null) {
 | 
						|
        if (next == quote && !escaped) {
 | 
						|
          end = true; break;
 | 
						|
        }
 | 
						|
        escaped = !escaped && next == "\\";
 | 
						|
      }
 | 
						|
      if (end || !(escaped || multiLineStrings))
 | 
						|
        state.tokenize = tokenBase;
 | 
						|
      return "error";
 | 
						|
    };
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
  function tokenBase(stream, state) {
 | 
						|
    var ch = stream.next();
 | 
						|
 | 
						|
    // is a start of string?
 | 
						|
    if (ch == '"' || ch == "'")
 | 
						|
      return chain(stream, state, tokenString(ch));
 | 
						|
    // is it one of the special chars
 | 
						|
    else if(/[\[\]{}\(\),;\.]/.test(ch))
 | 
						|
      return null;
 | 
						|
    // is it a number?
 | 
						|
    else if(/\d/.test(ch)) {
 | 
						|
      stream.eatWhile(/[\w\.]/);
 | 
						|
      return "number";
 | 
						|
    }
 | 
						|
    // multi line comment or operator
 | 
						|
    else if (ch == "/") {
 | 
						|
      if (stream.eat("*")) {
 | 
						|
        return chain(stream, state, tokenComment);
 | 
						|
      }
 | 
						|
      else {
 | 
						|
        stream.eatWhile(isOperatorChar);
 | 
						|
        return "operator";
 | 
						|
      }
 | 
						|
    }
 | 
						|
    // single line comment or operator
 | 
						|
    else if (ch=="-") {
 | 
						|
      if(stream.eat("-")){
 | 
						|
        stream.skipToEnd();
 | 
						|
        return "comment";
 | 
						|
      }
 | 
						|
      else {
 | 
						|
        stream.eatWhile(isOperatorChar);
 | 
						|
        return "operator";
 | 
						|
      }
 | 
						|
    }
 | 
						|
    // is it an operator
 | 
						|
    else if (isOperatorChar.test(ch)) {
 | 
						|
      stream.eatWhile(isOperatorChar);
 | 
						|
      return "operator";
 | 
						|
    }
 | 
						|
    else {
 | 
						|
      // get the while word
 | 
						|
      stream.eatWhile(/[\w\$_]/);
 | 
						|
      // is it one of the listed keywords?
 | 
						|
      if (keywords && keywords.propertyIsEnumerable(stream.current().toUpperCase())) {
 | 
						|
        //keywords can be used as variables like flatten(group), group.$0 etc..
 | 
						|
        if (!stream.eat(")") && !stream.eat("."))
 | 
						|
          return "keyword";
 | 
						|
      }
 | 
						|
      // is it one of the builtin functions?
 | 
						|
      if (builtins && builtins.propertyIsEnumerable(stream.current().toUpperCase()))
 | 
						|
        return "variable-2";
 | 
						|
      // is it one of the listed types?
 | 
						|
      if (types && types.propertyIsEnumerable(stream.current().toUpperCase()))
 | 
						|
        return "variable-3";
 | 
						|
      // default is a 'variable'
 | 
						|
      return "variable";
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  // Interface
 | 
						|
  return {
 | 
						|
    startState: function() {
 | 
						|
      return {
 | 
						|
        tokenize: tokenBase,
 | 
						|
        startOfLine: true
 | 
						|
      };
 | 
						|
    },
 | 
						|
 | 
						|
    token: function(stream, state) {
 | 
						|
      if(stream.eatSpace()) return null;
 | 
						|
      var style = state.tokenize(stream, state);
 | 
						|
      return style;
 | 
						|
    }
 | 
						|
  };
 | 
						|
});
 | 
						|
 | 
						|
(function() {
 | 
						|
  function keywords(str) {
 | 
						|
    var obj = {}, words = str.split(" ");
 | 
						|
    for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
 | 
						|
    return obj;
 | 
						|
  }
 | 
						|
 | 
						|
  // builtin funcs taken from trunk revision 1303237
 | 
						|
  var pBuiltins = "ABS ACOS ARITY ASIN ATAN AVG BAGSIZE BINSTORAGE BLOOM BUILDBLOOM CBRT CEIL "
 | 
						|
    + "CONCAT COR COS COSH COUNT COUNT_STAR COV CONSTANTSIZE CUBEDIMENSIONS DIFF DISTINCT DOUBLEABS "
 | 
						|
    + "DOUBLEAVG DOUBLEBASE DOUBLEMAX DOUBLEMIN DOUBLEROUND DOUBLESUM EXP FLOOR FLOATABS FLOATAVG "
 | 
						|
    + "FLOATMAX FLOATMIN FLOATROUND FLOATSUM GENERICINVOKER INDEXOF INTABS INTAVG INTMAX INTMIN "
 | 
						|
    + "INTSUM INVOKEFORDOUBLE INVOKEFORFLOAT INVOKEFORINT INVOKEFORLONG INVOKEFORSTRING INVOKER "
 | 
						|
    + "ISEMPTY JSONLOADER JSONMETADATA JSONSTORAGE LAST_INDEX_OF LCFIRST LOG LOG10 LOWER LONGABS "
 | 
						|
    + "LONGAVG LONGMAX LONGMIN LONGSUM MAX MIN MAPSIZE MONITOREDUDF NONDETERMINISTIC OUTPUTSCHEMA  "
 | 
						|
    + "PIGSTORAGE PIGSTREAMING RANDOM REGEX_EXTRACT REGEX_EXTRACT_ALL REPLACE ROUND SIN SINH SIZE "
 | 
						|
    + "SQRT STRSPLIT SUBSTRING SUM STRINGCONCAT STRINGMAX STRINGMIN STRINGSIZE TAN TANH TOBAG "
 | 
						|
    + "TOKENIZE TOMAP TOP TOTUPLE TRIM TEXTLOADER TUPLESIZE UCFIRST UPPER UTF8STORAGECONVERTER ";
 | 
						|
 | 
						|
  // taken from QueryLexer.g
 | 
						|
  var pKeywords = "VOID IMPORT RETURNS DEFINE LOAD FILTER FOREACH ORDER CUBE DISTINCT COGROUP "
 | 
						|
    + "JOIN CROSS UNION SPLIT INTO IF OTHERWISE ALL AS BY USING INNER OUTER ONSCHEMA PARALLEL "
 | 
						|
    + "PARTITION GROUP AND OR NOT GENERATE FLATTEN ASC DESC IS STREAM THROUGH STORE MAPREDUCE "
 | 
						|
    + "SHIP CACHE INPUT OUTPUT STDERROR STDIN STDOUT LIMIT SAMPLE LEFT RIGHT FULL EQ GT LT GTE LTE "
 | 
						|
    + "NEQ MATCHES TRUE FALSE DUMP";
 | 
						|
 | 
						|
  // data types
 | 
						|
  var pTypes = "BOOLEAN INT LONG FLOAT DOUBLE CHARARRAY BYTEARRAY BAG TUPLE MAP ";
 | 
						|
 | 
						|
  CodeMirror.defineMIME("text/x-pig", {
 | 
						|
    name: "pig",
 | 
						|
    builtins: keywords(pBuiltins),
 | 
						|
    keywords: keywords(pKeywords),
 | 
						|
    types: keywords(pTypes)
 | 
						|
  });
 | 
						|
 | 
						|
  CodeMirror.registerHelper("hintWords", "pig", (pBuiltins + pTypes + pKeywords).split(" "));
 | 
						|
}());
 | 
						|
 | 
						|
});
 |