Package wyautl.io

Source Code of wyautl.io.PrettyAutomataReader$SyntaxError

// Copyright (c) 2011, David J. Pearce (djp@ecs.vuw.ac.nz)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//    * Redistributions of source code must retain the above copyright
//      notice, this list of conditions and the following disclaimer.
//    * Redistributions in binary form must reproduce the above copyright
//      notice, this list of conditions and the following disclaimer in the
//      documentation and/or other materials provided with the distribution.
//    * Neither the name of the <organization> nor the
//      names of its contributors may be used to endorse or promote products
//      derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL DAVID J. PEARCE BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package wyautl.io;

import java.io.*;
import java.math.BigInteger;
import java.util.*;

import wyautl.core.*;
import wyautl.util.BigRational;

public class PrettyAutomataReader {
  private final InputStream input;
  private final int[] lookaheads;
  private final Schema schema;
  private final HashMap<String,Integer> rSchema;
  private int start,end;
  private int pos;

  public PrettyAutomataReader(InputStream reader, Schema schema) {
    this.input = reader;
    this.schema = schema;
    this.rSchema = new HashMap<String,Integer>();
    for(int i=0;i!=schema.size();++i) {
      rSchema.put(schema.get(i).name, i);
    }
    this.lookaheads = new int[2];
  }

  public Automaton read() throws IOException,SyntaxError {
    Automaton automaton = new Automaton();
    int root = parseState(automaton);
    automaton.setRoot(0,root);
    return automaton;
  }

  protected int parseState(Automaton automaton) throws IOException, SyntaxError {
    skipWhiteSpace();
    int lookahead = lookahead();

    switch(lookahead) {
      case '(':
        return parseBracketed(automaton);
      case '[':
      case '{':
        return parseCompound(automaton);
      case '-':
        return parseNumber(automaton,true);
      case '0':
      case '1':
      case '2':
      case '3':
      case '4':
      case '5':
      case '6':
      case '7':
      case '8':
      case '9':
        return parseNumber(automaton,false);
      case '\"':
        return parseString(automaton);
      default:
        return parseTermOrBool(automaton);
    }
  }

  protected int parseTermOrBool(Automaton automaton)
      throws IOException, SyntaxError {

    // ======== parse identifier ===========
    StringBuffer sb = new StringBuffer();
    int lookahead;
    while ((lookahead = lookahead()) != -1
        && Character.isJavaIdentifierPart((char) lookahead)) {
      sb.append((char) next());
    }
    String name = sb.toString();

    if(name.equals("true")) {
      return automaton.add(Automaton.TRUE);
    } else if(name.equals("false")) {
      return automaton.add(Automaton.FALSE);
    }

    Integer kind = rSchema.get(name);
    if (kind == null) {
      throw new SyntaxError("unrecognised term encountered (" + name
          + ")", pos, pos);
    }
    Schema.Term type = schema.get(kind);
    int data = -1;

    if(type.child != null) {
      data = parseState(automaton);
    }

    return automaton.add(new Automaton.Term(kind, data));
  }

  protected int parseBracketed(Automaton automaton) throws IOException, SyntaxError {
    match('(');
    int r = parseState(automaton);
    match(')');
    return r;
  }

  protected int parseNumber(Automaton automaton, boolean negative)
      throws IOException, SyntaxError {
    if(negative) {
      match('-');
    }
    StringBuffer sb = new StringBuffer();
    int lookahead;
    while ((lookahead = lookahead()) != -1
        && Character.isDigit((char) lookahead)) {
      sb.append((char) next());
    }

    if(lookahead == '.') {
      sb.append((char) next());
      while ((lookahead = lookahead()) != -1
          && Character.isDigit((char) lookahead)) {
        sb.append((char) next());
      }
      BigRational val = new BigRational(sb.toString());

      if(negative) {
        val = val.negate();
      }

      return automaton.add(new Automaton.Real(val));

    } else {
      BigInteger val = new BigInteger(sb.toString());

      if(negative) {
        val = val.negate();
      }

      return automaton.add(new Automaton.Int(val));
    }
  }

  protected int parseString(Automaton automaton)
      throws IOException, SyntaxError {
    StringBuffer sb = new StringBuffer();
    int lookahead = next(); // skip starting '\"'

    while ((lookahead = next()) != -1
        && ((char)lookahead) != '\"') {
      sb.append((char) lookahead);
    }

    return automaton.add(new Automaton.Strung(sb.toString()));
  }

  protected int parseCompound(Automaton automaton)
      throws IOException, SyntaxError {
    int lookahead = next(); // skip opening brace

    int kind;

    switch(lookahead) {
      case '[':
        kind = Automaton.K_LIST;
        break;
      case '{':
        if(lookahead() == '|') {
          next(); // skip bar
          kind = Automaton.K_BAG;
        } else {
          kind = Automaton.K_SET;
        }
        break;
      default:
        throw new IllegalArgumentException("invalid compound start");
    }

    boolean firstTime = true;
    ArrayList<Integer> children = new ArrayList<Integer>();

    while ((lookahead = lookahead()) != -1 && lookahead != ']'
        && lookahead != '|' && lookahead != '}') {
      if (!firstTime) {
        if (lookahead != ',') {
          throw new SyntaxError("expecting ','", pos, pos);
        }
        next();
      } else {
        firstTime = false;
      }
      children.add(parseState(automaton));
      skipWhiteSpace();
    }

    switch(kind) {
      case Automaton.K_LIST:
        match(']');
        break;
      case Automaton.K_BAG:
        match('|');
        match('}');
        break;
      case Automaton.K_SET:
        match('}');
        break;
      default:
    }

    if(kind == Automaton.K_LIST) {
      return automaton.add(new Automaton.List(children));
    } else if(kind == Automaton.K_BAG) {
      return automaton.add(new Automaton.Bag(children));
    } else {
      return automaton.add(new Automaton.Set(children));
    }
  }

  protected int next() throws IOException {
    int lookahead;
    if(start != end) {
      lookahead = lookaheads[start];
      start = (start + 1) % lookaheads.length;
    } else {
      lookahead = input.read();
    }
    return lookahead;
  }

  protected int lookahead() throws IOException {
    int lookahead;
    if(start != end) {
      lookahead = lookaheads[start];
    } else {
      lookahead = input.read();
      lookaheads[end] = lookahead;
      end = (end + 1) % lookaheads.length;
    }
    return lookahead;
  }

  protected void match(char c) throws IOException, SyntaxError {
    int lookahead = next();
    if (lookahead != c) {
      throw new SyntaxError("expecting '" + c + "' --- found '"
          + (char) lookahead + "\'", pos, pos);
    }
  }

  protected void skipWhiteSpace() throws IOException {
    int lookahead;
    while ((lookahead = lookahead()) != -1
        && Character.isWhitespace(lookahead)) {
      next(); // dummy
      pos = pos + 1;
    }
  }

  public static final class SyntaxError extends Exception {
    public final int start;
    public final int end;
    public SyntaxError(String msg, int start, int end) {
      super(msg);
      this.start=start;
      this.end=end;
    }
  }

}
TOP

Related Classes of wyautl.io.PrettyAutomataReader$SyntaxError

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.