Exemplo n.º 1
0
  public Token scan() {

    // skip empty symbols and comments
    for (; ; readch()) {
      if (peek == ' ' || peek == '\t') continue;
      else if (peek == '\n') line++;
      // skip comments
      else if (peek == '/') {
        readch();
        if (peek == '/') {
          do {
            readch();
          } while (peek != '\n');
          line++;
        } else if (peek == '*') {
          for (; ; ) {
            readch();
            if (peek == '*') if (readch('/')) break;
            if (peek == '\n') line++;
          }
        } else return new Token('/');

      } else break;
    }

    // scan for not alone math symbols
    switch (peek) {
      case '&':
        if (readch('&')) return Word.and;
        else return new Token('&');
      case '|':
        if (readch('|')) return Word.or;
        else return new Token('|');
      case '=':
        if (readch('=')) return Word.eq;
        else return new Token('=');
      case '!':
        if (readch('=')) return Word.ne;
        else return new Token('!');
      case '<':
        if (readch('=')) return Word.le;
        else return new Token('<');
      case '>':
        if (readch('=')) return Word.ge;
        else return new Token('>');
      case '+':
        if (readch('+')) return Word.inc;
        else return new Token('+');
      case '-':
        if (readch('-')) return Word.dec;
        else return new Token('-');
    }

    // found quotes, so parse sting for print
    if (peek == '"') {
      StringBuffer b = new StringBuffer();
      readch();
      while (peek != '"') {

        // found slash, parse special symbol
        if (peek == '\\') {
          readch();
          if (peek == 'n') b.append('\n');
          else if (peek == 't') b.append('\t');
          else if (peek == '\\') b.append('\\');
          else if (peek == '\'') b.append('\'');
          else if (peek == '\"') b.append('\"');
          else throw new Error("Can't recognise symbol at " + line + " line");

        } else b.append(peek);

        readch();
      }
      readch();
      return new Text(b.toString());
    }

    // scan for number
    if (Character.isDigit(peek)) {
      StringBuilder b = new StringBuilder();
      do {
        b.append(peek);
        readch();
      } while (Character.isDigit(peek));
      // look is number were written in hex or bin format
      if (peek == 'h' || peek == 'H') {
        readch();
        return new Number(Integer.parseInt(b.toString(), 16));
      }
      if (peek == 'b' || peek == 'B') {
        readch();
        return new Number(Integer.parseInt(b.toString(), 2));
      }
      // look is number float
      if (peek != '.') return new Number(Integer.parseInt(b.toString()));
      float x = Integer.parseInt(b.toString());
      float d = 10;
      for (; ; ) {
        readch();
        if (!Character.isDigit(peek)) break;
        x = x + Character.digit(peek, 10) / d;
        d = d * 10;
      }
      return new Real(x);
    }

    // scan for words
    if (Character.isLetter(peek) || peek == '_') {
      StringBuilder builder = new StringBuilder();
      do {
        builder.append(peek);
        readch();
      } while (Character.isLetterOrDigit(peek) || peek == '_');
      String name = builder.toString();
      Word word = words.get(name);
      if (word != null) return word;
      word = new Word(name, Tag.ID);
      reserve(word);
      return word;
    }

    // something other
    Token t = new Token(peek);
    peek = ' ';
    return t;
  }
Exemplo n.º 2
0
  public Lexer(InputStream src) {
    this.source = src;
    words = new Hashtable<>();

    // reserve key words
    reserve(new Word("for", Tag.FOR));
    reserve(new Word("if", Tag.IF));
    reserve(new Word("else", Tag.ELSE));
    reserve(new Word("while", Tag.WHILE));
    reserve(new Word("do", Tag.DO));
    reserve(new Word("print", Tag.PRINT));
    reserve(new Word("read", Tag.READ));
    reserve(Word.True);
    reserve(Word.False);
    reserve(Type.Int);
    reserve(Type.Bool);
    reserve(Type.Float);
  }