Package org.rascalmpl.library.lang.rsf

Source Code of org.rascalmpl.library.lang.rsf.RSFIO

/*******************************************************************************
* Copyright (c) 2009-2013 CWI
* 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:

*   * Jurgen J. Vinju - Jurgen.Vinju@cwi.nl - CWI
*******************************************************************************/
package org.rascalmpl.library.lang.rsf;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.imp.pdb.facts.IConstructor;
import org.eclipse.imp.pdb.facts.IMapWriter;
import org.eclipse.imp.pdb.facts.ISetWriter;
import org.eclipse.imp.pdb.facts.ISourceLocation;
import org.eclipse.imp.pdb.facts.IString;
import org.eclipse.imp.pdb.facts.IValue;
import org.eclipse.imp.pdb.facts.IValueFactory;
import org.eclipse.imp.pdb.facts.type.Type;
import org.eclipse.imp.pdb.facts.type.TypeFactory;
import org.eclipse.imp.pdb.facts.type.TypeStore;
import org.rascalmpl.interpreter.IEvaluatorContext;
import org.rascalmpl.interpreter.TypeReifier;
import org.rascalmpl.interpreter.utils.RuntimeExceptionFactory;

public class RSFIO {
  private static final TypeFactory types = TypeFactory.getInstance();
  private final IValueFactory values;
  private TypeReifier tr;
 
  public RSFIO(IValueFactory values){
    super();
   
    this.values = values;
    this.tr = new TypeReifier(values);
  }
 
  /*
   * Read relations from an RSF file. An RSF file contains tuples of binary relations
   * in the following format:
   *     RelationName Arg1 Arg2
   * where each field is separated by a tabulation character (\t). One file may contain tuples
   * for more than one relation.
   *
   * readRSF takes an RSF file nameRSFFile and generates a map[str,rel[str,str]] that maps
   * each relation name to the actual relation.
   */

  public IValue readRSF(ISourceLocation nameRSFFile, IEvaluatorContext ctx)
  //@doc{readRSF -- read an RSF file}
  {
    HashMap<java.lang.String, ISetWriter> table = new HashMap<java.lang.String, ISetWriter>();
 
    Type strType = types.stringType();
    Type tupleType = types.tupleType(strType, strType);

    Reader input = null;
    try {
      input = ctx.getResolverRegistry().getCharacterReader(nameRSFFile.getURI());
      BufferedReader bufRead = new BufferedReader(input);
      java.lang.String line = bufRead.readLine();

      while (line != null) {
        java.lang.String[] fields = line.split("\\s+");
        java.lang.String name = fields[0];
        //System.err.println(fields[0] + "|" + fields[1] + "|" + fields[2]);
        if (!table.containsKey(name)) {
          table.put(name, values.relationWriter(tupleType));
        }
        ISetWriter rw = table.get(name);
        rw.insert(values.tuple(values.string(fields[1]), values.string(fields[2])));
        line = bufRead.readLine();
      }
      bufRead.close();

    } catch (IOException e) {
      throw RuntimeExceptionFactory.io(values.string(e.getMessage()), null, null);
    }
    finally {
      if (input != null) {
        try {
          input.close();
        } catch (IOException e) {
            throw RuntimeExceptionFactory.io(values.string(e.getMessage()), null, null);
        }
      }
    }

    IMapWriter mw = values.mapWriter(strType, types.relType(strType, strType));

    for (Map.Entry<java.lang.String, ISetWriter> entry : table.entrySet()) {
      mw.insert(values.tuple(values.string(entry.getKey()), entry.getValue().done()));
    }
    return mw.done();
  }
 
  /*
   * Convert a string element from an RSF tuple to a typed Rascal value
   */
 
  private IValue getElementAsTypedValue(String elem, Type type){
    if(type.isString())
      return values.string(elem);
    if(type.isInteger())
      return values.integer(elem);
    if(type.isReal())
      return values.real(elem);
    if(type.isBool())
      return values.bool(elem.toLowerCase().equals("true"));
    return null;
  }
 
  /*
   * Read a named RSF relation, given its
   * - type
   * - name
   * - location
   */
 
  public IValue readRSFRelation(IValue result, IString relName, ISourceLocation loc, IEvaluatorContext ctx){
   
    Type resultType = tr.valueToType((IConstructor) result, new TypeStore());
 
    while (resultType.isAliased()) {
      resultType = resultType.getAliased();
    }
   
    if(!resultType.isRelation() || (resultType.getArity() != 2)){
      throw RuntimeExceptionFactory.illegalArgument(
          values.string("Type of an RSF relation should be a binary relation"),
          ctx.getCurrentAST(), ctx.getStackTrace());
    }
   
    Type elem1Type = resultType.getFieldType(0);
    Type elem2Type = resultType.getFieldType(1);
    ISetWriter rw = values.relationWriter(resultType.getElementType());
    String rname = relName.getValue();

    try (Reader reader = ctx.getResolverRegistry().getCharacterReader(loc.getURI())) {
      java.lang.String line = readLine(reader);

      while (!line.isEmpty()) {
        java.lang.String[] fields = line.split("\\s+");
        java.lang.String name = fields[0];
        if(name.equals(rname)){
          //System.err.println(fields[0] + "|" + fields[1] + "|" + fields[2]);
          IValue v1 = getElementAsTypedValue(fields[1], elem1Type);
          IValue v2 = getElementAsTypedValue(fields[2], elem2Type);
          rw.insert(values.tuple(v1, v2));
        }
        line = readLine(reader);
      }
      reader.close();

    } catch (IOException e) {
      throw RuntimeExceptionFactory.io(values.string(e.getMessage()), null, null);
    }
   
    return rw.done();
  }
 
  private boolean isEOL(int c) {
    return c == '\n' || c == '\r';
  }
 
  private String readLine(Reader reader) throws IOException{
    StringWriter sw = new StringWriter();
    int lastChar = reader.read();
    while(lastChar != -1){
      if(isEOL(lastChar)){
        return sw.toString();
      }
      sw.append((char)lastChar);
      lastChar = reader.read();
    }
    return sw.toString();
  }
 
  /*
   * Extract all relations and their types from an RSF file.
   * Returns a map[str Symbol]
   */
 
  public IValue getRSFTypes(ISourceLocation loc, IEvaluatorContext ctx)
  {
    HashMap<java.lang.String, Type> table = new HashMap<java.lang.String, Type>();
 
//    Type strType = types.stringType();
//    Type symbolType = Factory.Symbol;
   
    Reader reader = null;
    try {
      reader = ctx.getResolverRegistry().getCharacterReader(loc.getURI());
   
      java.lang.String line = readLine(reader);

      while (!line.isEmpty()) {
        System.err.println(line);
        java.lang.String[] fields = line.split("\\s+");
        java.lang.String name = fields[0];
        System.err.println(fields[0] + "|" + fields[1] + "|" + fields[2]);
       
        Type t1 = getElementType(fields[1]);
        Type t2 = getElementType(fields[2]);
        Type t1t2Tuple = types.tupleType(t1, t2);
        if (!table.containsKey(name)) {
            table.put(name, t1t2Tuple);
        } else
          table.put(name, table.get(name).lub(t1t2Tuple));
             
        line = readLine(reader);
      }
      reader.close();

    } catch (IOException e) {
      throw RuntimeExceptionFactory.io(values.string(e.getMessage()), null, null);
    }
    finally {
      if (reader != null){
        try {
          reader.close();
        } catch (IOException e){
          throw RuntimeExceptionFactory.io(values.string(e.getMessage()), ctx.getCurrentAST(), ctx.getStackTrace());
        }
      }
    }
   
    IMapWriter mr = values.mapWriter();
   
    for (Map.Entry<java.lang.String, Type> entry : table.entrySet()) {
      Type t = entry.getValue();
      mr.put(values.string(entry.getKey()),
             ((IConstructor) new TypeReifier(values).typeToValue(types.relType(t.getFieldType(0), t.getFieldType(1)), ctx).getValue()))
    }
    return mr.done();
  }
 
  private Type getElementType(String elem){

    if(elem.isEmpty()){
      return types.voidType();
    } else
      if(elem.matches("^[+-]?[0-9]+$")){
        return types.integerType();
      } else
        if(elem.matches("[+-]?[0-9]+\\.[0-9]*")){
          return types.realType();
        } else
          if(elem.equals("true") || elem.equals("false")){
            return types.boolType();
          } else {
            return types.stringType();
          }
  }
 
}
TOP

Related Classes of org.rascalmpl.library.lang.rsf.RSFIO

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.