All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cb.parser.PrintVisitor Maven / Gradle / Ivy

The newest version!
/**
 * Copyright (c) 2001 Markus Dahm
 * Copyright (C) 2015-2018 BITPlan GmbH http://www.bitplan.com
 *
 * This source is part of
 * https://github.com/BITPlan/CrazyBeans
 * and the license as outlined there applies
 */
package cb.parser;

import java.io.PrintStream;
import java.util.Collection;
import java.util.Iterator;
import java.util.Stack;

import cb.petal.BooleanLiteral;
import cb.petal.DescendingVisitor;
import cb.petal.FloatLiteral;
import cb.petal.IntegerLiteral;
import cb.petal.PetalNodeList;
import cb.petal.Location;
import cb.petal.PetalFile;
import cb.petal.PetalNode;
import cb.petal.PetalObject;
import cb.petal.StringLiteral;
import cb.petal.Tag;
import cb.petal.Tagged;
import cb.petal.Tuple;
import cb.petal.Value;

/**
 * Print petal file exactly like Rose would with some limitations concerning
 * indendattion, i.e., if you don't mind white space, input and output files are
 * identical.
 *
 * @version $Id: PrintVisitor.java,v 1.18 2001/11/01 15:56:49 dahm Exp $
 * @author M. Dahm
 */
public class PrintVisitor extends DescendingVisitor {
  private PrintStream out;
  private int level = 0;
  private int column = 0, row = 1;
  private Stack align_stack = new Stack();

  /**
   * initialize this Visitor with the given PrintStream
   * @param out - the output stream e.g. System.out
   */
  public PrintVisitor(PrintStream out) {
    this.out = out;
  }

  /**
   * visit the given PetalFile object
   */
  public void visit(PetalFile obj) {
    println();
    obj.getPetal().accept(this);
    println();
    println();
    obj.getDesign().accept(this);
    println();
  }

  public void visitObject(PetalObject obj) {
    StringBuffer buf = new StringBuffer("(object " + obj.getName());

    for (Iterator i = obj.getParameterList().iterator(); i.hasNext();)
      buf.append(" \"" + i.next() + "\"");

    if (obj instanceof Tagged) {
      int label = ((Tagged) obj).getTag();

      if (label > 0)
        buf.append(" @" + label);
    }

    print(buf);

    if (obj.getNames().size() > 0)
      println();

    level++;
    setAlignment(obj.getLongestName().length());

    for (Iterator i = obj.getNames().iterator(), j = obj.getPropertyList()
        .iterator(); i.hasNext();) {
      indent();
      print(i.next());
      align();

      ((PetalNode) j.next()).accept(this);

      if (i.hasNext())
        println();
    }

    print(")");

    level--;
    restoreAlignment();
  }

  /*
   * Property names are aligned to a 4 column boundary Property values are
   * aligned to a 8 column boundary 8 spaces are replaced by one tab.
   */

  private int align_at = -1;

  private void setAlignment(int max) {
    align_stack.push(new Integer(align_at));

    int indent = level * 4;
    int min_dist; // min distance between first char of name and first char of
                  // property

    if (indent % 8 == 0) // name aligned on 8
      min_dist = 16;
    else
      // name aligned on 4
      min_dist = 12;

    align_at = indent + min_dist;
  }

  private void restoreAlignment() {
    Integer i = (Integer) align_stack.pop();
    align_at = i.intValue();
  }

  /**
   * Insert spaces up to next 8 column boundary
   */
  private void align() {
    int fill;

    if (column < align_at) {
      fill = align_at - column;
      // System.err.println("< : " + align_at + ":" + column + ":" + fill);
    } else {
      fill = 8 - (column % 8);
      // System.err.println(">= : " + align_at + ":" + column + ":" + fill);
    }

    int spaces = 4 - (fill % 4);
    for (int i = 0; i < spaces; i++)
      out.print(' ');

    column += spaces;
    fill -= spaces;

    if (fill > 0) {
      int tabs = fill / 8;

      if (fill % 8 > 0)
        tabs++;

      for (int i = 0; i < tabs; i++)
        out.print('\t');
    }

    // for(int i=0; i < fill; i++)
    // out.print(' ');

    column += fill;
  }

  /**
   * Initial indentation of line depend on current nesting level to 4 column
   * boundary.
   */
  private void indent() {
    int tabs = level / 2; // 4 spaces (INDENT) == 1 tab
    int spaces = level % 2;

    for (int i = 0; i < tabs; i++)
      out.print('\t');

    for (int i = 0; i < spaces; i++)
      out.print("    ");

    column += level * 4;
  }

  private void println() {
    out.print("\r\n");
    row++;
    column = 0;
  }

  private void print(java.lang.Object o) {
    String s = o.toString();
    column += s.length();

    out.print(s);
  }

  public void visit(StringLiteral obj) {
    if (obj.isMultiLine()) {
      println();

      Collection c = obj.getLines();

      for (Iterator i = c.iterator(); i.hasNext();) {
        print("|" + i.next());
        println();
      }

      indent();
    } else
      print(obj);
  }

  public void visit(BooleanLiteral obj) {
    print(obj);
  }

  public void visit(FloatLiteral obj) {
    print(obj);
  }

  public void visit(IntegerLiteral obj) {
    print(obj);
  }

  public void visit(Tag ref) {
    print(ref);
  }

  public void visit(Location loc) {
    print(loc);
  }

  public void visit(PetalNodeList list) {
    print("(list ");

    if (list.getName() != null)
      print(list.getName());

    java.util.List c = list.getElements();

    if (c.size() > 0) {
      level++;

      for (Iterator i = c.iterator(); i.hasNext();) {
        println();
        indent();
        ((PetalNode) i.next()).accept(this);
      }

      level--;
    }

    print(")");
  }

  public void visit(Value value) {
    print("(value " + value.getValueName());

    StringLiteral val = value.getValue();

    if (val.isMultiLine()) {
      val.accept(this);

      print(")");
    } else
      print(" " + val + ")");
  }

  public void visit(Tuple tuple) {
    print(tuple);
  }

  /**
   * this class can be called from the command line with given command line arguments
   * @param args
   */
  public static void main(String[] args) {
    PetalFile tree = PetalParser.parse(args);
    tree.accept(new PrintVisitor(System.out));
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy