2015-12-31 8 views
5

Ich habe überall auf der Website, im Internet und natürlich SO gesucht und finde keine Beschreibung oder Spezifikation für die in umlet verwendete Markup-Sprache.Wie lautet die Spezifikation der Auszeichnungssprache für umlet?

Im Beispiel Sequenzdiagramm zum Beispiel:

title: sample 
_alpha:A~id1_|_beta:B~id2_|_gamma:G~id3_ 
id1->>id2:id1,id2 
id2-/>id1:async Msg. 
id3->>>id1:id1,id3 
id1.>id3:id1,id3:async return Msg 
id1->id1:id1:self 
iframe{:interaction frame 
id2->id3:id1,id3:async Msg. 
iframe} 

Die -> -> usw ziemlich offensichtlich sind, aber was die Doppelpunkte tun?

Warum sind Unterstreichungen erforderlich usw. Neugierige Köpfe möchten wissen, dass dies ein nützliches Werkzeug zum Skizzieren ist.

+0

Anmelden bei IEEE, wenn Sie wirklich interessiert sind in diesem. –

+0

@tgunr was genau ist die Frage? Denn das All-in-One-Diagramm ist selbsterklärend, wenn man ein bisschen damit spielt ... Auch persönlich würde ich Plantuml-Sequenzdiagramme empfehlen http://plantuml.com/sequence.html; sie haben eine schönere Syntax und sehen besser aus –

+0

Warum versuchst du es nicht einfach in UMLet? – gefei

Antwort

2

gefunden an annotated script (das nicht gültig scheinen ab 14.2):

//UML2 style titles are optional. 
title:sequence diagram 
//the participating objects are separated using the pipe symbol "|". Their names may be underlined using underscores. 
_alpha:A_|_beta:B_|_gamma:G_ 
//The following line describes a (synchonuous) message originating from the first object sent to the second object, while both objects are active. 
1->>2:1,2 
//This message is asynchronous being sent from the second object to the first object. The messages is named. 
2-/>1:async Msg. 
//A message from the third object to the first object; both objects are active. 
3->>>1:1,3 
//A named asynchronous return message in UML2 style (using a stick arrow head). 
1.>3:1,3:async return Msg 
//This is a self call of the first object. 
1->1:1:self 
//Interaction frames may be used to show optional or conditional blocks within sequence diagrams. 
iframe{:interaction frame 
2->3:2,3:async Msg. 
iframe} 

RE: BNF, gibt es umlet-elements/src/main/javacc/SequenceAllInOneParser.jj in der Quelle:

options { 
    static    = false; 
    IGNORE_CASE   = false; 
    JAVA_UNICODE_ESCAPE = true; 
    JDK_VERSION  = "1.6"; 
    // Not yet detected as a valid option by the Eclipse plugin, but works nonetheless. This is essential for GWT compatible generated code. 
    JAVA_TEMPLATE_TYPE = "modern"; 
} 


PARSER_BEGIN(SequenceAllInOneParser) 
package com.baselet.element.facet.specific.sequence_aio.gen; 

import org.slf4j.Logger;import org.slf4j.LoggerFactory; 

import com.baselet.control.enums.LineType; 
import com.baselet.element.facet.specific.sequence_aio.Lifeline; 
import com.baselet.element.facet.specific.sequence_aio.Message.ArrowType; 
import com.baselet.element.facet.specific.sequence_aio.SequenceDiagramBuilder; 
import com.baselet.element.facet.specific.sequence_aio.SequenceDiagramException; 

public class SequenceAllInOneParser { 
    private static final Logger log = LoggerFactory.getLogger(SequenceAllInOneParser.class); 

    private boolean autoTick; 

    /** 
    * Replaces "\\\\" with "\\" in the output so that any further specified match replace pair can't match the replaced "\\". 
    * @param matchReplacePairs 
    * @return the string with the replacements 
    */ 
    public static String backslashReplace(String input, String... matchReplacePairs) { 
     if (matchReplacePairs.length % 2 == 1) { 
      throw new IllegalArgumentException("matchReplacePairs must have an even number of elements."); 
     } 
     String split = "\\\\"; 
     StringBuilder strBuilder = new StringBuilder(input.length()); 
     int firstIndex = 0; 
     // use the indexOf function instead of a split, because split uses regex and regex is not 100% supported by GWT 
     int foundIndex = input.indexOf(split, firstIndex); 
     while (firstIndex < input.length()) { 
      int lastIndex = foundIndex == -1 ? input.length() : foundIndex; 
      String tmp = input.substring(firstIndex, lastIndex); 
      for (int j = 0; j < matchReplacePairs.length - 1; j += 2) { 
       tmp = tmp.replace(matchReplacePairs[j], matchReplacePairs[j + 1]); 
      } 
      strBuilder.append(tmp); 
      if (foundIndex != -1) { 
       strBuilder.append('\\'); 
      } 
      firstIndex = lastIndex + split.length(); 
      foundIndex = input.indexOf(split, firstIndex); 
     } 
     return strBuilder.toString(); 
    } 

    /** 
    * Small data container to pass all informations. 
    */ 
    private class MessageArrowInfo { 
     boolean fromLeftToRight; 
     LineType lineType; 
     ArrowType arrowType; 
    } 

    private class InteractionConstraint { 
     private String lifelineId = null; 
     private String text = ""; 
    } 

    private class LifelineInterval { 
     private String startId; 
     private String endId; 
    } 
} 
PARSER_END(SequenceAllInOneParser) 

/* defines input to be ignored */ 
< * > SKIP: 
{ 
    " " 
    | "\t" 
} 

<DIAGRAM_DEF_TEXT> SKIP: 
{ 
    "\n" : DEFAULT 
    | "\r\n" : DEFAULT 
    | "\r" : DEFAULT 
} 

<DEFAULT> TOKEN: 
{ 
    < DIAGRAM_OPTION_OVERRIDE_ID :"overrideIds=" > 
    | < DIAGRAM_OPTION_AUTO_TICK: "autoTick=" > 
    | < TRUE: "true" > 
    | < FALSE: "false" > 
    | < DIAGRAM_TITLE: "title=" > : DIAGRAM_DEF_TEXT 
    | < DIAGRAM_DESC: "desc=" > : DIAGRAM_DEF_TEXT 
    | < LIFELINE_DEFINITIONS: "obj=" > : LIFELINE_DEF 
} 

<DIAGRAM_DEF_TEXT> TOKEN: 
{ 
    < DIAGRAM_DEFINITION_TEXT: 
     (
      ~ ["\\","\r","\n"] 
      | ("\\" ["\\", "n"]) 
     )+> : DIAGRAM_DEF_TEXT 
} 

<LIFELINE_DEF> TOKEN : 
{ 
    < LL_DEF_NEW_LINE: "\n" | "\r\n" | "\r" > : DEFAULT 
    | < LIFELINE_DEF_DELIMITER: "|" > 
    /*| < LIFELINE_TITLE_DELIMITER: "~" > integrated in the title */ 
    | < LIFELINE_ACTOR: "ACTOR" > 
    | < LIFELINE_ACTIVE: "ACTIVE" > 
    | < LIFELINE_CREATED_LATER :"CREATED_LATER" > 
    | < LIFELINE_EXEC_SPEC_FROM_START: "EXECUTION" > 
    | < LIFELINE_TITLE: /* since | and ~ are special characters which delimit the title they need to be escaped */ 
     ( 
      ~["~","\\","\n","\r","|"] 
      | ("\\" ["\\","~","|","n"]) 
     )+ 
     "~" > 
} 

<DEFAULT> TOKEN : 
{ 
    < TEXT_DELIMITER: ":" > : DIAGRAM_SEQ_TEXT 
    | < LIST_DELIMITER: "," > 
    | < OPEN_CURLY_BRACKET: "{" > 
    | < CLOSE_CURLY_BRACKET: "}" > 
    | < COMMAND_DELIMITER: ";" > 
    | < T_DASH: "-" > 
    | < T_DOT: "." > 
    | < T_DDOT: ".." > 
    | < T_EQ: "=" > 
    | < MESSAGE_ARROW_LEFT_OPEN: "<" > 
    | < MESSAGE_ARROW_LEFT_FILLED: "<<<" > 
    | < MESSAGE_ARROW_RIGHT_OPEN: ">" > 
    | < MESSAGE_ARROW_RIGHT_FILLED: ">>>" > 
    | < MESSAGE_DURATION_INC: "+" > 
    | < LOST: "lost" > 
    | < FOUND: "found" > 
    | < GATE: "gate" > 
    | < START_COREGION: "coregionStart=" > 
    | < END_COREGION: "coregionEnd=" > 
    | < INVARIANT: "invariant=" > 
    | < STATE_INVARIANT: "stateInvariant=" > 
    | < EXEC_SPEC_START: "on=" > 
    | < EXEC_SPEC_END: "off=" > 
    | < LL_DESTROY: "destroy=" > 
    | < REF: "ref=" > 
    | < CONTINUATION: "continuation=" > 
    | < TEXT_ON_LIFELINE: "text=" > 
    | < TICK: "tick=" > 
    | < COMBINED_FRAGMENT: "combinedFragment=" > : CF_OPERATOR 
    | < INTERACTION_CONSTRAINT: "constraint=" > 
    | < UNSIGNED_INT_CONSTANT: (["0" - "9"]) + > 
    | < DEFAULT_NEW_LINE: "\n" | "\r\n" | "\r" > 
} 

< LIFELINE_DEF, DEFAULT > TOKEN : 
{ 
    < LIFELINE_ID: ["a"-"z","A"-"Z"] (["a"-"z","A"-"Z","0"-"9"])* > 
} 

<DIAGRAM_SEQ_TEXT> TOKEN : 
{ 
    < TEXT_UNTIL_NEXT_COMMAND : (/* since ; is special characters which delimit the text it must be escaped */ 
      ~["\\","\n","\r",";"] 
      | ("\\" ["\\",";","n"]) 
     )+ > : DEFAULT 
} 

<CF_OPERATOR> TOKEN : 
{ 
    < COMBINED_FRAGMENT_OPERATOR: /* since ; and ~ are special characters which delimit the operator they need to be escaped */ 
     ( 
      ~["~","\\","\n","\r",";"] 
      | ("\\" ["\\","~","|","n",";"]) 
     )+ 
     "~" > : DEFAULT 
} 

/* general Tokens */ 

/* skip comments */ 
< * > SKIP : 
{ 
    <"//"(~["\n","\r"])*> 
} 

< * > TOKEN : 
{ 
    <LAST_LINE_COMMENT: "//"(~["\n","\r"])*> 
} 


/** 
* The main function which parses the whole diagram. 
* Line comments are skipped (see Tokens) 
*/ 
SequenceDiagramBuilder start() : 
{ 
    String titleText = ""; 
    String descText = ""; 
    SequenceDiagramBuilder diagram = new SequenceDiagramBuilder(); 
    autoTick = true; 
} 
{ 
    (
     (
      titleText=DiagramTitle() /* NL skip and change state to DEFAULT */ 
      | descText = DiagramDescription() /* NL skip and change state to DEFAULT */ 
      | Option(diagram) <DEFAULT_NEW_LINE> 
      | LifelineDefinitions(diagram) /* NL part of the nonterminal */ 

     )+//diagram definition as new NT followed by NL alternating with sequence so that the sequence= can be removed 
     Sequence(diagram) 
    ) 

    (<LAST_LINE_COMMENT>)? 
    <EOF> 
    { 
     diagram.setTitle(titleText); 
     diagram.setText(descText); 
     return diagram; 
    } 
} 

String DiagramTitle() : 
{ 
    String text = ""; 
} 
{ 
    <DIAGRAM_TITLE> 
    (
     <DIAGRAM_DEFINITION_TEXT> { text = backslashReplace(token.image, "\\n","\n");} 
    )? 
    {return text;} 
} 

String DiagramDescription() : 
{ 
    String desc = ""; 
} 
{ 
    <DIAGRAM_DESC> 
    <DIAGRAM_DEFINITION_TEXT> { desc = backslashReplace(token.image, "\\n","\n");} 
    {return desc;} 
} 

/** 
* Options for the whole diagram 
*/ 
void Option(SequenceDiagramBuilder diagram) : 
{ 
    boolean overrideIds; 
} 
{ 
    <DIAGRAM_OPTION_OVERRIDE_ID> overrideIds = booleanConstant() 
    { 
     diagram.setOverrideDefaultIds(overrideIds); 
    } 
    | <DIAGRAM_OPTION_AUTO_TICK> autoTick = booleanConstant() 
} 

/** 
* Defines all Lifelines 
*/ 
void LifelineDefinitions(SequenceDiagramBuilder diagram) : 
{} 
{ 
    <LIFELINE_DEFINITIONS> LifelineDef(diagram) (<LIFELINE_DEF_DELIMITER> LifelineDef(diagram))* <LL_DEF_NEW_LINE> 
} 

/** 
* Defines one Lifeline, the id can't be LIFELINE_ACTOR, LIFELINE_ACTIVE 
* or LIFELINE_CREATED_LATER because these are keywords. 
*/ 
void LifelineDef(SequenceDiagramBuilder diagram) : 
{ 
    String name = ""; 
    String id = null; 
    boolean createdOnStart = true; 
    Lifeline.LifelineHeadType headType = Lifeline.LifelineHeadType.STANDARD; 
    boolean execSpecFromStart = false; 
} 
{ 
    name = LifelineDefTitleText() (id=LifelineId())? 
    (
     <LIFELINE_ACTOR> { headType = Lifeline.LifelineHeadType.ACTOR; } 
     | <LIFELINE_ACTIVE> { headType = Lifeline.LifelineHeadType.ACTIVE_CLASS; } 
     | <LIFELINE_CREATED_LATER> { createdOnStart = false; } 
     | <LIFELINE_EXEC_SPEC_FROM_START> { execSpecFromStart = true; } 
    ) * 
    { 
     if("lost".equals(id) || "found".equals(id)) { 
      throw new SequenceDiagramException("'lost' and 'found' are keywords and can not be used as lifeline identifiers."); 
     } 
     diagram.addLiveline(name, id, headType, createdOnStart, execSpecFromStart); 
    } 
} 

/** can could be multiple lines */ 
String LifelineDefTitleText() : 
{} 
{ 
    <LIFELINE_TITLE> 
    { 
     /* remove trailing ~ and handle the escaping of \, |, n and ~ */ 
     return backslashReplace(token.image.substring(0, token.image.length() - 1), "\\n", "\n", "\\~", "~", "\\|", "|"); 
    } 
} 

/** 
* Can't be one of the following, because these are keywords in the lifeline definition! 
* < LIFELINE_ACTOR: "ACTOR" > 
* < LIFELINE_ACTIVE: "ACTIVE" > 
* < LIFELINE_CREATED_LATER :"CREATED_LATER" > 
*/ 
String LifelineId() : 
{} 
{ 
    <LIFELINE_ID> 
    { 
     return token.image; 
    } 
} 

void Sequence(SequenceDiagramBuilder diagram) : 
{} 
{ 
    (
     SequenceTick(diagram) <DEFAULT_NEW_LINE> 
     | (
      SequenceElement(diagram) 
      (LOOKAHEAD(2) <COMMAND_DELIMITER> SequenceElement(diagram))* 
      (<COMMAND_DELIMITER>)? 
      <DEFAULT_NEW_LINE> 
      { if(autoTick) { diagram.tick(); } } 
     ) 
     | <DEFAULT_NEW_LINE> 
    )* 
} 

void SequenceTick(SequenceDiagramBuilder diagram) : 
{ 
    int tickCount = 1; 
} 
{ 
    <TICK> (tickCount = unsignedIntConstant())? 
    { diagram.tick(tickCount); } 
} 

void SequenceElement(SequenceDiagramBuilder diagram) : 
{} 
{ 
    (
     MessageOrGeneralOrderingOrText(diagram) /* Message, GeneralOrdering have a common prefix for more clarity a new nonterminal was created*/ 
     | Coregion(diagram) 
     | DestroyLL(diagram) 
     | ExecutionSpecification(diagram) 
     | StateInvariant(diagram) 
     //| (diagram) //general ordering, TimeConstraint TimeObservation and DurationConstraint Duration Observation missing 
     | InteractionUse(diagram) 
     | Continuation(diagram) 
     | CombinedFragment(diagram) 
    ) 
} 

void MessageOrGeneralOrderingOrText(SequenceDiagramBuilder diagram) : 
{} 
{ 
    /* 
    * (Message and GeneralOrdering) A common prefix is: <LIFELINE_ID> "." <LIFELINE_ID> "<" 
    * All three have <LIFELINE_ID > as common prefix 
    * therefore use LOOKAHEAD(2) if it is a text, if not use a LOOKAHEAD(5) to determine if it is a message or a general ordering 
    */ 
    LOOKAHEAD(2) TextOnLifeline(diagram) 
    | LOOKAHEAD(5) Message(diagram) 
    | GeneralOrdering(diagram) 
} 

void CombinedFragment(SequenceDiagramBuilder diagram) : 
{ 
    LifelineInterval interval = new LifelineInterval(); 
    String operator = ""; 
    String id = null; 
} 
{ 
    (
     <COMBINED_FRAGMENT> 
     (
      <COMBINED_FRAGMENT_OPERATOR> 
      { operator = backslashReplace(token.image.substring(0, token.image.length() - 1), "\\n", "\n", "\\;", ";", "\\~", "~"); } 
     ) 
     [ 
      id = LifelineId() 
      [interval = LifelineInterval()] 
     ] 
     { diagram.beginCombinedFragment(interval.startId, interval.endId, id, operator); } 
    ) 
    | (
     <T_DASH> <T_DASH> (<T_EQ> id=LifelineId())? 
     { diagram.endCombinedFragment(id); } 
    ) 
    | (
     <T_DDOT> (<T_EQ> id=LifelineId())? 
     { diagram.endAndBeginOperand(id); } 
    ) 
} 

void Message(SequenceDiagramBuilder diagram) : 
{ 
    String leftLifelineId = null; 
    String rightLifelineId = null; 
    String leftLifelineLocalId = null; 
    String rightLifelineLocalId = null; 
    MessageArrowInfo messageArrowInfo; 
    String msgText = ""; 
    int lostCount = 0; 
    int foundCount = 0; 
    int gateCount = 0; 
    int duration = 0; 
} 
{ 
    (
     (
      leftLifelineId = LifelineId() [LOOKAHEAD(2)<T_DOT> leftLifelineLocalId = LifelineId()] 
      | <LOST> { leftLifelineId = "lost"; lostCount++; } 
      | <FOUND> { leftLifelineId = "found"; foundCount++; } 
      | <GATE> { leftLifelineId = "gate"; gateCount++; } 
     ) 
     messageArrowInfo = MessageArrow() 
     (
      rightLifelineId = LifelineId() [<T_DOT> rightLifelineLocalId = LifelineId()] 
      | <LOST> { rightLifelineId = "lost"; lostCount++; } 
      | <FOUND> { rightLifelineId = "found"; foundCount++; } 
      | <GATE> { rightLifelineId = "gate"; gateCount++; } 
     ) 
     (duration = MessageDuration())? 
     (msgText = TextUntilNewLine())? 
    ) 
    { 
     if(lostCount + foundCount + gateCount > 1) { 
      throw new SequenceDiagramException("Error: 'lost', 'found' and 'gate' can only occur once per message."); 
     } 
     String send; 
     String receive; 
     String sendLocalId; 
     String receiveLocalId; 
     if(messageArrowInfo.fromLeftToRight) { 
      send = leftLifelineId; 
      receive = rightLifelineId; 
      sendLocalId = leftLifelineLocalId; 
      receiveLocalId = rightLifelineLocalId; 
     } 
     else { 
      send = rightLifelineId; 
      receive = leftLifelineId; 
      sendLocalId = rightLifelineLocalId; 
      receiveLocalId = leftLifelineLocalId; 
     } 
     if(gateCount > 0) { 
      if(duration != 0) { 
       throw new SequenceDiagramException("Error: a messages with a gate can only have a duration of 0, but the duration was " + duration + "."); 
      } 
      if(send.equals("gate")) { 
       diagram.addSendGateMessage(receive, msgText, messageArrowInfo.lineType, messageArrowInfo.arrowType, receiveLocalId); 
      } 
      else { 
       diagram.addReceiveGateMessage(send, msgText, messageArrowInfo.lineType, messageArrowInfo.arrowType, sendLocalId); 
      } 
     } 
     else if(send.equals("lost")) { 
      throw new SequenceDiagramException("Error: 'lost' can only be on the receiving end of a message."); 
     } 
     else if(send.equals("found")) { 
      if(duration != 0) { 
       throw new SequenceDiagramException("Error: 'lost' and 'found' messages can only have a duration of 0, but the duration was " + duration + "."); 
      } 
      diagram.addFoundMessage(receive, msgText, messageArrowInfo.lineType, messageArrowInfo.arrowType, receiveLocalId); 
     } 
     else 
     { 
      if(receive.equals("lost")) { 
       if(duration != 0) { 
        throw new SequenceDiagramException("Error: 'lost' and 'found' messages can only have a duration of 0, but the duration was " + duration + "."); 
       } 
       diagram.addLostMessage(send, msgText, messageArrowInfo.lineType, messageArrowInfo.arrowType, sendLocalId); 
      } 
      else if(receive.equals("found")) { 
       throw new SequenceDiagramException("Error: 'found' can only be on the sending end of a message."); 
      } 
      else { 
       diagram.addMessage(send, receive, duration, msgText, messageArrowInfo.lineType, messageArrowInfo.arrowType, sendLocalId, receiveLocalId); 
      } 
     } 
    } 
} 

MessageArrowInfo MessageArrow(): 
{ 
    MessageArrowInfo messageArrowInfo = new MessageArrowInfo(); 
} 
{ 
     (
      (
       messageArrowInfo.lineType = MessageArrowLineType() 
       (
        <MESSAGE_ARROW_RIGHT_OPEN> { messageArrowInfo.arrowType = ArrowType.OPEN; } 
        | <MESSAGE_ARROW_RIGHT_FILLED> { messageArrowInfo.arrowType = ArrowType.FILLED; } 
       ) 
      ) 
      { 
       messageArrowInfo.fromLeftToRight = true; 
      } 
      | (
       (
        <MESSAGE_ARROW_LEFT_OPEN> { messageArrowInfo.arrowType = ArrowType.OPEN; } 
        | <MESSAGE_ARROW_LEFT_FILLED> { messageArrowInfo.arrowType = ArrowType.FILLED; } 
       ) 
       messageArrowInfo.lineType = MessageArrowLineType() 
      ) 
      { 
       messageArrowInfo.fromLeftToRight = false; 
      } 
     ) 
     { return messageArrowInfo; } 
} 

LineType MessageArrowLineType() : 
{ 
    LineType lineType; 
} 
{ 
    (
     <T_DASH> { lineType = LineType.SOLID; } 
     | <T_DOT> { lineType = LineType.DASHED; } 
    ) 
    { 
     return lineType; 
    } 
} 

int MessageDuration() : 
{ 
    int duration; 
} 
{ 
    (
     (
      <MESSAGE_DURATION_INC> { duration = 1; } 
      (
       duration = unsignedIntConstant() 
       | (<MESSAGE_DURATION_INC> { duration++; })* 
      ) 
     ) 
     | (
      <T_DASH> { duration = -1; } 
      (
       duration = unsignedIntConstant() { duration = -duration; } 
       | (<T_DASH> { duration--; })* 
      ) 
     ) 
    ) 
    { 
     return duration; 
    } 
} 

void GeneralOrdering(SequenceDiagramBuilder diagram): 
{ 
    String leftLifelineId = null; 
    String rightLifelineId = null; 
    String leftLifelineLocalId = null; 
    String rightLifelineLocalId = null; 
    boolean leftEarlier; 
} 
{ 
    leftLifelineId = LifelineId() 
    <T_DOT> 
    leftLifelineLocalId = LifelineId() 
    (
     <MESSAGE_ARROW_RIGHT_OPEN> { leftEarlier = true; } 
     | <MESSAGE_ARROW_LEFT_OPEN> { leftEarlier = false; } 
    ) 
    rightLifelineId = LifelineId() 
    <T_DOT> 
    rightLifelineLocalId = LifelineId() 
    { 
     if(leftEarlier) { 
      diagram.addGeneralOrdering(leftLifelineId, leftLifelineLocalId, rightLifelineId, rightLifelineLocalId); 
     } 
     else { 
      diagram.addGeneralOrdering(rightLifelineId, rightLifelineLocalId, leftLifelineId, leftLifelineLocalId); 
     } 
    } 
} 

void Coregion(SequenceDiagramBuilder diagram) : 
{ 
    String lifelineId; 
    boolean start; 
} 
{ 
    (
     <START_COREGION> { start = true; } 
     | <END_COREGION> { start = false; } 
    ) 
    lifelineId = LifelineId() 
    { 
     diagram.addCoregion(lifelineId, start); 
    } 
} 

void DestroyLL(SequenceDiagramBuilder diagram) : 
{ 
    String lifelineId; 
} 
{ 
    <LL_DESTROY> 
    lifelineId = LifelineId() 
    { 
     diagram.destroyLifeline(lifelineId); 
    } 
} 

void ExecutionSpecification(SequenceDiagramBuilder diagram) : 
{ 
    String lifelineId; 
    boolean on; 
} 
{ 
    (
     <EXEC_SPEC_START> { on = true; } 
     | <EXEC_SPEC_END> { on = false; } 
    ) 
    lifelineId = LifelineId() 
    { 
     diagram.changeExecutionSpecification(lifelineId, on); 
    } 
    ((<LIST_DELIMITER>)? lifelineId = LifelineId() 
     { 
      diagram.changeExecutionSpecification(lifelineId, on); 
     } 
    )* 
} 

void StateInvariant(SequenceDiagramBuilder diagram) : 
{ 
    String lifelineId; 
    String text = ""; 
    boolean stateStyle; 
} 
{ 
    (
     <INVARIANT> { stateStyle = false; } 
     | <STATE_INVARIANT> { stateStyle = true; } 
    ) 
    lifelineId = LifelineId() 
    (text = TextUntilNewLine())? 
    { 
     diagram.addStateInvariant(lifelineId, text, stateStyle); 
    } 
} 

void TextOnLifeline(SequenceDiagramBuilder diagram) : 
{ 
    String lifelineId; 
    String text = ""; 
} 
{ 
    [<TEXT_ON_LIFELINE>] 
    lifelineId = LifelineId() 
    text = TextUntilNewLine() /* text is mandatory, if not lookahead with message and general ordering would not work*/ 
    { 
     diagram.addTextOnLifeline(lifelineId, text); 
    } 
} 

String TextUntilNewLine() : 
{ 
} 
{ 
    <TEXT_DELIMITER> 
    <TEXT_UNTIL_NEXT_COMMAND> 
    { 
     return backslashReplace(token.image, "\\n", "\n", "\\;", ";"); 
    } 
} 

void InteractionUse(SequenceDiagramBuilder diagram): 
{ 
    LifelineInterval interval; 
    String text = ""; 
} 
{ 
    (
     <REF> 
     interval = LifelineInterval() 
     (text = TextUntilNewLine())? 
    ) 
    { 
     diagram.addInteractionUse(interval.startId, interval.endId, text); 
    } 
} 

void Continuation(SequenceDiagramBuilder diagram): 
{ 
    LifelineInterval interval; 
    String text = ""; 
} 
{ 
    (
     <CONTINUATION> 
     interval = LifelineInterval() 
     (text = TextUntilNewLine())? 
    ) 
    { 
     diagram.addContinuation(interval.startId, interval.endId, text); 
    } 
} 

/** 
* @return the start and end of the interval. 
*/ 
LifelineInterval LifelineInterval(): 
{ 
    LifelineInterval interval = new LifelineInterval(); 
} 
{ 
    interval.startId = LifelineId() 
    (<LIST_DELIMITER>)? 
    interval.endId = LifelineId() 
    { 
     return interval; 
    } 
} 

boolean booleanConstant() : 
{ boolean value;} 
{ 
    (
     <FALSE> { value = false;} 
     | <TRUE> { value = true;} 
    ) {return value; } 
} 

int unsignedIntConstant() : 
{} 
{ 
    <UNSIGNED_INT_CONSTANT> { 
     int value; 
     try { 
      value = Integer.parseInt(token.image); 
     } catch(NumberFormatException e) { 
      // only digits are accepted by the gramer, so the only reason for a NumberFormatException should be that the number is too big for int 
      throw (ParseException) new ParseException("Error: The string '" + token.image + "' couldn't be parsed as integer. The most probable reason is that the number is too big.").initCause(e); 
     } 
     return value; 
    } 
} 
Verwandte Themen