github.com/elliott5/community@v0.14.1-0.20160709191136-823126fb026a/app/public/codemirror/mode/ebnf/ebnf.js (about)

     1  // CodeMirror, copyright (c) by Marijn Haverbeke and others
     2  // Distributed under an MIT license: http://codemirror.net/LICENSE
     3  
     4  (function(mod) {
     5    if (typeof exports == "object" && typeof module == "object") // CommonJS
     6      mod(require("../../lib/codemirror"));
     7    else if (typeof define == "function" && define.amd) // AMD
     8      define(["../../lib/codemirror"], mod);
     9    else // Plain browser env
    10      mod(CodeMirror);
    11  })(function(CodeMirror) {
    12    "use strict";
    13  
    14    CodeMirror.defineMode("ebnf", function (config) {
    15      var commentType = {slash: 0, parenthesis: 1};
    16      var stateType = {comment: 0, _string: 1, characterClass: 2};
    17      var bracesMode = null;
    18  
    19      if (config.bracesMode)
    20        bracesMode = CodeMirror.getMode(config, config.bracesMode);
    21  
    22      return {
    23        startState: function () {
    24          return {
    25            stringType: null,
    26            commentType: null,
    27            braced: 0,
    28            lhs: true,
    29            localState: null,
    30            stack: [],
    31            inDefinition: false
    32          };
    33        },
    34        token: function (stream, state) {
    35          if (!stream) return;
    36  
    37          //check for state changes
    38          if (state.stack.length === 0) {
    39            //strings
    40            if ((stream.peek() == '"') || (stream.peek() == "'")) {
    41              state.stringType = stream.peek();
    42              stream.next(); // Skip quote
    43              state.stack.unshift(stateType._string);
    44            } else if (stream.match(/^\/\*/)) { //comments starting with /*
    45              state.stack.unshift(stateType.comment);
    46              state.commentType = commentType.slash;
    47            } else if (stream.match(/^\(\*/)) { //comments starting with (*
    48              state.stack.unshift(stateType.comment);
    49              state.commentType = commentType.parenthesis;
    50            }
    51          }
    52  
    53          //return state
    54          //stack has
    55          switch (state.stack[0]) {
    56          case stateType._string:
    57            while (state.stack[0] === stateType._string && !stream.eol()) {
    58              if (stream.peek() === state.stringType) {
    59                stream.next(); // Skip quote
    60                state.stack.shift(); // Clear flag
    61              } else if (stream.peek() === "\\") {
    62                stream.next();
    63                stream.next();
    64              } else {
    65                stream.match(/^.[^\\\"\']*/);
    66              }
    67            }
    68            return state.lhs ? "property string" : "string"; // Token style
    69  
    70          case stateType.comment:
    71            while (state.stack[0] === stateType.comment && !stream.eol()) {
    72              if (state.commentType === commentType.slash && stream.match(/\*\//)) {
    73                state.stack.shift(); // Clear flag
    74                state.commentType = null;
    75              } else if (state.commentType === commentType.parenthesis && stream.match(/\*\)/)) {
    76                state.stack.shift(); // Clear flag
    77                state.commentType = null;
    78              } else {
    79                stream.match(/^.[^\*]*/);
    80              }
    81            }
    82            return "comment";
    83  
    84          case stateType.characterClass:
    85            while (state.stack[0] === stateType.characterClass && !stream.eol()) {
    86              if (!(stream.match(/^[^\]\\]+/) || stream.match(/^\\./))) {
    87                state.stack.shift();
    88              }
    89            }
    90            return "operator";
    91          }
    92  
    93          var peek = stream.peek();
    94  
    95          if (bracesMode !== null && (state.braced || peek === "{")) {
    96            if (state.localState === null)
    97              state.localState = bracesMode.startState();
    98  
    99            var token = bracesMode.token(stream, state.localState),
   100            text = stream.current();
   101  
   102            if (!token) {
   103              for (var i = 0; i < text.length; i++) {
   104                if (text[i] === "{") {
   105                  if (state.braced === 0) {
   106                    token = "matchingbracket";
   107                  }
   108                  state.braced++;
   109                } else if (text[i] === "}") {
   110                  state.braced--;
   111                  if (state.braced === 0) {
   112                    token = "matchingbracket";
   113                  }
   114                }
   115              }
   116            }
   117            return token;
   118          }
   119  
   120          //no stack
   121          switch (peek) {
   122          case "[":
   123            stream.next();
   124            state.stack.unshift(stateType.characterClass);
   125            return "bracket";
   126          case ":":
   127          case "|":
   128          case ";":
   129            stream.next();
   130            return "operator";
   131          case "%":
   132            if (stream.match("%%")) {
   133              return "header";
   134            } else if (stream.match(/[%][A-Za-z]+/)) {
   135              return "keyword";
   136            } else if (stream.match(/[%][}]/)) {
   137              return "matchingbracket";
   138            }
   139            break;
   140          case "/":
   141            if (stream.match(/[\/][A-Za-z]+/)) {
   142            return "keyword";
   143          }
   144          case "\\":
   145            if (stream.match(/[\][a-z]+/)) {
   146              return "string-2";
   147            }
   148          case ".":
   149            if (stream.match(".")) {
   150              return "atom";
   151            }
   152          case "*":
   153          case "-":
   154          case "+":
   155          case "^":
   156            if (stream.match(peek)) {
   157              return "atom";
   158            }
   159          case "$":
   160            if (stream.match("$$")) {
   161              return "builtin";
   162            } else if (stream.match(/[$][0-9]+/)) {
   163              return "variable-3";
   164            }
   165          case "<":
   166            if (stream.match(/<<[a-zA-Z_]+>>/)) {
   167              return "builtin";
   168            }
   169          }
   170  
   171          if (stream.match(/^\/\//)) {
   172            stream.skipToEnd();
   173            return "comment";
   174          } else if (stream.match(/return/)) {
   175            return "operator";
   176          } else if (stream.match(/^[a-zA-Z_][a-zA-Z0-9_]*/)) {
   177            if (stream.match(/(?=[\(.])/)) {
   178              return "variable";
   179            } else if (stream.match(/(?=[\s\n]*[:=])/)) {
   180              return "def";
   181            }
   182            return "variable-2";
   183          } else if (["[", "]", "(", ")"].indexOf(stream.peek()) != -1) {
   184            stream.next();
   185            return "bracket";
   186          } else if (!stream.eatSpace()) {
   187            stream.next();
   188          }
   189          return null;
   190        }
   191      };
   192    });
   193  
   194    CodeMirror.defineMIME("text/x-ebnf", "ebnf");
   195  });