1 19 20 21 package SOFA.SOFAnode.Util.DFSRChecker.parser; 22 23 import java.io.*; 24 import java.util.*; 25 26 import SOFA.SOFAnode.Util.DFSRChecker.DFSR.Options; 27 import SOFA.SOFAnode.Util.DFSRChecker.node.ActionRepository; 28 import SOFA.SOFAnode.Util.DFSRChecker.node.AdjustmentNode; 29 import SOFA.SOFAnode.Util.DFSRChecker.node.AlternativeNode; 30 import SOFA.SOFAnode.Util.DFSRChecker.node.AndParallelNode; 31 import SOFA.SOFAnode.Util.DFSRChecker.node.AtomicNode; 32 import SOFA.SOFAnode.Util.DFSRChecker.node.CompositionNode; 33 import SOFA.SOFAnode.Util.DFSRChecker.node.EventNode; 34 import SOFA.SOFAnode.Util.DFSRChecker.node.NullNode; 35 import SOFA.SOFAnode.Util.DFSRChecker.node.RepetitionNode; 36 import SOFA.SOFAnode.Util.DFSRChecker.node.RestrictionNode; 37 import SOFA.SOFAnode.Util.DFSRChecker.node.SequenceNode; 38 import SOFA.SOFAnode.Util.DFSRChecker.node.TreeNode; 39 import SOFA.SOFAnode.Util.DFSRChecker.node.ConsentNode; 40 import SOFA.SOFAnode.Util.SyntaxErrorException; 41 42 43 56 public class Builder { 57 58 61 private boolean MULTINODES = true; 62 63 66 private char next_char; 67 68 71 private ProtocolReader source; 72 73 76 private String next_token; 77 78 81 private boolean isTokenID; 82 83 86 private ActionRepository repository; 87 88 91 private String protocol; 92 93 97 public Builder(ActionRepository repository) { 98 this.repository = repository; 99 this.MULTINODES = Options.multinodes; 100 } 101 102 109 static private String getReverseAction(String src) { 110 String e; 111 if (src.startsWith("!")) 112 e = (new String ("?")).concat(src.substring(1)); 113 else if (src.startsWith("?")) 114 e = (new String ("!")).concat(src.substring(1)); 115 else 116 e = new String (src); 117 return e; 118 } 119 120 127 static private boolean isSimpleCall(String src) { 128 return !(src.endsWith("^") || src.endsWith("$") || src.endsWith("~") || src.endsWith("[")); 129 } 130 131 137 private boolean isLetter(char ch) { 138 return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch == '_') || (ch >= '0' && ch <= '9'); 139 } 140 141 148 public static boolean isWhiteSpace(char ch) { 149 return ((ch == ' ') || (ch == '\t') || (ch == '\n')); 150 } 151 152 private void nextPart(String part) { 153 protocol += part; 154 Debug.print(2, part); 155 } 156 157 166 private String nextToken() throws SyntaxErrorException, IOException { 167 String result; 168 isTokenID = false; 169 if (!source.ready()) { 170 Debug.println(2, ""); 171 return ""; 172 } 173 while (isWhiteSpace(next_char)) 174 if (source.ready()) { 176 protocol += " "; 177 next_char = (char) source.read(); 178 } 179 else { 180 Debug.println(2, ""); 181 return ""; 182 } 183 switch (next_char) { 184 case (char) -1: { 185 Debug.println(2, ""); 186 return ""; 187 } 188 case '|': 189 next_char = (char) source.read(); 190 if (next_char == '|') { 191 next_char = (char) source.read(); 192 nextPart("||"); 193 return "||"; 194 } else { 195 nextPart("|"); 196 return "|"; 197 } 198 case '&': 199 next_char = (char) source.read(); 200 nextPart("&"); 201 return "&"; 202 case '@': 203 next_char = (char) source.read(); 204 nextPart("@"); 205 return "@"; 206 case '.': 207 next_char = (char) source.read(); 208 nextPart("."); 209 return "."; 210 case '*': 211 next_char = (char) source.read(); 212 nextPart("*"); 213 return "*"; 214 case '+': 215 next_char = (char) source.read(); 216 nextPart("+"); 217 return "+"; 218 case ';': 219 next_char = (char) source.read(); 220 nextPart(";"); 221 return ";"; 222 case ',': 223 next_char = (char) source.read(); 224 nextPart(","); 225 return ","; 226 case '\\': 227 next_char = (char) source.read(); 228 nextPart("\\"); 229 return "\\"; 230 case '{': 231 next_char = (char) source.read(); 232 nextPart("{"); 233 return "{"; 234 case '}': 235 next_char = (char) source.read(); 236 nextPart("}"); 237 return "}"; 238 case '(': 239 next_char = (char) source.read(); 240 nextPart("("); 241 return "("; 242 case ')': 243 next_char = (char) source.read(); 244 nextPart(")"); 245 return ")"; 246 case '[': 247 next_char = (char) source.read(); 248 nextPart("["); 249 return "["; 250 251 case ']': 252 next_char = (char) source.read(); 253 nextPart("]"); 254 return "]"; 255 256 270 default: 271 if (isLetter(next_char) || next_char == '?' || next_char == '!' || next_char == '<' || next_char == '#') { 272 result = ""; 273 if (next_char == '!' || next_char == '?' || next_char == '#') { 274 result = result + next_char; 275 next_char = (char) source.read(); 276 } 277 if (next_char == '<') { 278 do { 279 result = result + next_char; 280 next_char = (char) source.read(); 281 } while (next_char != '>'); 282 result = result + next_char; 283 next_char = (char) source.read(); 284 } else { 285 while (isLetter(next_char)) { 286 result = result + next_char; 287 next_char = (char) source.read(); 288 } 289 } 290 if (next_char != '.') { 291 if (result.equals("NULL")) { 292 isTokenID = true; 293 nextPart(result); 294 return result; 295 } 296 throw new SyntaxErrorException("invalide event name: dot delimiter expected in event name, found " + next_char + " after " + result); 297 } else 298 result = result + next_char; 299 next_char = (char) source.read(); 300 while (isLetter(next_char)) { 301 result = result + next_char; 302 next_char = (char) source.read(); 303 } 304 if (next_char == '^' || next_char == '$' || next_char == '~') { 305 result = result + next_char; 306 next_char = (char) source.read(); 307 } 308 isTokenID = true; 309 nextPart(result); 310 return result; 311 } 312 throw new SyntaxErrorException("Unexpected literal with code " + (int) next_char); 313 } 314 } 315 316 317 327 private TreeNode alternative() throws SyntaxErrorException, IOException { 328 Vector nodelist = new Vector(); 329 330 Vector protindices = new Vector(); 331 protindices.add(new Integer (source.getIndex() - next_token.length() - 1)); 332 333 nodelist.add(sequence()); 334 while (next_token == "+") { 335 next_token = nextToken(); 336 nodelist.add(sequence()); 337 protindices.add(new Integer (source.getIndex() - next_token.length() - (next_token.length() > 0 ? 1 : 0))); 338 } 339 340 343 if (nodelist.size() > 1) { 344 if (MULTINODES) { 345 TreeNode[] nodes = new TreeNode[nodelist.size()]; 346 for (int i = 0; i < nodelist.size(); ++i) 347 nodes[i] = (TreeNode) nodelist.get(i); 348 349 TreeNode newnode = new AlternativeNode(nodes); 350 newnode.protocol = protocol.substring(((Integer ) protindices.get(0)).intValue(), ((Integer ) protindices.lastElement()).intValue()); 351 return newnode; 352 } 353 354 else { 355 TreeNode[] nodes = new TreeNode[2]; 356 TreeNode result = (TreeNode) nodelist.get(0); 357 358 for (int i = 1; i < nodelist.size(); ++i) { 359 nodes = new TreeNode[2]; 360 nodes[0] = result; 361 nodes[1] = (TreeNode) nodelist.get(i); 362 result = new AlternativeNode(nodes); 363 result.protocol = protocol.substring(((Integer ) protindices.get(0)).intValue(), ((Integer ) protindices.get(i)).intValue()); 364 } 365 366 return result; 367 } 368 } else { 369 return (TreeNode) nodelist.get(0); 370 } 371 } 372 373 384 private TreeNode sequence() throws SyntaxErrorException, IOException { 385 Vector nodelist = new Vector(); 386 Vector protindices = new Vector(); 387 protindices.add(new Integer (source.getIndex() - next_token.length() - 1)); 388 389 nodelist.add(andparallel()); 390 391 while (next_token == ";") { 392 next_token = nextToken(); 393 nodelist.add(andparallel()); 394 protindices.add(new Integer (source.getIndex() - next_token.length() - (next_token.length() > 0 ? 1 : 0))); 395 } 396 397 400 if (nodelist.size() > 1) { 401 if (MULTINODES) { 402 TreeNode[] nodes = new TreeNode[nodelist.size()]; 403 for (int i = 0; i < nodelist.size(); ++i) 404 nodes[i] = (TreeNode) nodelist.get(i); 405 406 TreeNode newnode = new SequenceNode(nodes); 407 newnode.protocol = protocol.substring(((Integer ) protindices.get(0)).intValue(), ((Integer ) protindices.lastElement()).intValue()); 408 return newnode; 409 } else { 410 TreeNode[] nodes = new TreeNode[2]; 411 TreeNode result = (TreeNode) nodelist.get(0); 412 413 for (int i = 1; i < nodelist.size(); ++i) { 414 nodes = new TreeNode[2]; 415 nodes[0] = result; 416 nodes[1] = (TreeNode) nodelist.get(i); 417 result = new SequenceNode(nodes); 418 result.protocol = protocol.substring(((Integer ) protindices.get(0)).intValue(), ((Integer ) protindices.get(i)).intValue()); 419 } 420 421 return result; 422 } 423 424 } else { 425 return (TreeNode) nodelist.get(0); 426 } 427 } 428 429 440 private TreeNode andparallel() throws SyntaxErrorException, IOException { 441 Vector nodelist = new Vector(); 442 Vector protindices = new Vector(); 443 protindices.add(new Integer (source.getIndex() - next_token.length() - 1)); 444 445 nodelist.add(orparallel()); 446 while (next_token == "|") { 447 next_token = nextToken(); 448 nodelist.add(orparallel()); 449 protindices.add(new Integer (source.getIndex() - next_token.length() - (next_token.length() > 0 ? 1 : 0))); 450 } 451 454 if (nodelist.size() > 1) { 455 if (MULTINODES) { 456 TreeNode[] nodes = new TreeNode[nodelist.size()]; 457 for (int i = 0; i < nodelist.size(); ++i) 458 nodes[i] = (TreeNode) nodelist.get(i); 459 460 TreeNode newnode = new AndParallelNode(nodes); 461 newnode.protocol = protocol.substring(((Integer ) protindices.get(0)).intValue(), ((Integer ) protindices.lastElement()).intValue()); 462 return newnode; 463 } else { 464 TreeNode[] nodes = new TreeNode[2]; 465 TreeNode result = (TreeNode) nodelist.get(0); 466 467 for (int i = 1; i < nodelist.size(); ++i) { 468 nodes = new TreeNode[2]; 469 nodes[0] = result; 470 nodes[1] = (TreeNode) nodelist.get(i); 471 result = new AndParallelNode(nodes); 472 result.protocol = protocol.substring(((Integer ) protindices.get(0)).intValue(), ((Integer ) protindices.get(i)).intValue()); 473 } 474 475 return result; 476 } 477 478 } else { 479 return (TreeNode) nodelist.get(0); 480 } 481 482 } 483 484 495 private TreeNode orparallel() throws SyntaxErrorException, IOException { 496 Vector nodelist = new Vector(); 497 Vector protindices = new Vector(); 498 protindices.add(new Integer (source.getIndex() - next_token.length() - 1)); 499 500 nodelist.add(term()); 501 while (next_token == "||") { 502 next_token = nextToken(); 503 nodelist.add(term()); 504 protindices.add(new Integer (source.getIndex() - next_token.length() - (next_token.length() > 0 ? 1 : 0))); 505 } 506 507 513 TreeNode result = (TreeNode) nodelist.get(0); 514 for (int i = 1; i < nodelist.size(); ++i) { 515 516 TreeNode[] altnodes = new TreeNode[3]; 517 TreeNode[] apnodes = new TreeNode[2]; 518 apnodes[0] = result; 519 apnodes[1] = (TreeNode) nodelist.get(i); 520 altnodes[0] = result; 521 altnodes[1] = (TreeNode) nodelist.get(i); 522 altnodes[2] = new AndParallelNode(apnodes); 523 result = new AlternativeNode(altnodes); 524 ((AlternativeNode)result).setorparallel(); 525 result.protocol = protocol.substring(((Integer ) protindices.get(0)).intValue(), ((Integer ) protindices.get(i)).intValue()); 527 } 528 529 return result; 530 } 531 532 548 private TreeSet collectList(String endmark) throws SyntaxErrorException, IOException { 549 TreeSet result = new TreeSet(); 550 while (isTokenID) { 551 if (next_token.startsWith("?") || next_token.startsWith("!") || next_token.startsWith("#")) { 552 if (next_token.endsWith("^") || next_token.endsWith("$") || next_token.endsWith("~")) { 554 Debug.println(3, "CollectList: action token"); 556 557 result.add(new Integer (repository.addItem(next_token))); 558 559 } else { 560 Debug.println(3, "CollectList: action token without"); 561 563 result.add(new Integer (repository.addItem(next_token + "^"))); 564 565 result.add(new Integer (repository.addItem(getReverseAction(next_token + "$")))); 567 568 } 569 } else { 570 if (next_token.endsWith("^") || next_token.endsWith("$") || next_token.endsWith("~")) { 572 Debug.println(3, "CollectList: adding event"); 573 result.add(new Integer (repository.addItem("?" + next_token))); 575 576 result.add(new Integer (repository.addItem("!" + next_token))); 577 578 if (endmark == "&") { result.add(new Integer (repository.addItem("#" + next_token))); 580 } 581 } else { 582 Debug.println(3, "CollectList: adding event name"); 583 result.add(new Integer (repository.addItem("?" + next_token + "^"))); 585 586 result.add(new Integer (repository.addItem("?" + next_token + "$"))); 587 588 result.add(new Integer (repository.addItem("!" + next_token + "^"))); 589 590 result.add(new Integer (repository.addItem("!" + next_token + "$"))); 591 592 if (endmark == "&") { result.add(new Integer (repository.addItem("#" + next_token + "^"))); 594 595 result.add(new Integer (repository.addItem("#" + next_token + "$"))); 596 597 } 598 } 599 } 600 next_token = nextToken(); 601 if (next_token == endmark) { 602 Debug.println(2, "End mark reached "); 603 next_token = nextToken(); 604 return result; 605 } 606 if (next_token.compareTo(",") != 0) 607 throw new SyntaxErrorException("Comma expected in list"); 608 else 609 next_token = nextToken(); 610 } 611 if (next_token == endmark) { 612 Debug.println(2, "End mark reached"); 613 next_token = nextToken(); 614 return result; 615 } else 616 throw new SyntaxErrorException("List syntax error"); 617 } 618 619 631 private TreeNode restriction() throws SyntaxErrorException, IOException { 632 int protstart = source.getIndex() - next_token.length() - 1; 633 TreeNode result = alternative(); 634 635 while (next_token == "\\") { 636 Debug.println(2, "Restriction found"); 637 next_token = nextToken(); 638 if (next_token != "(") 639 throw new SyntaxErrorException("Restriction list expected"); 640 next_token = nextToken(); 641 TreeSet sync = collectList(")"); 642 Debug.println(2, "Restriction action tokens: " + sync.toString()); 643 644 649 result = new RestrictionNode(result, sync, repository); 650 result.protocol = protocol.substring(protstart, source.getIndex() - next_token.length()); 651 } 652 653 return result; 654 } 655 656 668 private TreeNode composition() throws SyntaxErrorException, IOException { 669 int protstart = source.getIndex() - next_token.length() - 1; 670 671 TreeNode node1 = restriction(); 672 673 while (next_token == "&") { 674 Debug.println(2, "Composition found"); 675 next_token = nextToken(); 676 TreeSet sync = collectList("&"); 677 Debug.println(2, "Composition action tokens: " + sync.toString()); 678 679 683 684 TreeNode node2 = restriction(); 685 node1 = new ConsentNode(node1, node2, sync, new TreeSet(), repository, true); 687 node1.protocol = protocol.substring(protstart, source.getIndex() - next_token.length()); 688 689 } 690 return node1; 691 } 692 693 704 private TreeNode adjustment() throws SyntaxErrorException, IOException { 705 int protstart = source.getIndex() - next_token.length() - 1; 706 707 TreeNode node1 = composition(); 708 709 while (next_token == "@") { 710 Debug.println(2, "Adjustment found"); 711 next_token = nextToken(); 712 TreeSet sync = collectList("@"); 713 Debug.println(2, "Adjustment action tokens: " + sync.toString()); 714 715 719 TreeNode node2 = composition(); 720 node1 = new AdjustmentNode(node1, node2, sync); 721 node1.protocol = protocol.substring(protstart, source.getIndex() - next_token.length()); 722 723 } 724 return node1; 725 } 726 727 739 private TreeNode term() throws SyntaxErrorException, IOException { 740 int protstart = source.getIndex() - next_token.length() - 1; 741 742 TreeNode result = factor(); 743 744 if (next_token == "*") { 745 next_token = nextToken(); 746 result = new RepetitionNode(result); result.protocol = protocol.substring(protstart, source.getIndex() - next_token.length()); 748 749 } 750 751 return result; 752 } 753 754 766 private TreeNode factor() throws SyntaxErrorException, IOException { 767 TreeNode result; 768 if (next_token.equals("NULL")) { 769 result = new NullNode(); 770 result.protocol = "null"; 771 next_token = nextToken(); 772 } 773 774 else if (next_token == "(") { 775 next_token = nextToken(); 776 result = adjustment(); 777 if (next_token != ")") { 778 throw new SyntaxErrorException(") expected"); 779 } 780 next_token = nextToken(); 781 } 782 783 else if (next_token == "[") { 784 Debug.println(2, "Atomic action found"); 785 next_token = nextToken(); 786 787 TreeSet events = collectList("]"); 788 789 result = new AtomicNode(repository.addAtomicItem(events), events, repository); 790 791 } 792 793 else if (next_token.equals("")) { 794 result = null; 795 } else { int protstart = source.getIndex() - next_token.length() - 1; 797 798 if (!isTokenID) 799 throw new SyntaxErrorException("identifier expected, last token " + next_token); 800 String event = next_token; 801 next_token = nextToken(); 802 if (next_token == "{") { 803 next_token = nextToken(); 805 TreeNode pom = alternative(); 806 807 if (next_token != "}") 808 throw new SyntaxErrorException("} expected"); 809 810 int protstop = source.getIndex() - next_token.length(); 811 812 next_token = nextToken(); 813 814 EventNode start = new EventNode(repository.addItem(event + "^"), repository); 817 start.protocol = event + "^"; 818 819 EventNode stop; 820 821 825 String rev = getReverseAction(event); 826 stop = new EventNode(repository.addItem(rev + "$"), repository); 827 stop.protocol = rev + "$"; 828 830 834 TreeNode[] nodearray = new TreeNode[3]; 835 nodearray[0] = start; 836 nodearray[1] = pom; 837 nodearray[2] = stop; 838 result = new SequenceNode(nodearray); 839 result.protocol = protocol.substring(protstart, protstop); 840 841 Debug.println(3, "Nested call abbreviation:"); 842 844 } else { EventNode a = new EventNode(repository.addItem(event), repository); 846 if (isSimpleCall(event)) { EventNode start = new EventNode(repository.addItem(event + "^"), repository); 848 start.protocol = event + "^"; 849 EventNode stop = new EventNode(repository.addItem(getReverseAction(event + "$")), repository); 850 stop.protocol = getReverseAction(event + "$"); 851 852 TreeNode[] nodearray = new TreeNode[2]; 853 nodearray[0] = start; 854 nodearray[1] = stop; 855 result = new SequenceNode(nodearray); 856 result.protocol = event; 857 } else { result = a; 859 result.protocol = event; 860 } 861 } 862 } 863 return result; 864 } 865 866 878 public TreeNode build(ProtocolReader reader) throws SyntaxErrorException { 879 Debug.println(1, "Protocol Build: start"); 880 try { 881 source = reader; 882 protocol = new String (); 883 next_char = (char) source.read(); 884 if (next_char == -1) 885 return null; 886 887 next_token = nextToken(); 888 TreeNode m = adjustment(); 889 if (next_token != "") 890 throw new SyntaxErrorException("Unexpected token: '" + next_token + "'."); 891 892 Debug.println(1, "Protocol Build: finished"); 893 return m; 895 } catch (IOException e) { 896 return null; 897 } 898 } 899 900 } 901 902 | Popular Tags |