%//
%// MTOM written in java-MTOM using the ATerm Library from Loria
%//
%{
import java.util.*;
import java.io.*;
import aterm.api.*;
import aterm.pure.*;
public class jtom3 {
private static String iSuffix = ".tfix";
private static String oSuffix = ".tom.c";
private static List emptyList = new ArrayList();
private ATermFactory factory;
private FileInputStream input;
private OutputCode output;
private AFun f_Tom;
private AFun f_DeclGL;
private AFun f_MainGL;
private AFun f_DeclListTom;
private AFun f_RuleListTom;
private AFun f_Rule;
private AFun f_RhsGL;
private AFun f_SortDecl;
private AFun f_SortsToSort;
private AFun f_GetFunSymDecl;
private AFun f_GetSubtermDecl;
private AFun f_TermsEqualDecl;
private AFun f_VariableDecl;
private AFun f_Variable;
private AFun f_GL;
private AFun f_ApiGL;
private AFun f_CodeGL;
private AFun f_SymbolDecl;
private AFun f_SymbolTom;
private AFun f_Appl;
private AFun f_empty;
private AFun f_cons;
private AFun f_sort;
// Goal Language
private AFun f_TomGL;
private AFun f_RuleSortedListTom;
private AFun f_RuleSetGL;
private AFun f_VariableList;
private AFun f_IfThenElseGL;
public ATermList empty() {
return factory.makeList();
}
public ATermList cons(ATerm t, ATermList l) {
return l.insert(t);
}
public jtom3(String name, ATermFactory factory) {
this.factory = factory;
try {
this.input = new FileInputStream(name + iSuffix);
this.output = new OutputCode(new BufferedWriter(new FileWriter(name + oSuffix)));
} catch (java.io.FileNotFoundException e) {
System.out.println("File " + input + " not found.");
} catch (IOException e2) {
System.out.println(e2);
}
// AFun initialisation
f_Tom = factory.makeAFun("Tom", 4, false);
f_DeclGL = factory.makeAFun("DeclGL", 1, false);
f_MainGL = factory.makeAFun("MainGL", 1, false);
f_DeclListTom = factory.makeAFun("DeclListTom", 1, false);
f_RuleListTom = factory.makeAFun("RuleListTom", 1, false);
f_Rule = factory.makeAFun("Rule", 2, false);
f_RhsGL = factory.makeAFun("RhsGL", 1, false);
f_SortDecl = factory.makeAFun("SortDecl", 1, false);
f_SortsToSort = factory.makeAFun("SortsToSort", 2, false);
f_GetFunSymDecl = factory.makeAFun("GetFunSymDecl", 2, false);
f_GetSubtermDecl = factory.makeAFun("GetSubtermDecl", 3, false);
f_TermsEqualDecl = factory.makeAFun("TermsEqualDecl", 3, false);
f_VariableDecl = factory.makeAFun("VariableDecl", 1, false);
f_Variable = factory.makeAFun("Variable", 2, false);
f_GL = factory.makeAFun("GL", 1, false);
f_ApiGL = factory.makeAFun("ApiGL", 1, false);
f_CodeGL = factory.makeAFun("CodeGL", 1, false);
f_SymbolDecl = factory.makeAFun("SymbolDecl", 1, false);
f_SymbolTom = factory.makeAFun("SymbolTom", 4, false);
f_Appl = factory.makeAFun("Appl", 2, false);
f_empty = factory.makeAFun("empty", 0, false);
f_cons = factory.makeAFun("cons", 2, false);
f_sort = factory.makeAFun("sort", 1, false);
// Goal Language
f_TomGL = factory.makeAFun("TomGL", 4, false);
f_RuleSortedListTom = factory.makeAFun("RuleSortedListTom", 2, false);
f_RuleSetGL = factory.makeAFun("RuleSetGL", 3, false);
f_VariableList = factory.makeAFun("VariableList", 1, false);
f_IfThenElseGL = factory.makeAFun("IfThenElseGL", 3, false);
}
%}
%type ATerm ATerm
%type ATermList ATermList
%type int int
%type void void
%type ATermTable Map
%type File OutputCode
%GET_FUN_SYM ATerm t (((ATermAppl)t).getAFun())
%GET_SUBTERM ATerm t n (((ATermAppl)t).getArgument(n))
%GET_FUN_SYM ATermList l ((((ATermList)l).isEmpty())?f_empty:f_cons)
%GET_SUBTERM ATermList l n ((n==0)?((ATermList)l).getFirst():(ATerm)(((ATermList)l).getNext()))
%// ------------------------------------------------------------
%sym ATerm compile(ATerm)
%sym void prettyPrint(File, ATerm)
%sym void prettyPrintList(File,ATermList)
%sym ATerm Tom(ATerm, ATerm, ATerm, ATerm) % f_Tom
%sym ATerm DeclGL(ATerm) % f_DeclGL
%sym ATerm MainGL(ATerm) % f_MainGL
%sym ATerm DeclListTom(ATermList) % f_DeclListTom
%sym ATerm RuleListTom(ATermList) % f_RuleListTom
%sym ATerm Rule(ATerm, ATerm) % f_Rule
%sym ATerm RhsGL(ATerm) % f_RhsGL
%sym ATerm SortDecl(ATerm) % f_SortDecl
%sym ATerm SortsToSort(ATermList,ATerm) % f_SortsToSort
%sym ATerm GetFunSymDecl(ATerm,ATerm) % f_GetFunSymDecl
%sym ATerm GetSubtermDecl(ATerm,ATerm,ATerm) % f_GetSubtermDecl
%sym ATerm TermsEqualDecl(ATerm,ATerm,ATerm) % f_TermsEqualDecl
%sym ATerm VariableDecl(ATerm) % f_VariableDecl
%sym ATerm Variable(ATerm,ATerm) % f_Variable
%sym ATerm GL(ATerm) % f_GL
%sym ATerm ApiGL(ATerm) % f_ApiGL
%sym ATerm CodeGL(ATerm) % f_CodeGL
%sym ATerm SymbolDecl(ATerm) % f_SymbolDecl
%sym ATerm SymbolTom(ATerm,ATerm,ATerm,ATerm) % f_SymbolTom
%sym ATerm Appl(ATerm,ATermList) % f_Appl
%sym ATermList empty() % f_empty
%sym ATermList cons(ATerm, ATermList) % f_cons
%sym ATermList sort(ATermList) % f_sort
%// Goal Language
%sym ATerm TomGL(ATerm, ATermList, ATermList, ATerm) % f_TomGL
%sym ATerm RuleSortedListTom(ATerm, ATermList) % f_RuleSortedListTom
%sym ATerm RuleSetGL(ATerm, ATerm, ATermList) % f_RuleSetGL
%sym ATerm VariableList(ATermList) % f_VariableList
%sym ATerm IfThenElseGL(ATerm, ATerm, ATerm) % f_IfThenElseGL
%sym void collectVariable(ATermTable, ATerm)
%// ------------------------------------------------------------
%var ATerm t, v1, v2, v3, v4
%var ATermList l, l1, l2
%var ATerm vDeclGL, vMainGL
%var ATermList vDeclList, vRuleList
%var ATerm name1, sort1, name2, sort2
%var ATermTable vTable
%var File out
%// ------------------------------------------------------------
%rule compile(Tom(v1,v2,v3,v4)) %--> {
ATerm declPart = compile(v1);
ATerm declListPart = compile(v2);
ATerm ruleListPart = compile(v3);
ATerm mainPart = compile(v4);
ATerm[] args = new ATerm[] {declPart,declListPart,ruleListPart,mainPart};
return factory.makeAppl(f_TomGL,args);
}
%rule compile(DeclGL(t)) %--> return t;
%rule compile(DeclListTom(l)) %--> {
ATermList res = empty();
ATerm c;
while(!l.isEmpty()) {
c = compile(l.getFirst());
if(c != null) {
res = cons(c,res);
}
l = l.getNext();
}
return (ATerm) res;
}
%rule compile(RuleListTom(l)) %--> {
Map table = new HashMap();
ATerm c, rule, topSymbol;
ATermList ruleList;
ATermList res = empty();
while(!l.isEmpty()) {
rule = l.getFirst();
topSymbol = getSymbolRule(rule);
ruleList = (ATermList)table.get(topSymbol);
if(ruleList == null) {
ruleList = empty();
}
ruleList = ruleList.append(rule);
table.put(topSymbol,(ATerm)ruleList);
l = l.getNext();
}
Iterator it = table.keySet().iterator();
while(it.hasNext()) {
//ATprintf("key = %t\n",ATgetFirst(keyList));
topSymbol = (ATerm)it.next();
ruleList = (ATermList)table.get(topSymbol);
//ATprintf("rules = %l\n",ruleList);
/*
* for each ruleList: build a matching automaton
*/
c = compile((ATerm)factory.makeAppl(f_RuleSortedListTom,topSymbol,(ATerm)ruleList));
if(c != null) {
res = cons(c,res);
}
}
return (ATerm)res;
}
%rule compile(RuleSortedListTom(t,l)) %--> {
// t is the top-symbol
ATerm lhs,rhs;
ATermList result = empty();
String path = "";
String s;
Map table = new HashMap();
ATerm variableList;
int nextlab = 0;
List list;
while(!l.isEmpty()) {
list = l.getFirst().match("Rule(,RhsGL())");
lhs = (ATerm)list.get(0);
rhs = (ATerm)list.get(1);
collectVariable(table,lhs);
if(Flags.cCode) {
result = genOneToOneMatching(result,lhs,rhs,path,nextlab+1,0);
result = result.append(makeGL(decapString(rhs)));
s = "lab" + (nextlab+1) + ":;";
result = result.append(makeGL(s));
} else if(Flags.jCode) {
s = "ok=true; lab" + (nextlab+1) + ":";
result = result.append(makeGL(s));
result = result.append(makeGL("while(ok) {"));
result = genOneToOneMatching(result,lhs,rhs,path,nextlab+1,1);
result = result.append(makeGL(decapString(rhs)));
result = result.append(makeGL("}"));
}
nextlab++;
l = l.getNext();
}
ATermList al = empty();
Iterator it = table.keySet().iterator();
while(it.hasNext()) {
al = al.insert((ATerm)it.next());
}
variableList = (ATerm)factory.makeAppl(f_VariableList,(ATerm)al);
//ATprintf("keyList = %l\n",keyList);
return (ATerm)factory.makeAppl(f_RuleSetGL,t,variableList,(ATerm)result);
}
%rule collectVariable(vTable,Appl(v1,empty)) %--> {
return;
}
%rule collectVariable(vTable,Appl(v1,l)) %--> {
while(!l.isEmpty()) {
collectVariable(vTable,l.getFirst());
l = l.getNext() ;
}
return;
}
%rule collectVariable(vTable,Variable(name1,sort1)) %--> {
ATerm variable = _2;
vTable.put(variable,variable);
return;
}
%rule compile(MainGL(t)) %--> return t;
%rule compile(SortDecl(t)) %--> return null;
%rule compile(VariableDecl(t)) %--> return null;
%rule compile(GetFunSymDecl(Variable(name1,sort1),ApiGL(t))) %--> {
String s = "";
if(Flags.cCode) {
s = "#define GET_FUN_SYM_" + decapString(((ATermAppl) sort1).getArgument(0)) +
"(" + decapString(name1) + ") " + decapString(t);
} else if(Flags.jCode) {
s = "Object GET_FUN_SYM_" + decapString(((ATermAppl) sort1).getArgument(0)) +
"(Object " + decapString(name1) + ") { return " + decapString(t) + "; }";
}
//printf("*** s= '%s'\n",s);
return makeGL(s);
}
%rule compile(GetSubtermDecl(Variable(name1,sort1),Variable(name2,sort2),ApiGL(t))) %--> {
String s = "";
if(Flags.cCode) {
s = "#define GET_SUBTERM_" + decapString(((ATermAppl) sort1).getArgument(0)) +
"(" + decapString(name1) + "," + decapString(name2) + ") " + decapString(t);
} else if(Flags.jCode) {
s = "Object GET_SUBTERM_" + decapString(((ATermAppl) sort1).getArgument(0)) +
"(Object " + decapString(name1) + ",int " + decapString(name2) + ") { return " + decapString(t) + "; }";
}
return makeGL(s);
}
%rule compile(TermsEqualDecl(Variable(name1,sort1),Variable(name2,sort2),ApiGL(t))) %--> {
String s = "";
if(Flags.cCode) {
s = "#define TERMS_EQUAL_" + decapString(((ATermAppl) sort1).getArgument(0)) +
"(" + decapString(name1) + "," + decapString(name2) + ") " + decapString(t);
} else if(Flags.jCode) {
s = "boolean TERMS_EQUAL_" + decapString(((ATermAppl) sort1).getArgument(0)) +
"(Object " + decapString(name1) + ",Object " + decapString(name2) +
") { return " + decapString(t) + "; }";
}
return makeGL(s);
}
%rule compile(SymbolDecl(SymbolTom(name1,SortsToSort(l,sort1),v2,v3))) %--> {
String s;
int argno=1;
if(Flags.cCode) {
if(!l.isEmpty()) {
s = getSortGL(sort1) + " " + decapString(name1);
if(!l.isEmpty()) {
s += "(";
while (!l.isEmpty()) {
s += getSortGL(l.getFirst()) + " _" + argno;
argno++;
l = l.getNext() ;
if(!l.isEmpty()) {
s += ",";
}
}
s += ");";
}
//printf("%s\n",s);
return makeGL(s);
}
}
return null;
}
%rule compile(t) %--> {
System.out.println("Cannot compile: " + t);
System.exit(1);
}
%// ------------------------------------------------------------
%rule prettyPrint(out,TomGL(vDeclGL,vDeclList,vRuleList,vMainGL)) %--> {
out.write(decapString(vDeclGL) + "\n");
prettyPrintList(out,vDeclList);
prettyPrintList(out,vRuleList);
out.write(decapString(vMainGL) + "\n");
return;
}
%rule prettyPrint(out,SortDecl(v1)) %--> {
out.write("%type " + getSortTom(v1) + " " + getSortGL(v1) + "\n");
return;
}
%rule prettyPrint(out,GetFunSymDecl(Variable(name1,sort1),ApiGL(v3))) %--> {
out.write("%GET_FUN_SYM " + getSortTom(sort1) + " " + decapString(name1) + " " + decapString(v3) + "\n");
return;
}
%rule prettyPrint(out,GetSubtermDecl(Variable(name1,sort1),Variable(name2,sort2),ApiGL(v3))) %--> {
out.write("%GET_SUBTERM " + getSortTom(sort1) + " " + decapString(name1) + " " + decapString(name2) +
" " + decapString(v3) + "\n");
return;
}
%rule prettyPrint(out,TermsEqualDecl(Variable(name1,sort1),Variable(name2,sort2),ApiGL(v3))) %--> {
out.write("%TERMS_EQUAL " + getSortTom(sort1) + " " + decapString(name1) + " " + decapString(name2) +
" " + decapString(v3) + "\n");
return;
}
%// removed here
%rule prettyPrint(out,RuleSetGL(SymbolTom(name1,SortsToSort(l,sort1),v2,CodeGL(v3)),v1,l2)) %--> {
String s;
int argno=1;
if(!l.isEmpty()) {
s = getSortGL(sort1) + " " + decapString(name1);
if(!l.isEmpty()) {
s += "(";
while (!l.isEmpty()) {
s += getSortGL(l.getFirst()) + " _" + argno;
argno++;
l = l.getNext() ;
if(!l.isEmpty()) {
s += ",";
}
}
s += ") {";
}
out.write(s + "\n");
}
if(Flags.jCode) {
out.write(" boolean ok;\n");
}
prettyPrint(out,v1);
prettyPrintList(out,l2);
if(Flags.jCode) {
if(getSortGL(sort1).equals("void")) {
out.write(" return ;\n");
} else {
out.write(" return null;\n");
}
}
out.write("}\n");
return;
}
%rule prettyPrint(out,VariableList(empty)) %--> return;
%rule prettyPrint(out,VariableList(cons(Variable(name1,sort1),l))) %--> {
out.write(getSortGL(sort1) + " " + decapString(name1) + ";\n");
prettyPrint(out,factory.makeAppl(f_VariableList,l));
return;
}
%rule prettyPrint(out,GL(t)) %--> {
out.write(getString(t) + "\n");
return;
}
%rule prettyPrint(out,t) %--> {
System.out.println("Cannot print: " + t);
System.exit(1);
}
%// ------------------------------------------------------------
%rule prettyPrintList(out,empty) %--> return;
%rule prettyPrintList(out,cons(t,l)) %--> {
prettyPrint(out,t);
prettyPrintList(out,l);
return;
}
%rule prettyPrintList(out,l) %--> {
System.out.println("Cannot print list: " + l);
System.exit(1);
}
%// ------------------------------------------------------------
%%
String getString(ATerm t) {
return ((ATermAppl) t).getAFun().getName();
}
String decapString(ATerm t) {
return getString(((ATermAppl) t).getArgument(0));
}
String getSortTom(ATerm sort) {
return decapString(((ATermAppl) sort).getArgument(0));
}
String getSortGL(ATerm sort) {
return decapString(((ATermAppl)((ATermAppl) sort).getArgument(1)).getArgument(0));
}
ATerm getSymbolRule(ATerm rule) {
return ((ATermAppl)((ATermAppl) rule).getArgument(0)).getArgument(0);
}
ATerm getSymbolName(ATerm symbol) {
return ((ATermAppl) symbol).getArgument(0);
}
ATerm getSymbolSort(ATerm symbol) {
return ((ATermAppl)((ATermAppl) symbol).getArgument(1)).getArgument(1);
}
ATerm getSymbolCode(ATerm symbol) {
return ((ATermAppl) symbol).getArgument(3);
}
ATerm makeGL(String s) {
//return (ATerm)factory.make("GL(\"" + s + "\")",emptyList);
ATerm str = (ATerm) factory.makeAppl(factory.makeAFun(s,0,true));
return (ATerm) factory.makeAppl(f_GL,str);
}
ATermList genOneToOneMatching(ATermList result, ATerm lhs, ATerm rhs, String oldPath,
int nextlab, int deep) {
int i,j;
String s = "";
ATerm symbol, subterm;
ATermList args;
ATerm subtermSymbol, subtermName, subtermSort, subtermOption, subtermCode;
ATermList subtermArgs, subtermSortList;
int indexSubterm = 0;
List list;
String path;
list = lhs.match("Appl(,[])");
symbol = (ATerm)list.get(0);
args = (ATermList)list.get(1);
//ATprintf("term = %t\n",term);
//ATprintf("symb = %t\n",symbol);
//ATprintf("args = %l\n",args);
while(!args.isEmpty()) {
ATerm name,sort;
subterm = args.getFirst();
indexSubterm++;
//ATprintf("subterm = %t\n",subterm);
path = oldPath + "_" + indexSubterm;
list = subterm.match("Variable(,)");
if(list != null) {
name = (ATerm)list.get(0);
sort = (ATerm)list.get(1);
s = indent(deep) + decapString(name) + " = " + path + ";";
result = result.append(makeGL(s));
} else {
list = subterm.match("Appl(SymbolTom(,SortsToSort([],),,CodeGL()),[])");
if(list != null) {
subtermName = (ATerm)list.get(0);
subtermSortList = (ATermList)list.get(1);
subtermSort = (ATerm)list.get(2);
subtermOption = (ATerm)list.get(3);
subtermCode = (ATerm)list.get(4);
subtermArgs = (ATermList)list.get(5);
int indexSubSubterm = 0;
//ATprintf("subtermName = %t\n",subtermName);
//ATprintf("subtermSort = %t\n",subtermSort);
//ATprintf("subtermCode = %t\n",subtermCode);
//ATprintf("subtermArgs = %t\n",subtermArgs);
s = indent(deep) + " if(GET_FUN_SYM_" + getSortTom(subtermSort) + "(" +
path + ") != " + decapString(subtermCode) + ") {";
result = result.append(makeGL(s));
if(Flags.cCode) {
s = indent(deep) + " goto lab" + nextlab + ";";
result = result.append(makeGL(s));
} else if(Flags.jCode) {
s = indent(deep) + " break lab" + nextlab + ";";
result = result.append(makeGL(s));
}
s = indent(deep) + " } else {";
result = result.append(makeGL(s));
while(!subtermArgs.isEmpty()) {
ATerm subSubterm = subtermArgs.getFirst();
ATerm subSubtermSymbol, subSubtermSort = null, subSubtermName;
ATermList subSubtermArgs;
//ATprintf("*** subSubterm = %t\n",subSubterm);
list = subSubterm.match("Appl(,[])");
//System.out.println("*** subSubterm = " + subSubterm);
//System.out.println("*** list = " + list);
if(list != null) {
subSubtermSymbol = (ATerm)list.get(0);
subSubtermArgs = (ATermList)list.get(1);
subSubtermSort = getSymbolSort(subSubtermSymbol);
//System.out.println("*** sort = " + subSubtermSort);
} else {
list = subSubterm.match("Variable(,)");
if(list != null) {
subSubtermName = (ATerm)list.get(0);
subSubtermSort = (ATerm)list.get(1);
//System.out.println("*** name = " + subSubtermName + "\tsort = " + subSubtermSort);
} else {
System.out.println("Strange term: " + subSubterm);
System.exit(1);
}
}
indexSubSubterm++;
s = indent(deep) + " " + getSortGL(subSubtermSort) + " " +
path + "_" + indexSubSubterm + " = (" + getSortGL(subSubtermSort) +
") GET_SUBTERM_" + getSortTom(subtermSort) + "(" +
path + "," + (indexSubSubterm-1) + ");";
result = result.append(makeGL(s));
subtermArgs = subtermArgs.getNext();
}
result = genOneToOneMatching(result,subterm, rhs, path, nextlab, deep+1);
s = indent(deep) + " }";
result = result.append(makeGL(s));
}
}
args = args.getNext();
}
//ATprintf("*** result = %l\n",result);
return result;
}
public final static void main(String[] args) {
String fileName = "";
if(args.length >= 1) {
for(int i=0; i < args.length; i++) {
if(args[i].charAt(0) == '-') {
if(args[i].equals("--noOutput")) {
Flags.printOutput = false;
} else if(args[i].equals("--atermStat")) {
Flags.atermStat = true;
} else if(args[i].equals("--jCode") || args[i].equals("-j")) {
Flags.jCode = true;
Flags.cCode = false;
oSuffix = ".java";
} else {
System.out.println("'" + args[i] + "' is not a valid option");
usage();
}
} else {
if(args[i].endsWith(iSuffix)) {
fileName = args[i].substring(0,args[i].length()-(iSuffix.length()));
} else {
fileName = args[i];
}
}
}
} else {
usage();
}
if(fileName.length() == 0) {
System.out.println("no inputfile");
usage();
}
jtom3 test = new jtom3(fileName,new PureFactory(16));
test.run();
}
public void run() {
ATerm t;
try {
t = factory.readFromTextFile(input);
//System.out.println("result = " + t);
ATerm compiledTerm = compile(t);
prettyPrint(output,compiledTerm);
output.close();
} catch (java.io.FileNotFoundException e1) {
System.out.println("File " + input + " not found.");
} catch (IOException e2) {
System.out.println(e2);
}
}
private static void usage() {
System.out.println("Tom Source usage:");
System.out.println("\tjava jtom3 [options] inputfile");
System.out.println("Options:");
System.out.println("\t--noOutput");
System.out.println("\t--atermStat");
System.out.println("\t--jCode | -j");
System.exit(0);
}
private static String indent(int deep) {
StringBuffer s = new StringBuffer();
for(int j=0 ; j
Last modified: Thu Jan 11 19:03:42 GMT 2001