all repos — NoPaste @ 29b774f090102303e43cf939b38ac2083e62d9f1

Resurrected - The PussTheCat.org fork of NoPaste

scripts/CodeMirror/mode/ebnf/ebnf.js (view raw)

  1// CodeMirror, copyright (c) by Marijn Haverbeke and others
  2// Distributed under an MIT license: https://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 = CodeMirror.startState(bracesMode);
 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});