Package org.eclipse.jdi.internal

Source Code of org.eclipse.jdi.internal.SourceDebugExtensionParser$Lexer

/*******************************************************************************
*  Copyright (c) 2003, 2012 IBM Corporation and others.
*  All rights reserved. This program and the accompanying materials
*  are made available under the terms of the Eclipse Public License v1.0
*  which accompanies this distribution, and is available at
*  http://www.eclipse.org/legal/epl-v10.html
*
*  Contributors:
*     IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdi.internal;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.osgi.util.NLS;

import com.sun.jdi.AbsentInformationException;

/**
*
*/
public class SourceDebugExtensionParser {

  private static class Lexer {

    static final int UNKNOWN = 0;
    static final int SMAP = 1;
    static final int NON_ASTERISK_STRING = 2;
    static final int NUMBER = 3;
    static final int CR = 4;
    static final int ASTERISK_CHAR = 5;
    static final int ASTERISK_C = 6;
    static final int ASTERISK_E = 7;
    static final int ASTERISK_F = 8;
    static final int ASTERISK_L = 9;
    static final int ASTERISK_O = 10;
    static final int ASTERISK_S = 11;
    static final int ASTERISK_V = 12;
    // never used
    // static final int WHITE_SPACE= 13;
    static final int COLON = 14;
    static final int COMMA = 15;
    static final int SHARP = 16;
    static final int PLUS = 17;

    private char[] fSmap;
    private int fPointer;
    private char fChar;

    private char[] fLexem;
    private int fLexemType;

    private boolean fEOF;

    public Lexer(String smap) {
      fSmap = smap.toCharArray();
      fLexemType = UNKNOWN;
      fPointer = -1;
      nextChar();
    }

    /**
     * Compute the next lexem.
     *
     * @return the type of the next lexem.
     */
    public int nextLexem() throws AbsentInformationException {
      if (fEOF) {
        throw new AbsentInformationException(
            JDIMessages.SourceDebugExtensionParser_0);
      }
      startWith();
      return fLexemType;
    }

    private char nextChar() {
      if (++fPointer == fSmap.length) {
        fEOF = true;
        return '\000';
      }
      fChar = fSmap[fPointer];
      return fChar;
    }

    private void startWith() throws AbsentInformationException {
      switch (fChar) {
      case '\n':
      case '\r':
        startWithCR();
        break;
      case '*':
        startWithAsterisk();
        break;
      case ':':
        fLexem = new char[] { ':' };
        fLexemType = COLON;
        nextChar();
        break;
      case ',':
        fLexem = new char[] { ',' };
        fLexemType = COMMA;
        nextChar();
        break;
      case '#':
        fLexem = new char[] { '#' };
        fLexemType = SHARP;
        nextChar();
        break;
      case '+':
        fLexem = new char[] { '+' };
        fLexemType = PLUS;
        nextChar();
        break;
      default:
        startWithOtherChar();
        break;
      }
    }

    /**
     *
     */
    private void startWithOtherChar() {
      int lexemStart = fPointer;
      consumeWhiteSpace();
      if (fChar >= '0' && fChar <= '9') { // a number
        number(lexemStart);
      } else {
        nonAsteriskString(lexemStart);
      }
    }

    /**
     * @param lexemStart
     */
    private void nonAsteriskString(int lexemStart) {
      while (fChar != '\n' && fChar != '\r' && !fEOF) {
        nextChar();
      }
      int length = fPointer - lexemStart;
      fLexem = new char[length];
      System.arraycopy(fSmap, lexemStart, fLexem, 0, length);
      if (length == 4 && fLexem[0] == 'S' && fLexem[1] == 'M'
          && fLexem[2] == 'A' && fLexem[3] == 'P') {
        fLexemType = SMAP;
      } else {
        fLexemType = NON_ASTERISK_STRING;
      }
    }

    /**
     * @param lexemStart
     */
    private void number(int lexemStart) {
      while (fChar >= '0' && fChar <= '9') {
        nextChar();
      }
      consumeWhiteSpace();
      fLexemType = NUMBER;
      int length = fPointer - lexemStart;
      fLexem = new char[length];
      System.arraycopy(fSmap, lexemStart, fLexem, 0, length);
    }

    /**
     *
     */
    private void startWithAsterisk() throws AbsentInformationException {
      nextChar();
      if (fEOF) {
        throw new AbsentInformationException(
            JDIMessages.SourceDebugExtensionParser_0);
      }
      switch (fChar) {
      case 'C':
        fLexemType = ASTERISK_C;
        break;
      case 'E':
        fLexemType = ASTERISK_E;
        break;
      case 'F':
        fLexemType = ASTERISK_F;
        break;
      case 'L':
        fLexemType = ASTERISK_L;
        break;
      case 'O':
        fLexemType = ASTERISK_O;
        break;
      case 'S':
        fLexemType = ASTERISK_S;
        break;
      case 'V':
        fLexemType = ASTERISK_V;
        break;
      default:
        fLexemType = ASTERISK_CHAR;
        break;
      }
      fLexem = new char[] { '*', fChar };
      nextChar();
    }

    /**
     *
     */
    private void startWithCR() {
      if (fChar == '\r') {
        if (nextChar() == '\n') {
          fLexem = new char[] { '\r', '\n' };
          nextChar();
        } else {
          fLexem = new char[] { '\r' };
        }
      } else {
        fLexem = new char[] { fChar };
        nextChar();
      }
      fLexemType = CR;
    }

    /**
     *
     */
    private void consumeWhiteSpace() {
      while (fChar == ' ' || fChar == '\t') {
        nextChar();
      }
    }

    /**
     * @return the value of the current lexem.
     */
    public char[] lexem() {
      return fLexem;
    }

    /**
     * @return the type of the current lexem.
     */
    public int lexemType() {
      return fLexemType;
    }

  }

  /**
   * The reference type to which this source debug extension is associated.
   */
  private ReferenceTypeImpl fReferenceType;

  private List<String> fDefinedStrata;

  // parser data;
  private ReferenceTypeImpl.Stratum fCurrentStratum;
  private boolean fFileSectionDefinedForCurrentStratum;
  private boolean fLineSectionDefinedForCurrentStratum;
  private int fCurrentLineFileId;

  public static void parse(String smap, ReferenceTypeImpl referenceType)
      throws AbsentInformationException {
    new SourceDebugExtensionParser(referenceType).parseSmap(smap);
  }

  /**
   * SourceDebugExtension constructor.
   */
  private SourceDebugExtensionParser(ReferenceTypeImpl referenceType) {
    fReferenceType = referenceType;
    fDefinedStrata = new ArrayList<String>();
    fDefinedStrata.add(VirtualMachineImpl.JAVA_STRATUM_NAME);
  }

  /**
   *
   */
  private void parseSmap(String smap) throws AbsentInformationException {
    Lexer lexer = new Lexer(smap);
    parseHeader(lexer);
    parseSections(lexer);
    if (!fDefinedStrata.contains(fReferenceType.defaultStratum())) {
      throw new AbsentInformationException(
          JDIMessages.SourceDebugExtensionParser_2);
    }
  }

  /**
   * @param lexer
   */
  private void parseHeader(Lexer lexer) throws AbsentInformationException {
    int lexemType = lexer.nextLexem();
    if (lexemType != Lexer.SMAP) {
      throw new AbsentInformationException(
          JDIMessages.SourceDebugExtensionParser_3);
    }
    if (lexer.nextLexem() != Lexer.CR) {
      throw new AbsentInformationException(
          JDIMessages.SourceDebugExtensionParser_4);
    }
    if (isAsteriskLexem(lexer.nextLexem())) {
      throw new AbsentInformationException(
          JDIMessages.SourceDebugExtensionParser_5);
    }
    fReferenceType.setOutputFileName(getNonAsteriskString(lexer));
    if (isAsteriskLexem(lexer.lexemType())) {
      throw new AbsentInformationException(
          JDIMessages.SourceDebugExtensionParser_6);
    }
    fReferenceType.setDefaultStratumId(getNonAsteriskString(lexer));
  }

  /**
   * @param lexer
   */
  private void parseSections(Lexer lexer) throws AbsentInformationException {
    while (lexer.lexemType() != Lexer.ASTERISK_E) {
      parseStratumSection(lexer);
    }
  }

  /**
   * @param lexer
   */
  private void parseStratumSection(Lexer lexer)
      throws AbsentInformationException {
    if (lexer.lexemType() != Lexer.ASTERISK_S) {
      throw new AbsentInformationException(
          JDIMessages.SourceDebugExtensionParser_7);
    }
    if (isAsteriskLexem(lexer.nextLexem())) {
      throw new AbsentInformationException(
          JDIMessages.SourceDebugExtensionParser_8);
    }
    String stratumId = getNonAsteriskString(lexer);
    if (fDefinedStrata.contains(stratumId)) {
      throw new AbsentInformationException(NLS.bind(
          JDIMessages.SourceDebugExtensionParser_9,
          new String[] { stratumId }));
    }
    fCurrentStratum = new ReferenceTypeImpl.Stratum(stratumId);
    fFileSectionDefinedForCurrentStratum = false;
    fLineSectionDefinedForCurrentStratum = false;
    int lexemType = lexer.lexemType();
    while (lexemType != Lexer.ASTERISK_E && lexemType != Lexer.ASTERISK_S) {
      switch (lexemType) {
      case Lexer.ASTERISK_F:
        if (fFileSectionDefinedForCurrentStratum) {
          throw new AbsentInformationException(NLS.bind(
              JDIMessages.SourceDebugExtensionParser_10,
              new String[] { stratumId }));
        }
        parseFileSection(lexer);
        fFileSectionDefinedForCurrentStratum = true;
        break;
      case Lexer.ASTERISK_L:
        if (fLineSectionDefinedForCurrentStratum) {
          throw new AbsentInformationException(NLS.bind(
              JDIMessages.SourceDebugExtensionParser_11,
              new String[] { stratumId }));
        }
        parseLineSection(lexer);
        fLineSectionDefinedForCurrentStratum = true;
        break;
      case Lexer.ASTERISK_V:
        parseVendorSection(lexer);
        break;
      case Lexer.ASTERISK_CHAR:
        parseFutureSection(lexer);
        break;
      default:
        throw new AbsentInformationException(NLS.bind(
            JDIMessages.SourceDebugExtensionParser_12,
            new String[] { new String(lexer.lexem()) }));
      }
      lexemType = lexer.lexemType();
    }
    if (!fFileSectionDefinedForCurrentStratum) {
      throw new AbsentInformationException(NLS.bind(
          JDIMessages.SourceDebugExtensionParser_13,
          new String[] { stratumId }));
    }
    if (!fLineSectionDefinedForCurrentStratum) {
      throw new AbsentInformationException(NLS.bind(
          JDIMessages.SourceDebugExtensionParser_14,
          new String[] { stratumId }));
    }
    fDefinedStrata.add(stratumId);
    fReferenceType.addStratum(fCurrentStratum);
  }

  /**
   * @param lexer
   */
  private void parseFileSection(Lexer lexer)
      throws AbsentInformationException {
    if (lexer.nextLexem() != Lexer.CR) {
      throw new AbsentInformationException(NLS.bind(
          JDIMessages.SourceDebugExtensionParser_12,
          new String[] { new String(lexer.lexem()) }));
    }
    lexer.nextLexem();
    while (!isAsteriskLexem(lexer.lexemType())) {
      parseFileInfo(lexer);
    }
  }

  /**
   * @param lexer
   */
  private void parseFileInfo(Lexer lexer) throws AbsentInformationException {
    int lexemType = lexer.lexemType();
    if (lexemType == Lexer.NUMBER) {
      int fileId = integerValue(lexer.lexem());
      if (isAsteriskLexem(lexer.nextLexem())) {
        throw new AbsentInformationException(
            JDIMessages.SourceDebugExtensionParser_16);
      }
      fCurrentStratum.addFileInfo(fileId, getNonAsteriskString(lexer));
    } else if (lexemType == Lexer.PLUS) {
      if (lexer.nextLexem() != Lexer.NUMBER) {
        throw new AbsentInformationException(
            JDIMessages.SourceDebugExtensionParser_17);
      }
      int fileId = integerValue(lexer.lexem());
      if (isAsteriskLexem(lexer.nextLexem())) {
        throw new AbsentInformationException(
            JDIMessages.SourceDebugExtensionParser_16);
      }
      String fileName = getNonAsteriskString(lexer);
      if (isAsteriskLexem(lexer.lexemType())) {
        throw new AbsentInformationException(
            JDIMessages.SourceDebugExtensionParser_19);
      }
      fCurrentStratum.addFileInfo(fileId, fileName,
          getNonAsteriskString(lexer));
    } else {
      throw new AbsentInformationException(NLS.bind(
          JDIMessages.SourceDebugExtensionParser_12,
          new String[] { new String(lexer.lexem()) }));
    }
  }

  /**
   * @param lexer
   */
  private void parseLineSection(Lexer lexer)
      throws AbsentInformationException {
    fCurrentLineFileId = 0;
    if (lexer.nextLexem() != Lexer.CR) {
      throw new AbsentInformationException(NLS.bind(
          JDIMessages.SourceDebugExtensionParser_12,
          new String[] { new String(lexer.lexem()) }));
    }
    lexer.nextLexem();
    while (!isAsteriskLexem(lexer.lexemType())) {
      parseLineInfo(lexer);
    }
  }

  /**
   * @param lexer
   */
  private void parseLineInfo(Lexer lexer) throws AbsentInformationException {
    if (lexer.lexemType() != Lexer.NUMBER) {
      throw new AbsentInformationException(
          JDIMessages.SourceDebugExtensionParser_22);
    }
    int inputStartLine = integerValue(lexer.lexem());
    int lexemType = lexer.nextLexem();
    if (lexemType == Lexer.SHARP) {
      if (lexer.nextLexem() != Lexer.NUMBER) {
        throw new AbsentInformationException(
            JDIMessages.SourceDebugExtensionParser_23);
      }
      fCurrentLineFileId = integerValue(lexer.lexem());
      lexemType = lexer.nextLexem();
    }
    int repeatCount;
    if (lexemType == Lexer.COMMA) {
      if (lexer.nextLexem() != Lexer.NUMBER) {
        throw new AbsentInformationException(
            JDIMessages.SourceDebugExtensionParser_24);
      }
      repeatCount = integerValue(lexer.lexem());
      lexemType = lexer.nextLexem();
    } else {
      repeatCount = 1;
    }
    if (lexemType != Lexer.COLON) {
      throw new AbsentInformationException(
          JDIMessages.SourceDebugExtensionParser_25);
    }
    if (lexer.nextLexem() != Lexer.NUMBER) {
      throw new AbsentInformationException(
          JDIMessages.SourceDebugExtensionParser_26);
    }
    int outputStartLine = integerValue(lexer.lexem());
    lexemType = lexer.nextLexem();
    int outputLineIncrement;
    if (lexemType == Lexer.COMMA) {
      if (lexer.nextLexem() != Lexer.NUMBER) {
        throw new AbsentInformationException(
            JDIMessages.SourceDebugExtensionParser_27);
      }
      outputLineIncrement = integerValue(lexer.lexem());
      lexemType = lexer.nextLexem();
    } else {
      outputLineIncrement = 1;
    }
    if (lexemType != Lexer.CR) {
      throw new AbsentInformationException(
          JDIMessages.SourceDebugExtensionParser_28);
    }
    lexer.nextLexem();
    fCurrentStratum.addLineInfo(inputStartLine, fCurrentLineFileId,
        repeatCount, outputStartLine, outputLineIncrement);
  }

  /**
   * @param lexer
   */
  private void parseVendorSection(Lexer lexer)
      throws AbsentInformationException {
    if (lexer.nextLexem() != Lexer.CR) {
      throw new AbsentInformationException(NLS.bind(
          JDIMessages.SourceDebugExtensionParser_12,
          new String[] { new String(lexer.lexem()) }));
    }
    lexer.nextLexem();
    while (!isAsteriskLexem(lexer.lexemType())) {
      // do nothing in this case, just consume the lexems.
      getNonAsteriskString(lexer);
    }
  }

  /**
   * @param lexer
   */
  private void parseFutureSection(Lexer lexer)
      throws AbsentInformationException {
    if (lexer.nextLexem() != Lexer.CR) {
      throw new AbsentInformationException(NLS.bind(
          JDIMessages.SourceDebugExtensionParser_12,
          new String[] { new String(lexer.lexem()) }));
    }
    lexer.nextLexem();
    while (!isAsteriskLexem(lexer.lexemType())) {
      // do nothing in this case, just consume the lexems.
      getNonAsteriskString(lexer);
    }
  }

  private String getNonAsteriskString(Lexer lexer)
      throws AbsentInformationException {
    StringBuffer string = new StringBuffer();
    int lexemType = lexer.lexemType();
    while (lexemType != Lexer.CR) {
      string.append(lexer.lexem());
      lexemType = lexer.nextLexem();
    }
    lexer.nextLexem();
    // remove the leading white spaces
    int i = -1, length = string.length();
    char c;
    while (++i < length && ((c = string.charAt(i)) == ' ' || c == '\t'))
      ;
    return string.delete(0, i).toString();
  }

  private int integerValue(char[] lexem) {
    int i = 0;
    char c = lexem[0];
    while (c == ' ' || c == '\t') {
      c = lexem[++i];
    }
    int value = 0;
    while (c >= '0' && c <= '9') {
      value = value * 10 + c - '0';
      if (++i == lexem.length) {
        break;
      }
      c = lexem[i];
    }
    return value;
  }

  private boolean isAsteriskLexem(int lexemType) {
    switch (lexemType) {
    case Lexer.ASTERISK_C:
    case Lexer.ASTERISK_E:
    case Lexer.ASTERISK_F:
    case Lexer.ASTERISK_L:
    case Lexer.ASTERISK_O:
    case Lexer.ASTERISK_S:
    case Lexer.ASTERISK_V:
    case Lexer.ASTERISK_CHAR:
      return true;
    default:
      return false;
    }
  }

}
TOP

Related Classes of org.eclipse.jdi.internal.SourceDebugExtensionParser$Lexer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.