openrat-cms

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

ebnf.js (6085B)


      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 = 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 });