锘??xml version="1.0" encoding="utf-8" standalone="yes"?>
]]>
涓庝笂涓綃囦腑鎵鎻愬強(qiáng)鍐呴儴DSL涓嶅悓錛屼嬌鐢ㄨ呬笉鏄氳繃API璋冪敤鏉ヤ嬌鐢?/span>DSL錛岃屾槸閫氳繃鎴戜滑瀹氫箟鐨勭壒瀹氳娉曠殑棰嗗煙璇█鏉ヤ嬌鐢?/span>DSL銆?/span>
1 XML褰㈠紡鐨?/span>DSL
鑴氭湰鏂囦歡
<process name="Auto-Door">
<state name="Open">
<transition event="time-out" next_state="Close"/>
</state>
<state name="Close">
<transition event="people-closer" next_state="Open"/>
</state>
</process>
瀹炵幇
publicclass XmlConfigParser {
//followings are context variables
private Machine currentMachine;
private State currentState;
class ElementHandler extends DefaultHandler{
private String getAttributeValue(String elemName,String attributeName,Attributes attris){
String attrValue=attris.getValue(attributeName);
if (attrValue==null){
thrownew XmlConfigParseException("Element "+elemName+" shoudle have the attribute:"+attributeName);
}
return attrValue;
}
@Override
publicvoid endElement(String arg0, String arg1, String elemName)
throws SAXException {
if (elemName.equals("state")){
currentMachine.getStates().add(currentState);
}
}
@Override
publicvoid startElement(String arg0, String arg1, String elemName,
Attributes attris) throws SAXException{
if (elemName.equals("process")){
String processName=getAttributeValue(elemName,"name",attris);
currentMachine=new Machine(processName);
}
if (elemName.equals("state")){
String stateName=getAttributeValue(elemName,"name",attris);
currentState=new State(stateName);
}
if (elemName.equals("transition")){
String eventName=getAttributeValue(elemName,"event",attris);
String nextState=getAttributeValue(elemName,"next_state",attris);
Transition transition=new Transition();
transition.setEvent(new Event(eventName));
transition.setNextState(nextState);
currentState.getTransitions().add(transition);
}
}
}
public Machine parser(String fileName){
SAXParserFactory spfactory =
SAXParserFactory.newInstance();
try{
SAXParser saxParser =
spfactory.newSAXParser();
XMLReader reader=saxParser.getXMLReader();
reader.setContentHandler(new ElementHandler());
reader.parse(fileName);
returncurrentMachine;
}catch(Exception e){
thrownew XmlConfigParseException("parsing is failed",e);
}
}
}
瀹炵幇瑕佺偣
涓婅堪瀹炵幇鏄氳繃SAX鏉ヨ繘琛?/span>XML瑙f瀽鐨勩?/span>
1 灝嗛鍩熸ā鍨嬬粨鏋勭洿鎺ユ槧灝勪負(fù)XML鍏冪礌鐨勭粨鏋?/span>
鎴戜滑鐢ㄨ繖縐嶆柟寮忔潵璁捐鎴戜滑鐨?/span>DSL錛岃繖鏍峰仛鐨勫ソ澶勬槸DSL姣旇緝瀹規(guī)槗浣跨敤錛堟洿鎺ヨ繎棰嗗煙妯″瀷錛夛紝鍚屾椂瑙f瀽紼嬪簭涔熶細(xì)鐩稿綆鍗曪紝姣旇緝瀹規(guī)槗鐢熸垚鐩稿簲鐨勮涔夋ā鍨嬨?/span>
2 浣跨敤涓婁笅鏂囧彉閲?/span>
濡備笂闈㈢▼搴忎腑鐨勶細(xì)
private Machine currentMachine;
private State currentState;
浠栦滑灝辨槸涓婁笅鏂囧彉閲忥紝鐢變簬SAX鏄『搴忚В鏋愮殑錛屾墍浠ュ繀欏諱繚鎸佹紜殑宸ヤ綔涓婁笅鏂囷紝濡傛妸鐢熶駭Transition瀵硅薄鍔犲叆鍒版紜殑State涓?/span>
2 鑷畾涔夎璦
鑴氭湰鏂囦歡
Machine (Auto-Door){
State(Open){
Transition{
event : time-out ,
next-state : Close
}
}
State (Close){
Transition{
event : people-closer ,
next-state : Open
}
}
}
瀹炵幇
鑷繁璁捐璇硶騫跺疄鐜拌В鏋愬櫒錛岄氬父闇瑕佹垜浠叿澶囦竴瀹氱殑緙栬瘧鍘熺悊鐭ヨ瘑騫朵笖鍊熺敤涓瀹氱殑瑙f瀽鍣ㄧ敓鎴愬伐鍏鋒潵甯姪鎴戜滑鐢熶駭瑙f瀽鍣ㄤ唬鐮併?/span>
瀹炵幇涓湰浜轟嬌鐢ㄤ簡 Antlr
Antlr鐨勮娉曟弿榪版枃浠訛細(xì)
grammar StateMachineG;
@header {
import org.ccsoft.statemachine.models.Machine;
import org.ccsoft.statemachine.models.State;
import org.ccsoft.statemachine.models.Transition;
import org.ccsoft.statemachine.models.Event;
}
@members {
public void emitErrorMessage(String msg) {
throw new RuntimeException(msg);
//super.emitErrorMessage(msg);
}
}
machine returns [Machine value] : 'Machine''('NAME')''{'{$value=new Machine($NAME.text);} (e=state{$value.getStates().add($e.value);})+'}';
state returns [State value] : 'State''('NAME')''{'{$value=new State($NAME.text);}(e=transition{$value.getTransitions().add($e.value);})+'}';
transition returns [Transition value]
: 'Transition''{'{$value=new Transition();}e=event{$value.setEvent($e.value);}','f=nextState{$value.setNextState($f.value);}'}';
event returns [Event value] : 'event'':'e=NAME{$value=new Event($NAME.text);};
nextState returns [String value]
: 'next-state'':'e=NAME{$value=$NAME.text;};
NAME : ('a'..'z' |'A'..'Z'|'0'..'9')+ ;
WS : (' ' |'"t' |'"n' |'"r' )+ {skip();} ;
瀹炵幇瑕佺偣
1 閲囩敤Antlr鐨勫唴宓?/span>Action
瀵逛簬DSL鐨勯氬父搴旂敤鍗抽氳繃澶栭儴鑴氭湰鐢熶駭鐩稿叧閮ㄥ垎璇箟妯″瀷瀵硅薄錛屼嬌鐢?/span>Antlr鐨勫唴宓?/span>Action姣旈噰鐢ㄨ娉曟爲(wèi)鏂瑰紡綆鍗曞緱澶氥?/span>