亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? scanner.java

?? MSP IM Source code 2008 update
?? JAVA
字號:
package se.sics.mspsim.extutil.highlight;import java.util.HashMap;// Public domain, no restrictions, Ian Holyer, University of Bristol./** * <p> * A Scanner object provides a lexical analyser and a resulting token array. * Incremental rescanning is supported, e.g. for use in a token colouring * editor. This is a base class dealing with plain text, which can be extended * to support other languages. *  * <p> * The actual text is assumed to be held elsewhere, e.g. in a document. The * <code>change()</code> method is called to report the position and length of * a change in the text, and the <code>scan()</code> method is called to * perform scanning or rescanning. For example, to scan an entire document held * in a character array <code>text</code> in one go: *  * <blockquote> *  * <pre> * scanner.change(0, 0, text.length); * scanner.scan(text, 0, text.length); * </pre> *  * </blockquote> *  * <p> * For incremental scanning, the <code>position()</code> method is used to * find the text position at which rescanning should start. For example, a * syntax highlighter might contain this code: *  * <blockquote> *  * <pre> * // Where to start rehighlighting, and a segment object * int firstRehighlightToken; * Segment segment; * ... * // Whenever the text changes, e.g. on an insert or remove or read. * firstRehighlightToken = scanner.change(offset, oldLength, newLength); * repaint(); * ... * // in repaintComponent * int offset = scanner.position(); * if (offset &lt; 0) return; * int tokensToRedo = 0; * int amount = 100; * while (tokensToRedo == 0 &amp;&amp; offset &gt;= 0) * { *    int length = doc.getLength() - offset; *    if (length &gt; amount) length = amount; *    try { doc.getText(offset, length, text); } *    catch (BadLocationException e) { return; } *    tokensToRedo = scanner.scan(text.array, text.offset, text.count); *    offset = scanner.position(); *    amount = 2*amount; * } * for (int i = 0; i &lt; tokensToRedo; i++) * { *    Token t = scanner.getToken(firstRehighlightToken + i); *    int length = t.symbol.name.length(); *    int type = t.symbol.type; *    doc.setCharacterAttributes (t.position, length, styles[type], false); * } * firstRehighlightToken += tokensToRedo; * if (offset &gt;= 0) repaint(2); * </pre> *  * </blockquote> *  * <p> * Note that <code>change</code> can be called at any time, even between calls * to <code>scan</code>. Only small number of characters are passed to * <code>scan</code> so that only a small burst of scanning is done, to * prevent the program's user interface from freezing. */public class Scanner implements TokenTypes {  /**   * <p>   * Read one token from the start of the current text buffer, given the start   * offset, end offset, and current scanner state. The method moves the start   * offset past the token, updates the scanner state, and returns the type of   * the token just scanned.   *    * <p>   * The scanner state is a representative token type. It is either the state   * left after the last call to read, or the type of the old token at the same   * position if rescanning, or WHITESPACE if at the start of a document. The   * method succeeds in all cases, returning whitespace or comment or error   * tokens where necessary. Each line of a multi-line comment is treated as a   * separate token, to improve incremental rescanning. If the buffer does not   * extend to the end of the document, the last token returned for the buffer   * may be incomplete and the caller must rescan it. The read method can be   * overridden to implement different languages. The default version splits   * plain text into words, numbers and punctuation.   */  protected int read() {    char c = buffer[start];    int type;    // Ignore the state, since there is only one.    if (Character.isWhitespace(c)) {      type = WHITESPACE;      while (++start < end) {        if (!Character.isWhitespace(buffer[start]))          break;      }    } else if (Character.isLetter(c)) {      type = WORD;      while (++start < end) {        c = buffer[start];        if (Character.isLetter(c) || Character.isDigit(c))          continue;        if (c == '-' || c == '\'' || c == '_')          continue;        break;      }    } else if (Character.isDigit(c)) {      type = NUMBER;      while (++start < end) {        c = buffer[start];        if (!Character.isDigit(c) && c != '.')          break;      }    } else if (c >= '!' || c <= '~') {      type = PUNCTUATION;      start++;    } else {      type = UNRECOGNIZED;      start++;    }    // state = WHITESPACE;    return type;  }  /**   * The current buffer of text being scanned.   */  protected char[] buffer;  /**   * The current offset within the buffer, at which to scan the next token.   */  protected int start;  /**   * The end offset in the buffer.   */  protected int end;  /**   * The current scanner state, as a representative token type.   */  protected int state = WHITESPACE;  // The array of tokens forms a gap buffer. The total length of the text is  // tracked, and tokens after the gap have (negative) positions relative to  // the end of the text. While scanning, the gap represents the area to be  // scanned, no tokens after the gap can be taken as valid, and in particular  // the end-of-text sentinel token is after the gap.  private Token[] tokens;  private int gap, endgap, textLength;  private boolean scanning;  private int position;  /**   * The symbol table can be accessed by <code>initSymbolTable</code> or   * <code>lookup</code>, if they are overridden. Symbols are inserted with   * <code>symbolTable.put(sym,sym)</code> and extracted with   * <code>symbolTable.get(sym)</code>.   */  protected HashMap<Symbol,Symbol> symbolTable;  /**   * Create a new Scanner representing an empty text document. For   * non-incremental scanning, use change() to report the document size, then   * pass the entire text to the scan() method in one go, or if coming from an   * input stream, a bufferful at a time.   */  public Scanner() {    tokens = new Token[1];    gap = 0;    endgap = 0;    textLength = 0;    symbolTable = new HashMap<Symbol,Symbol>();    initSymbolTable();    Symbol endOfText = new Symbol(WHITESPACE, "");    tokens[0] = new Token(endOfText, 0);    scanning = false;    position = 0;  }  // Move the gap to a new index within the tokens array. When preparing to  // pass a token back to a caller, this is used to ensure that the token's  // position is relative to the start of the text and not the end.  private void moveGap(int newgap) {    if (scanning)      throw new Error("moveGap called while scanning");    if (newgap < 0 || newgap > gap + tokens.length - endgap) {      throw new Error("bad argument to moveGap");    }    if (gap < newgap) {      while (gap < newgap) {        tokens[endgap].position += textLength;        tokens[gap++] = tokens[endgap++];      }    } else if (gap > newgap) {      while (gap > newgap) {        tokens[--endgap] = tokens[--gap];        tokens[endgap].position -= textLength;      }    }  }  /**   * Find the number of available valid tokens, not counting tokens in or after   * any area yet to be rescanned.   */  public int size() {    if (scanning) {      return gap;    }    return gap + tokens.length - endgap;  }  /**   * Find the n'th token, or null if it is not currently valid.   */  public Token getToken(int n) {    if (n < 0 || n >= gap && scanning)      return null;    if (n >= gap)      moveGap(n + 1);    return tokens[n];  }  /**   * Find the index of the valid token starting before, but nearest to, text   * position p. This uses an O(log(n)) binary chop search.   */  public int find(int p) {    int start = 0, end, mid, midpos;    if (!scanning)      moveGap(gap + tokens.length - endgap);    end = gap - 1;    if (p > tokens[end].position)      return end;    while (end > start + 1) {      mid = (start + end) / 2;      midpos = tokens[mid].position;      if (p > midpos) {        start = mid;      } else {        end = mid;      }    }    return start;  }  /**   * Report the position of an edit, the length of the text being replaced, and   * the length of the replacement text, to prepare for rescanning. The call   * returns the index of the token at which rescanning will start.   */  public int change(int start, int len, int newLen) {    if (start < 0 || len < 0 || newLen < 0 || start + len > textLength) {      throw new Error("change(" + start + "," + len + "," + newLen + ")");    }    textLength += newLen - len;    int end = start + newLen;    if (scanning) {      while (gap > 0 && tokens[gap - 1].position > start)        gap--;      if (gap > 0)        gap--;      if (gap > 0) {        gap--;        position = tokens[gap].position;        state = tokens[gap].symbol.type;      } else {        position = 0;        state = WHITESPACE;      }      while (tokens[endgap].position + textLength < end)        endgap++;      return gap;    }    if (endgap == tokens.length)      moveGap(gap - 1);    scanning = true;    while (tokens[endgap].position + textLength < start) {      tokens[endgap].position += textLength;      tokens[gap++] = tokens[endgap++];    }    while (gap > 0 && tokens[gap - 1].position > start) {      tokens[--endgap] = tokens[--gap];      tokens[endgap].position -= textLength;    }    if (gap > 0)      gap--;    if (gap > 0) {      gap--;      position = tokens[gap].position;      state = tokens[gap].symbol.type;    } else {      position = 0;      state = WHITESPACE;    }    while (tokens[endgap].position + textLength < end)      endgap++;    return gap;  }  /**   * Find out at what text position any remaining scanning work should start, or   * -1 if scanning is complete.   */  public int position() {    if (!scanning) {      return -1;    }    return position;  }  /**   * Create the initial symbol table. This can be overridden to enter keywords,   * for example. The default implementation does nothing.   */  protected void initSymbolTable() {    // Nothing as default  }  // Reuse this symbol object to create each new symbol, then look it up in  // the symbol table, to replace it by a shared version to minimize space.  private Symbol symbol = new Symbol(0, null);  /**   * Lookup a symbol in the symbol table. This can be overridden to implement   * keyword detection, for example. The default implementation just uses the   * table to ensure that there is only one shared occurrence of each symbol.   */  protected Symbol lookup(int type, String name) {    symbol.type = type;    symbol.name = name;    Symbol sym = symbolTable.get(symbol);    if (sym != null) {      return sym;    }    sym = new Symbol(type, name);    symbolTable.put(sym, sym);    return sym;  }  /**   * Scan or rescan a given read-only segment of text. The segment is assumed to   * represent a portion of the document starting at <code>position()</code>.   * Return the number of tokens successfully scanned, excluding any partial   * token at the end of the text segment but not at the end of the document. If   * the result is 0, the call should be retried with a longer segment.   */  public int scan(char[] array, int offset, int length) {    if (!scanning)      throw new Error("scan called when not scanning");    if (position + length > textLength)      throw new Error("scan too much");    boolean all = position + length == textLength;    end = start + length;    int startGap = gap;    buffer = array;    start = offset;    end = start + length;    while (start < end) {      int tokenStart = start;      int type = read();      if (start == end && !all)        break;      if (type != WHITESPACE) {        String name = new String(buffer, tokenStart, start - tokenStart);        Symbol sym = lookup(type, name);        Token t = new Token(sym, position);        if (gap >= endgap)          checkCapacity(gap + tokens.length - endgap + 1);        tokens[gap++] = t;      }      // Try to synchronise      while (tokens[endgap].position + textLength < position)        endgap++;      if (position + start - tokenStart == textLength)        scanning = false;      else if (gap > 0 && tokens[endgap].position + textLength == position          && tokens[endgap].symbol.type == type) {        endgap++;        scanning = false;        break;      }      position += start - tokenStart;    }    checkCapacity(gap + tokens.length - endgap);    return gap - startGap;  }  // Change the size of the gap buffer, doubling it if it fills up, and  // halving if it becomes less than a quarter full.  private void checkCapacity(int capacity) {    int oldCapacity = tokens.length;    if (capacity <= oldCapacity && 4 * capacity >= oldCapacity)      return;    Token[] oldTokens = tokens;    int newCapacity;    if (capacity > oldCapacity) {      newCapacity = oldCapacity * 2;      if (newCapacity < capacity)        newCapacity = capacity;    } else      newCapacity = capacity * 2;    tokens = new Token[newCapacity];    System.arraycopy(oldTokens, 0, tokens, 0, gap);    int n = oldCapacity - endgap;    System.arraycopy(oldTokens, endgap, tokens, newCapacity - n, n);    endgap = newCapacity - n;  }  void print() {    for (int i = 0; i < tokens.length; i++) {      if (i >= gap && i < endgap)        continue;      if (i == endgap)        System.out.print("... ");      System.out.print("" + i + ":" + tokens[i].position);      System.out.print("-"          + (tokens[i].position + tokens[i].symbol.name.length()));      System.out.print(" ");    }    System.out.println();  }}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
99精品视频在线观看| 久久免费精品国产久精品久久久久 | 国产曰批免费观看久久久| 国产成+人+日韩+欧美+亚洲| 欧美日韩一区二区三区在线| 国产视频911| 日日欢夜夜爽一区| 91网站在线播放| 欧美α欧美αv大片| 亚洲五月六月丁香激情| 不卡的电影网站| 精品国产精品网麻豆系列| 亚洲午夜av在线| 91亚洲精华国产精华精华液| wwww国产精品欧美| 日本不卡视频一二三区| 日本韩国欧美三级| 中文字幕一区二区在线观看| 国产一区二区三区| 日韩欧美久久一区| 天堂精品中文字幕在线| 欧美亚洲国产一区在线观看网站| 欧美国产成人在线| 韩国中文字幕2020精品| 日韩一区二区视频| 日韩精品一卡二卡三卡四卡无卡| 色香蕉成人二区免费| 国产精品久久久久桃色tv| 国产成人三级在线观看| 久久久久99精品一区| 狠狠狠色丁香婷婷综合久久五月| 日韩一区二区三区高清免费看看| 图片区小说区区亚洲影院| 欧美性色欧美a在线播放| 亚洲精品视频免费看| 91免费视频网| 夜色激情一区二区| 欧美日韩国产精选| 日韩av一区二区三区四区| 欧美日韩午夜精品| 日韩成人dvd| 欧美大片日本大片免费观看| 久久国产欧美日韩精品| 精品粉嫩超白一线天av| 国产高清无密码一区二区三区| 久久久久国产精品厨房| 成人动漫在线一区| 亚洲精品一二三四区| 欧美亚洲免费在线一区| 日本在线不卡视频| 26uuu精品一区二区| 成人免费三级在线| 亚洲精品中文在线| 欧美一区二区三区在线看| 九一久久久久久| 国产精品麻豆久久久| 日本电影欧美片| 日本不卡中文字幕| 国产亚洲欧美中文| 一本大道综合伊人精品热热| 视频在线观看国产精品| 精品福利av导航| av不卡在线播放| 肉肉av福利一精品导航| 国产亚洲欧美一区在线观看| 色综合久久精品| 美国三级日本三级久久99| 国产精品国产三级国产有无不卡| 在线亚洲免费视频| 久久国产生活片100| 国产精品久久久久久久久久免费看 | 亚洲狠狠丁香婷婷综合久久久| 欧美肥妇bbw| 国产成人免费视频网站高清观看视频| 中文字幕日韩一区| 日韩一区二区三区视频在线观看 | 国产成人精品免费| 亚洲成av人片在www色猫咪| 久久精品人人做人人综合| 欧美午夜不卡在线观看免费| 精品一区二区三区免费观看| 综合在线观看色| 精品国产一区二区三区久久久蜜月 | 久久久久久久综合| 欧美午夜精品久久久久久孕妇| 狠狠色综合色综合网络| 亚洲国产一区视频| 中文字幕精品在线不卡| 日韩欧美专区在线| 欧美视频一区二区三区四区| 国产成人精品亚洲日本在线桃色| 亚洲国产cao| 亚洲视频狠狠干| 国产丝袜欧美中文另类| 91精品国产综合久久精品app| 粉嫩绯色av一区二区在线观看| 日本一不卡视频| 亚洲影视在线观看| 亚洲视频香蕉人妖| 欧美激情在线看| 久久女同精品一区二区| 欧美r级在线观看| 在线观看91av| 欧美日韩成人综合天天影院| 一本色道亚洲精品aⅴ| 成人黄色av网站在线| 国产精品综合网| 激情综合色播激情啊| 免费xxxx性欧美18vr| 日韩**一区毛片| 首页国产丝袜综合| 五月天婷婷综合| 天天影视涩香欲综合网| 亚洲成人中文在线| 天堂va蜜桃一区二区三区| 天堂午夜影视日韩欧美一区二区| 亚洲一区二区三区中文字幕| 一区二区三区波多野结衣在线观看| 国产精品第一页第二页第三页| 国产精品女同一区二区三区| 国产精品网友自拍| 1区2区3区国产精品| 亚洲精品日韩专区silk| 亚洲一区av在线| 丝袜亚洲另类丝袜在线| 美女看a上一区| 国产在线不卡视频| 成人深夜福利app| 99免费精品在线观看| 欧美亚洲另类激情小说| 91精品国产91久久久久久一区二区 | 奇米一区二区三区| 精品在线你懂的| 国产91精品一区二区麻豆网站| 成人丝袜18视频在线观看| av中文字幕一区| 欧美丝袜丝nylons| 欧美一区二区三区在线| 久久久久久久国产精品影院| 中文在线资源观看网站视频免费不卡| 国产精品伦一区| 午夜视频在线观看一区二区三区 | 最新日韩av在线| 亚洲一区二区三区不卡国产欧美| 日韩成人一区二区| 国产v综合v亚洲欧| 色av一区二区| 精品久久久久久久久久久院品网 | 国产精品久久久久精k8| 亚洲激情自拍视频| 久久99九九99精品| 色综合久久久久网| 精品成人佐山爱一区二区| 亚洲图片欧美激情| 麻豆国产精品777777在线| 成人国产精品免费观看| 制服视频三区第一页精品| 国产欧美日韩精品在线| 五月天丁香久久| 粉嫩欧美一区二区三区高清影视| 欧美性生活一区| 国产精品天美传媒| 日本亚洲电影天堂| 99久久精品国产导航| 欧美va亚洲va国产综合| 一区二区三区在线免费视频 | 日韩区在线观看| 亚洲人成网站精品片在线观看| 日本欧美一区二区三区| 99在线精品一区二区三区| 日韩欧美国产小视频| 亚洲尤物视频在线| av电影天堂一区二区在线| 日韩欧美色综合| 亚洲一区二区三区四区在线观看| 国产麻豆9l精品三级站| 欧美一区二区视频在线观看2022 | eeuss国产一区二区三区| 精品日韩欧美一区二区| 亚洲18女电影在线观看| 色域天天综合网| 欧美国产欧美综合| 国产又黄又大久久| 日韩欧美电影一二三| 亚洲成av人片一区二区梦乃| 91欧美一区二区| 国产精品第一页第二页第三页 | 亚洲国产欧美日韩另类综合| 成人午夜又粗又硬又大| 久久影视一区二区| 久久超级碰视频| 欧美sm美女调教| 极品少妇xxxx偷拍精品少妇| 91精品国产综合久久久久久| 亚洲成av人片在线观看无码| 欧美三级中文字幕| 亚洲成a人v欧美综合天堂下载| 欧美在线观看一区二区| 一区av在线播放| 欧美午夜精品一区二区蜜桃|