|
- // CodeMirror, copyright (c) by Marijn Haverbeke and others
- // Distributed under an MIT license: https://codemirror.net/LICENSE
-
- (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("ebnf", function (config) {
- var commentType = {slash: 0, parenthesis: 1};
- var stateType = {comment: 0, _string: 1, characterClass: 2};
- var bracesMode = null;
-
- if (config.bracesMode)
- bracesMode = CodeMirror.getMode(config, config.bracesMode);
-
- return {
- startState: function () {
- return {
- stringType: null,
- commentType: null,
- braced: 0,
- lhs: true,
- localState: null,
- stack: [],
- inDefinition: false
- };
- },
- token: function (stream, state) {
- if (!stream) return;
-
- //check for state changes
- if (state.stack.length === 0) {
- //strings
- if ((stream.peek() == '"') || (stream.peek() == "'")) {
- state.stringType = stream.peek();
- stream.next(); // Skip quote
- state.stack.unshift(stateType._string);
- } else if (stream.match(/^\/\*/)) { //comments starting with /*
- state.stack.unshift(stateType.comment);
- state.commentType = commentType.slash;
- } else if (stream.match(/^\(\*/)) { //comments starting with (*
- state.stack.unshift(stateType.comment);
- state.commentType = commentType.parenthesis;
- }
- }
-
- //return state
- //stack has
- switch (state.stack[0]) {
- case stateType._string:
- while (state.stack[0] === stateType._string && !stream.eol()) {
- if (stream.peek() === state.stringType) {
- stream.next(); // Skip quote
- state.stack.shift(); // Clear flag
- } else if (stream.peek() === "\\") {
- stream.next();
- stream.next();
- } else {
- stream.match(/^.[^\\\"\']*/);
- }
- }
- return state.lhs ? "property string" : "string"; // Token style
-
- case stateType.comment:
- while (state.stack[0] === stateType.comment && !stream.eol()) {
- if (state.commentType === commentType.slash && stream.match(/\*\//)) {
- state.stack.shift(); // Clear flag
- state.commentType = null;
- } else if (state.commentType === commentType.parenthesis && stream.match(/\*\)/)) {
- state.stack.shift(); // Clear flag
- state.commentType = null;
- } else {
- stream.match(/^.[^\*]*/);
- }
- }
- return "comment";
-
- case stateType.characterClass:
- while (state.stack[0] === stateType.characterClass && !stream.eol()) {
- if (!(stream.match(/^[^\]\\]+/) || stream.match(/^\\./))) {
- state.stack.shift();
- }
- }
- return "operator";
- }
-
- var peek = stream.peek();
-
- if (bracesMode !== null && (state.braced || peek === "{")) {
- if (state.localState === null)
- state.localState = CodeMirror.startState(bracesMode);
-
- var token = bracesMode.token(stream, state.localState),
- text = stream.current();
-
- if (!token) {
- for (var i = 0; i < text.length; i++) {
- if (text[i] === "{") {
- if (state.braced === 0) {
- token = "matchingbracket";
- }
- state.braced++;
- } else if (text[i] === "}") {
- state.braced--;
- if (state.braced === 0) {
- token = "matchingbracket";
- }
- }
- }
- }
- return token;
- }
-
- //no stack
- switch (peek) {
- case "[":
- stream.next();
- state.stack.unshift(stateType.characterClass);
- return "bracket";
- case ":":
- case "|":
- case ";":
- stream.next();
- return "operator";
- case "%":
- if (stream.match("%%")) {
- return "header";
- } else if (stream.match(/[%][A-Za-z]+/)) {
- return "keyword";
- } else if (stream.match(/[%][}]/)) {
- return "matchingbracket";
- }
- break;
- case "/":
- if (stream.match(/[\/][A-Za-z]+/)) {
- return "keyword";
- }
- case "\\":
- if (stream.match(/[\][a-z]+/)) {
- return "string-2";
- }
- case ".":
- if (stream.match(".")) {
- return "atom";
- }
- case "*":
- case "-":
- case "+":
- case "^":
- if (stream.match(peek)) {
- return "atom";
- }
- case "$":
- if (stream.match("$$")) {
- return "builtin";
- } else if (stream.match(/[$][0-9]+/)) {
- return "variable-3";
- }
- case "<":
- if (stream.match(/<<[a-zA-Z_]+>>/)) {
- return "builtin";
- }
- }
-
- if (stream.match(/^\/\//)) {
- stream.skipToEnd();
- return "comment";
- } else if (stream.match(/return/)) {
- return "operator";
- } else if (stream.match(/^[a-zA-Z_][a-zA-Z0-9_]*/)) {
- if (stream.match(/(?=[\(.])/)) {
- return "variable";
- } else if (stream.match(/(?=[\s\n]*[:=])/)) {
- return "def";
- }
- return "variable-2";
- } else if (["[", "]", "(", ")"].indexOf(stream.peek()) != -1) {
- stream.next();
- return "bracket";
- } else if (!stream.eatSpace()) {
- stream.next();
- }
- return null;
- }
- };
- });
-
- CodeMirror.defineMIME("text/x-ebnf", "ebnf");
- });
|