import edu.neu.ccs.demeter.dj.*;
import java.lang.reflect.*;

FileSystem = <root> CompoundFile EOF.
File : SimpleFile | CompoundFile common <f> FileName.
SimpleFile = "simple".
CompoundFile = "compound" <contents> PList(File) [<parent> CompoundFile].  

Commands = List(Command) EOF.
Command : Simple.
Simple : MakeDirectory | ChangeDirectoryUp | ChangeDirectoryDown |
RecursiveCopy | DiskUsage | Find | Echo |
SymbolicLink | RemoveDirectory | CreateEmptyFile | RemoveFile.
MakeDirectory = "mkdir" DirectoryName.
ChangeDirectoryUp = "cd ..".
ChangeDirectoryDown = "cd" DirectoryName.
// RecursiveCopy = "cp -r ../* ." .
RecursiveCopy = "cp -r" <source> DirectoryName <target> DirectoryName.
DiskUsage = "du .".
SymbolicLink = "ln -s" <from> FileName <to> FileName.
RemoveDirectory = "rmdir" DirectoryName.

// "touch f" creates an empty file called f.
CreateEmptyFile = "touch" FileName.
RemoveFile = "rm" FileName.

Find = "find . -name" DirectoryName "-print".

Echo = "echo" Message.

FileName = Ident.
DirectoryName = Ident.
Message = String.

PList(S) ~ "(" {S} ")".
List(S) ~ {S}.

Main = .

CommandVisitor = extends Visitor.
touch x
touch y
mkdir a
mkdir b
cd a
mkdir c
mkdir d
touch r
cp -r c x
cd ..
echo "before_du"
du .
touch s
find . -name c -print
touch z

Main {
{{
  static CompoundFile cdir;
  static ClassGraph cg;
  static String FIdent = " edu.neu.ccs.demeter.Ident ";
  static public void main(String args[]) throws Exception {
    Commands cs = Commands.parse(System.in);
    cs.print();
    System.out.println();
    FileSystem fs = FileSystem.parse(
    "compound () root");
//    new FileSystem(
//      new CompoundFile(
//	new FileName(
//	  new Ident ("root")),
//	new File_PList()
//        )
//    );
    cdir = fs.get_root();

   cg = new ClassGraph(true, false);
   ClassGraph cgCommandsWithoutTail = new ClassGraph(Main.cg,
     "from Commands bypassing -> *,tail,* to *");
   cs.process(new TraversalGraph
//   ("from Commands to Simple",cg));
//   ("from Commands bypassing -> *,tail,* to Simple",cg));
   ("from Commands to Simple",cgCommandsWithoutTail));

    System.out.println();
    fs.print();
    System.out.println();
    fs.display();
    System.out.println();

  }
}}
}

Commands {
  void print() to * (PrintVisitor);
}

FileSystem {
  void print() bypassing -> *,parent,* to * (PrintVisitor);
}
FileSystem {
  void display() bypassing -> *,parent,* to * (DisplayVisitor);
}



Commands {
{{
  void process(TraversalGraph where) {
    CommandVisitor cV = new CommandVisitor();
    where.traverse(this, cV);
  }
}}
}

CommandVisitor {
{{
   void before(CreateEmptyFile host){
      SimpleFile sf = SimpleFile.parse("simple " + 
       (Ident) Main.cg.fetch(host,
         "from CreateEmptyFile to" + Main.FIdent));

      // host.get_filename().get_ident());
//     SimpleFile sf = new SimpleFile( host.get_filename());
     Main.cdir.get_contents().addElement(sf);
     System.out.println(" CreateEmptyFile ");
   }
}}
}


