package com.e2u.fsm;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class FSM
{
private static final int STAT_NONE = 0;
private static final int STAT_ESC = 1;
private static final int STAT_VAR = 2;
private static final int STAT_ESC_VAR = 3;
public String parseGrammar(String str, Map<String, Object> out)
{
String result = "";
String varname = "";
char[] buffer = str.toCharArray();
int curStat = STAT_NONE;
for(int i = 0; i < buffer.length; i++)
{
switch(curStat)
{
case STAT_NONE:
{
if(buffer[i] == '\\')
{
curStat = STAT_ESC;
}
else if(buffer[i] == '%')
{
curStat = STAT_VAR;
varname = "";
}
else
{
result += buffer[i];
}
break;
}
case STAT_ESC:
{
result += buffer[i];
curStat = STAT_NONE;
break;
}
case STAT_VAR:
{
if(buffer[i] == '\\')
{
curStat = STAT_ESC_VAR;
}
else if(buffer[i] == '%')
{
curStat = STAT_NONE;
if(out.containsKey(varname))
{
result += out.get(varname);
}
}
else
{
varname += buffer[i];
}
break;
}
case STAT_ESC_VAR:
{
varname += buffer[i];
curStat = STAT_VAR;
break;
}
}
}
return result;
}
private OnAction appendResultAction = new AppendResult();
private OnAction appendVarNameAction = new AppendVarName();
private OnAction parVarNameAction = new ParseVarName();
private static int[][] successor =
{
{STAT_ESC, STAT_VAR, STAT_NONE},
{STAT_NONE},
{STAT_ESC_VAR, STAT_NONE, STAT_VAR},
{STAT_VAR}
};
private static String[][] grammar =
{
{"\\", "%", ""},
{""},
{"\\", "%", ""},
{""}
};
private OnAction[][] actions =
{
{null, null, appendResultAction},
{appendResultAction},
{null, parVarNameAction, appendVarNameAction},
{appendVarNameAction}
};
public String parseGrammar1(String str, Map<String, Object> out)
{
char[] buffer = str.toCharArray();
StringBuffer result = new StringBuffer();
StringBuffer varname = new StringBuffer();
List params = new ArrayList(5);
params.add(result);
params.add(varname);
params.add(out);
params.add(null);
int curStat = STAT_NONE;
for(int i = 0; i < buffer.length; i++)
{
params.set(3, new Integer(buffer[i]));
curStat = transition(curStat, buffer[i], params);
}
return result.toString();
}
private int transition(int state, char c, List params)
{
int result = -1;
String[] grammars = grammar[state];
for(int i = 0; i < grammars.length; i++)
{
if(grammars[i].isEmpty() || grammars[i].indexOf(c) != -1)
{
if(actions[state][i] != null)
{
actions[state][i].action(params);
}
result = successor[state][i];
break;
}
}
return result;
}
private static class AppendResult implements OnAction
{
public void action(List params)
{
StringBuffer result = (StringBuffer)params.get(0);
char c = (char)((Integer)params.get(3)).intValue();
result.append(c);
}
}
private static class AppendVarName implements OnAction
{
public void action(List params)
{
StringBuffer varname = (StringBuffer)params.get(1);
char c = (char)((Integer)params.get(3)).intValue();
varname.append(c);
}
}
private static class ParseVarName implements OnAction
{
public void action(List params)
{
StringBuffer result = (StringBuffer)params.get(0);
StringBuffer varname = (StringBuffer)params.get(1);
Map<String, Object> map = (Map<String, Object>)params.get(2);
if(map.containsKey(varname.toString()))
{
result.append(map.get(varname.toString()));
}
varname.setLength(0);
}
}
private static interface OnAction
{
public void action(List params);
}
private static void test()
{
FSM fsm = new FSM();
Map<String, Object> out = new HashMap<String, Object>();
out.put("p1", "xyz");
out.put("p2", "8888");
out.put("Va%lue Onl\\%y@sME", "zaq");
String input = "\\\\32 -- %p1% -- %p2% -- %Va\\%lue Onl\\\\\\%y@sME% -- qw1";
String strings[] =
{
"\\\\32 -- %p1% -- %p2% -- %Va\\%lue Onl\\\\\\%y@sME% -- qw1",
"\\\\32%p1%%p2%%Va\\%lue Onl\\\\\\%y@sME%qw1"
};
String result = null;
for(int i = 0; i < strings.length; i++)
{
result = fsm.parseGrammar(strings[i], out);
System.out.println(result);
result = fsm.parseGrammar1(strings[i], out);
System.out.println(result);
}
}
public static void main(String[] args)
{
test();
}
}