/*
* File: ScriptInterpreter.java
* Author: Lukas K�nig
* Java version: 6.0
* Generated: 18.06.2008
*
* (c) Lukas K�nig, copyright according to GNU Lesser General Public License
* (LGPL) -> http://www.gnu.org/licenses/lgpl.html
*/
package fmg.fmg8.endlAutomat.script;
import java.util.Iterator;
import fmg.fmg8.endlAutomat.EndlicherAutomat;
import fmg.fmg8.endlAutomat.ZInfo;
import fmg.fmg8.endlAutomat.conditions.Condition;
import fmg.fmg8.graphVis.graph.Knoten;
import fmg.fmg8.sonstiges.SonstMeth;
import fmg.fmg8.statistik.Parametersatz;
/**
* Implements an interpreter for a script language for automata construction.
*
* @author Lukas K�nig
*/
public class ScriptInterpreter {
/**
* The instruction counter.
*/
private int instrCounter;
/**
* Counter.
*/
private int paramCounter;
/**
* Counter.
*/
private int ageCounter;
/**
* The parameters.
*/
private Parametersatz pars;
/**
* The current ScriptCondition.
*/
private ScriptCondition cond;
/**
* Der Modus, Verhalten oder Translator.
*/
private int modus;
/**
* Verhaltensautomaten-Modus.
*/
public static final int MODUS_VERHALTEN
= SonstMeth.MODUS_VERHALTEN;
/**
* �bersetzermodus.
*/
public static final int MODUS_TRANSLATOR
= SonstMeth.MODUS_TRANSLATOR;
/**
* Constructor.
*
* @param params The parameters.
* @param mod Der Modus (�bersetzer oder Verhalten).
*/
public ScriptInterpreter(
final Parametersatz params,
final int mod) {
this.pars = params;
this.cond = new ScriptCondition(this.pars, mod);
this.modus = mod;
this.reset();
}
/**
* Resets class vasiables.
*/
private void reset() {
this.instrCounter = 0;
this.paramCounter = 0;
this.ageCounter = 0;
this.cond.reset();
}
/**
* @param num Number to normalize.
*
* @return Normalized number.
*/
private int normalize(final int num) {
int i = num % 256;
if (i <= 0) {
i = 1;
}
return i;
}
/**
* Inserts a node into the automaton.
*
* @param nam The name of the node.
* @param aut The automaton to be altered.
*/
private void insertNode(final int nam, final EndlicherAutomat aut) {
int aktion = SonstMeth.modZwischen(
this.instrCounter,
SonstMeth.minBef(this.modus),
SonstMeth.maxBef(this.modus));
int param = this.paramCounter % 256 + 1;
int alt = this.ageCounter % 256 + 1;
if (param == 256) {
param = 1;
}
if (alt == 256) {
alt = 1;
}
aut.einfuegenKnoten(nam, aktion, param, alt);
if (aut.holeStartzustand() == null) {
aut.setStart(aut.holeKnoten(nam));
}
if (this.instrCounter
% (SonstMeth.maxBef(this.modus) - SonstMeth.minBef(this.modus) + 1)
== SonstMeth.maxBef(this.modus) - SonstMeth.minBef(this.modus)) {
this.paramCounter++;
}
if (this.paramCounter % 10 == 9) {
this.ageCounter++;
}
this.instrCounter++;
}
/**
* Inserts an edge.
*
* @param knotNam1 Source node.
* @param knotNam2 Target node.
* @param aut The automaton.
*/
private void insertEdge(final int knotNam1,
final int knotNam2,
final EndlicherAutomat aut) {
Knoten knot1 = aut.holeKnoten(knotNam1);
Knoten knot2 = aut.holeKnoten(knotNam2);
Condition c;
if (knot1 == null) {
this.insertNode(knotNam1, aut);
}
if (knot2 == null) {
this.insertNode(knotNam2, aut);
}
c = this.cond.getCondition();
aut.einfuegKante(knotNam1,
knotNam2,
c,
1);
this.cond.reset();
this.instrCounter++;
}
/**
* Changes a part of a node.
*
* @param mode Denotes which part of the node should be changed.
* 1: instruction,
* 2: parameter,
* 3: additional parameter.
* @param knotNam Node to be changed.
* @param setValue Value to set.
* @param aut Automaton.
*/
private void changeNode(final int mode,
final int knotNam,
final int setValue,
final EndlicherAutomat aut) {
Knoten knot = aut.holeKnoten(knotNam);
ZInfo zusatz;
int set;
int setInst;
if (knot == null) {
this.insertNode(knotNam, aut);
knot = aut.holeKnoten(knotNam);
}
zusatz = knot.getInfo();
set = setValue % 256;
if (set == 0) {
set++;
}
if (mode == 1) { // Change instruction.
setInst = SonstMeth.modZwischen(
setValue,
SonstMeth.minBef(this.modus),
SonstMeth.maxBef(this.modus));
zusatz.setAkt(setInst);
}
if (mode == 2) { // Change parameter.
zusatz.setPar(set);
}
if (mode == 3) { // Change additional parameter.
zusatz.setAlter(set);
}
this.instrCounter++;
}
/**
* Adds a token to the current Condition. If condition is null, creates a
* new Condition.
*
* @param token The token to add.
*/
private void addCondTok(final Integer token) {
this.cond.addToken(token);
}
/**
* Executes the instruction on the specified automaton.
*
* - k(x) : Inserts node x.
* - b(x, y): Inserts node x if it does not exist; then changes the
* instruction of x to y.
* - p(x, y): Like b(x, y), but for parameter.
* - z(x, y): Like b(x, y), but for additional parameter.
* - T(x) : Adds a token to the current condition. If the current
* condition is null, creates one.
* - K(x, y): Inserts transition from x to y with corrent Condition;
* Condition == null => Generate "false"
* if x or y do not exist, creates them; sets current
* Condition to null.
*
* @param aut The automaton to be altered.
* @param inst The Instruction to be executed.
*/
private void execute(final EndlicherAutomat aut,
final ScriptInstruction inst) {
int instName = this.normalize(inst.getInstName());
int[] parameters = new int[inst.getInstParam().length];
for (int i = 0; i < parameters.length; i++) {
parameters[i] = this.normalize(inst.getInstParam()[i]);
}
if (inst.getInstName() == 0) { // Insert node.
this.insertNode(parameters[0], aut);
} else if (instName == 1
|| instName == 2
|| instName == 3) { // Change part of node.
int mode = instName;
int knotNam = parameters[0];
int setValue = parameters[1];
this.changeNode(mode, knotNam, setValue, aut);
} else if (instName == 4) { // Insert edge.
this.insertEdge(parameters[0],
parameters[1],
aut);
} else if (instName == 5) { // Begin condition.
this.addCondTok(inst.getInstParam()[0]);
}
}
/**
* Generates an automaton based on the assigned Script.
*
* @param aut The automaton to construct.
* @param script The script which the construction is based on.
*/
public void generateAutomaton(final EndlicherAutomat aut,
final Script script) {
Iterator<ScriptInstruction> it = script.iterator();
ScriptInstruction inst;
SonstMeth.log(SonstMeth.LOG_STAGE1,
"Executing Script: "
+ script.toString().replace('\n', ' '),
this.pars);
this.reset();
aut.leereGraph();
while (it.hasNext()) {
inst = it.next();
this.execute(aut, inst);
}
SonstMeth.log(SonstMeth.LOG_STAGE1,
"Script executed.",
this.pars);
SonstMeth.log(SonstMeth.LOG_STAGE1,
"Generated "
+ aut.getClass().getCanonicalName()
+ ".",
// + aut,
this.pars);
}
/**
* Test.
*
* @param args Nichts.
*/
public static void main(final String[] args) {
String[] p = {"log", "-1"};
Parametersatz pars = new Parametersatz(p);
ScriptInterpreter interp
= new ScriptInterpreter(pars, ScriptInterpreter.MODUS_VERHALTEN);
EndlicherAutomat a = new EndlicherAutomat(null, interp);
String str = "";
for (int j = 0; j < 1000; j++) {
str = str + (j % Const.BEF_PAR.length) + "," + j * (13 + j);
if (Const.BEF_PAR[j % Const.BEF_PAR.length] == 2) {
str = str + "," + (j + 1);
}
str = str + ";";
}
SonstMeth.log(SonstMeth.LOG_STAGE1, "Raw script: " + str, pars);
Script s = new Script(str);
interp.generateAutomaton(a, s);
System.out.println(a.erzeugeStringSeq());
}
/**
* @return Returns the modus.
*/
public int getModus() {
return this.modus;
}
/**
* @param mod The modus to set.
*/
public void setModus(final int mod) {
this.modus = mod;
this.cond.setModus(mod);
}
}