414 self addTransitionFrom: fromState to: toState onCharacterSet: characterSet priority: 0 |
485 self addTransitionFrom: fromState to: toState onCharacterSet: characterSet priority: 0 |
415 ! |
486 ! |
416 |
487 |
417 addTransitionFrom: fromState to: toState onCharacterSet: characterSet priority: priority |
488 addTransitionFrom: fromState to: toState onCharacterSet: characterSet priority: priority |
418 | transition | |
489 | transition | |
419 transition := PEGFsaTransition new |
490 transition := PEGFsaCharacterTransition new |
420 characterSet: characterSet; |
491 characterSet: characterSet; |
421 destination: toState; |
492 destination: toState; |
422 priority: priority; |
493 priority: priority; |
423 yourself. |
494 yourself. |
424 |
495 |
425 fromState addTransition: transition |
496 fromState addTransition: transition |
426 ! |
497 ! |
427 |
498 |
|
499 addTransitionFrom: fromState to: toState onPredicate: block |
|
500 self addTransitionFrom: fromState to: toState onPredicate: block priority: 0 |
|
501 ! |
|
502 |
|
503 addTransitionFrom: fromState to: toState onPredicate: block priority: priority |
|
504 | transition | |
|
505 transition := PEGFsaPredicateTransition new |
|
506 predicate: block; |
|
507 destination: toState; |
|
508 priority: priority; |
|
509 yourself. |
|
510 |
|
511 fromState addTransition: transition |
|
512 ! |
|
513 |
428 addTransitionFrom: fromState to: toState priority: priority |
514 addTransitionFrom: fromState to: toState priority: priority |
429 | transition | |
515 | transition | |
|
516 "should not use minus priority epsilons any more" |
|
517 self assert: (priority == 0). |
430 self assert: (states includes: fromState). |
518 self assert: (states includes: fromState). |
431 self assert: (states includes: toState). |
519 self assert: (states includes: toState). |
432 |
520 |
433 transition := PEGFsaTransition new |
521 transition := PEGFsaEpsilonTransition new |
434 destination: toState; |
522 destination: toState; |
435 priority: priority; |
523 priority: priority; |
436 yourself. |
524 yourself. |
437 |
525 |
438 fromState addTransition: transition. |
526 fromState addTransition: transition. |
440 |
528 |
441 adopt: fsa |
529 adopt: fsa |
442 states addAll: fsa reachableStates. |
530 states addAll: fsa reachableStates. |
443 ! |
531 ! |
444 |
532 |
|
533 decreasePriority |
|
534 ^ self decreasePriorityBy: 1 |
|
535 ! |
|
536 |
|
537 decreasePriorityBy: value |
|
538 self states select: [ :s | s hasPriority ] thenDo: [ :s | |
|
539 s decreasePriorityBy: value. |
|
540 ]. |
|
541 |
|
542 self allTransitions do: [ :t | |
|
543 t decreasePriorityBy: value |
|
544 ] |
|
545 ! |
|
546 |
445 finalState: state |
547 finalState: state |
446 self assert: state isFinal not. |
548 self assert: state isFinal not. |
447 state final: true. |
549 state final: true. |
|
550 state priority: 0. |
448 ! |
551 ! |
449 |
552 |
450 fixFinalStatePriorities |
553 fixFinalStatePriorities |
451 self finalStates do: [ :s | |
554 self finalStates do: [ :s | |
452 s hasPriority ifFalse: [ s priority: 0 ] |
555 s hasPriority ifFalse: [ s priority: 0 ] |
453 ] |
556 ] |
454 ! |
557 ! |
455 |
558 |
|
559 minimize |
|
560 ^ PEGFsaMinimizator new minimize: self |
|
561 ! |
|
562 |
|
563 removePriorities |
|
564 self states select: [ :s| s hasPriority ] thenDo: [ :s | |
|
565 s priority: 0 |
|
566 ]. |
|
567 |
|
568 self allTransitions do: [ :t | |
|
569 t priority: 0 |
|
570 ] |
|
571 ! |
|
572 |
456 removeState: state |
573 removeState: state |
457 self assert: (states includes: state). |
574 self assert: (states includes: state). |
458 states remove: state. |
575 states remove: state. |
459 ! |
576 ! |
460 |
577 |
461 replace: state with: anotherState |
578 replace: state with: anotherState |
462 | transitions | |
579 | transitions | |
463 self assert: (state class == PEGFsaState). |
580 self assert: (state isKindOf: PEGFsaState). |
464 self assert: (anotherState class == PEGFsaState). |
581 self assert: (anotherState isKindOf: PEGFsaState). |
465 |
582 |
466 transitions := self allTransitions. |
583 transitions := self allTransitions. |
467 |
584 |
468 transitions do: [ :t | |
585 transitions do: [ :t | |
469 (t destination == state) ifTrue: [ |
586 (t destination == state) ifTrue: [ |
470 t destination: anotherState. |
587 t destination: anotherState. |
471 ] |
588 ] |
472 ]. |
589 ]. |
473 states := startState reachableStates. |
590 |
|
591 state == startState ifTrue: [ startState := anotherState ]. |
|
592 states remove: state. |
|
593 states add: anotherState. |
|
594 ! |
|
595 |
|
596 retval: returnValue |
|
597 self finalStates do: [ :s | |
|
598 self assert: s retval isNil. |
|
599 s retval: returnValue |
|
600 ] |
474 ! |
601 ! |
475 |
602 |
476 startState: state |
603 startState: state |
477 self assert: (states includes: state). |
604 self assert: (states includes: state). |
478 |
605 |
479 startState := state |
606 startState := state |
|
607 ! ! |
|
608 |
|
609 !PEGFsa methodsFor:'modifications - determinization'! |
|
610 |
|
611 determinize |
|
612 ^ PEGFsaSequenceDeterminizator new determinize: self. |
|
613 ! |
|
614 |
|
615 determinize: joinDictionary |
|
616 self error: 'deprecated'. |
|
617 |
|
618 self removeEpsilons. |
|
619 self removeUnreachableStates. |
|
620 self removeLowPriorityTransitions. |
|
621 self mergeTransitions. |
|
622 |
|
623 |
|
624 states := self topologicalOrder asOrderedCollection. |
|
625 |
|
626 states do: [ :state | |
|
627 state determinize: joinDictionary. |
|
628 ]. |
|
629 |
|
630 states := startState reachableStates. |
|
631 |
|
632 self removeUnreachableStates. |
|
633 self removeLowPriorityTransitions. |
|
634 self mergeTransitions. |
|
635 |
|
636 ! |
|
637 |
|
638 determinizeChoice |
|
639 ^ PEGFsaChoiceDeterminizator new determinize: self. |
|
640 ! |
|
641 |
|
642 determinizeStandard |
|
643 ^ PEGFsaDeterminizator new determinize: self. |
|
644 ! ! |
|
645 |
|
646 !PEGFsa methodsFor:'modifications - epsilons'! |
|
647 |
|
648 removeEpsilonTransition: transition source: state |
|
649 ^ self removeEpsilonTransition: transition source: state openSet: IdentitySet new |
|
650 ! |
|
651 |
|
652 removeEpsilonTransition: transition source: source openSet: openSet |
|
653 | destination | |
|
654 (openSet includes: transition) ifTrue: [ self error: 'loop in epsilons?!!' ]. |
|
655 openSet add: transition. |
|
656 |
|
657 destination := transition destination. |
|
658 |
|
659 "First Remove Recursively" |
|
660 ((self transitionsFor: destination ) select: [ :t | t isEpsilon ]) do: [ :t | |
|
661 self removeEpsilonTransition: t source: destination openSet: openSet |
|
662 ]. |
|
663 |
|
664 self assert: transition isEpsilon. |
|
665 self assert: transition priority = 0. |
|
666 |
|
667 (destination transitions) do: [ :t | |
|
668 source addTransition: (t copy) |
|
669 ]. |
|
670 |
|
671 source mergeInfo: destination into: source. |
|
672 |
|
673 destination isFinal ifTrue: [ |
|
674 source final: true. |
|
675 source retval: destination retval. |
|
676 ]. |
|
677 |
|
678 source removeTransition: transition. |
|
679 ! |
|
680 |
|
681 removeEpsilons |
|
682 "First, remove the negative values from epsilons" |
|
683 self removeNegativeEpsilons. |
|
684 |
|
685 states do: [ :state | |
|
686 self removeEpsilonsFor: state |
|
687 ] |
|
688 ! |
|
689 |
|
690 removeEpsilonsFor: state |
|
691 (self transitionsFor: state) copy do: [ :t | |
|
692 (t isEpsilon and: [ t destination isStub not ]) ifTrue: [ |
|
693 self removeEpsilonTransition: t source: state |
|
694 ] |
|
695 ] |
|
696 ! |
|
697 |
|
698 removeNegativeEpsilonTransition: transition source: state |
|
699 ^ self removeNegativeEpsilonTransition: transition source: state openSet: IdentitySet new |
|
700 ! |
|
701 |
|
702 removeNegativeEpsilonTransition: transition source: source openSet: openSet |
|
703 | destination | |
|
704 (openSet includes: transition) ifTrue: [ self error: 'loop in epsilons?!!' ]. |
|
705 openSet add: transition. |
|
706 |
|
707 destination := transition destination. |
|
708 |
|
709 "First Remove Recursively" |
|
710 ((self transitionsFor: destination ) select: [ :t | t isEpsilon ]) do: [ :t | |
|
711 self removeNegativeEpsilonTransition: t source: destination openSet: openSet |
|
712 ]. |
|
713 |
|
714 "JK: Problem alert: if two different epsilons point to the same state, |
|
715 it will decreas the state priority two times!! I don't know how to handle |
|
716 this situation properly and I make sure during FSA generation that there |
|
717 are no two paths to one state (except for loops). |
|
718 " |
|
719 (self statesReachableFrom: destination) do: [ :s | |
|
720 s decreasePriorityBy: transition priority abs. |
|
721 s transitions do: [ :t | t decreasePriorityBy: transition priority abs ] |
|
722 ]. |
|
723 |
|
724 transition priority: 0. |
|
725 ! |
|
726 |
|
727 removeNegativeEpsilons |
|
728 " |
|
729 This will remove only negative values from epsilons, the epsilons itself will not |
|
730 be removed!! |
|
731 " |
|
732 states do: [ :state | |
|
733 self removeNegativeEpsilonsFor: state |
|
734 ] |
|
735 ! |
|
736 |
|
737 removeNegativeEpsilonsFor: state |
|
738 (self transitionsFor: state) copy do: [ :t | |
|
739 t isEpsilon ifTrue: [ |
|
740 self removeNegativeEpsilonTransition: t source: state |
|
741 ] |
|
742 ] |
480 ! ! |
743 ! ! |
481 |
744 |
482 !PEGFsa methodsFor:'printing'! |
745 !PEGFsa methodsFor:'printing'! |
483 |
746 |
484 asString |
747 asString |
567 ! ! |
839 ! ! |
568 |
840 |
569 !PEGFsa methodsFor:'transformations'! |
841 !PEGFsa methodsFor:'transformations'! |
570 |
842 |
571 compact |
843 compact |
572 self fixFinalStatePriorities. |
844 self error: 'deprecated?' |
573 self determinize. |
|
574 self minimize. |
|
575 |
|
576 self checkSanity. |
|
577 ! |
|
578 |
|
579 determinize |
|
580 | joinDictionary | |
|
581 self removeEpsilons. |
|
582 |
|
583 self removeUnreachableStates. |
|
584 self removeLowPriorityTransitions. |
|
585 self mergeTransitions. |
|
586 |
|
587 joinDictionary := Dictionary new. |
|
588 self topologicalOrder do: [:state | state determinize: joinDictionary ]. |
|
589 |
|
590 states := startState reachableStates. |
|
591 |
|
592 self removeUnreachableStates. |
|
593 self removeLowPriorityTransitions. |
|
594 self mergeTransitions. |
|
595 |
|
596 ! |
845 ! |
597 |
846 |
598 mergeTransitions |
847 mergeTransitions |
599 | toRemove | |
848 | | |
600 self reachableStates do: [ :state | |
849 self reachableStates do: [ :state | |
601 toRemove := OrderedCollection new. |
850 state mergeTransitions. |
602 state transitionPairs do:[ :pair | |
|
603 (pair first destination = pair second destination) ifTrue: [ |
|
604 pair first mergeWith: pair second. |
|
605 toRemove add: pair second. |
|
606 ] |
|
607 ]. |
|
608 toRemove do: [ :t | |
|
609 state removeTransition: t |
|
610 ] |
|
611 ] |
|
612 ! |
|
613 |
|
614 minimize |
|
615 | pair | |
|
616 pair := self statePairs detect: [ :p | p first equals: p second ] ifNone: [ nil ]. |
|
617 [ pair isNil not ] whileTrue: [ |
|
618 "Join priorities, because equivalency of priorities does not imply from the equeality of states" |
|
619 pair first joinPriority: pair second newState: pair first. |
|
620 pair first joinName: pair second newState: pair first. |
|
621 self replace: pair second with: pair first. |
|
622 self mergeTransitions. |
|
623 pair := self statePairs detect: [ :p | p first equals: p second ] ifNone: [ nil ]. |
|
624 ]. |
|
625 ! |
|
626 |
|
627 removeEpsilonTransition: transition source: state |
|
628 ^ self removeEpsilonTransition: transition source: state openSet: IdentitySet new |
|
629 ! |
|
630 |
|
631 removeEpsilonTransition: transition source: source openSet: openSet |
|
632 | destination | |
|
633 (openSet includes: transition) ifTrue: [ self error: 'loop in epsilons?!!' ]. |
|
634 openSet add: transition. |
|
635 |
|
636 destination := transition destination. |
|
637 |
|
638 "First Remove Recursively" |
|
639 ((self transitionsFor: destination ) select: [ :t | t isEpsilon ]) do: [ :t | |
|
640 self removeEpsilonTransition: t source: destination openSet: openSet |
|
641 ]. |
|
642 |
|
643 (transition priority abs) timesRepeat: [ |
|
644 (self statesReachableFrom: destination) do: [ :s | |
|
645 s decreasePriority. |
|
646 s transitions do: [ :t | t decreasePriority ] |
|
647 ] |
|
648 ]. |
|
649 |
|
650 (destination transitions) do: [ :t | |
|
651 source addTransition: (t copy) |
|
652 ]. |
|
653 |
|
654 destination hasPriority ifTrue: [ |
|
655 source hasPriority ifTrue: [ |
|
656 "self assert: source priority == destination priority" |
|
657 self flag: 'I am not 100% sure about this case' |
|
658 ]. |
|
659 source priority: destination priority |
|
660 ]. |
|
661 |
|
662 destination isFinal ifTrue: [ |
|
663 source final: true. |
|
664 source retval: destination retval. |
|
665 ]. |
|
666 |
|
667 source removeTransition: transition. |
|
668 ! |
|
669 |
|
670 removeEpsilons |
|
671 states do: [ :state | |
|
672 self removeEpsilonsFor: state |
|
673 ] |
|
674 ! |
|
675 |
|
676 removeEpsilonsFor: state |
|
677 (self transitionsFor: state) copy do: [ :t | |
|
678 t isEpsilon ifTrue: [ |
|
679 self removeEpsilonTransition: t source: state |
|
680 ] |
|
681 ] |
851 ] |
682 ! |
852 ! |
683 |
853 |
684 removeLowPriorityTransitions |
854 removeLowPriorityTransitions |
685 states do: [ :state | |
855 states do: [ :state | |
686 self removeLowPriorityTransitionsFor: state |
856 self removeLowPriorityTransitionsFor: state |
687 ] |
857 ] |
688 ! |
858 ! |
689 |
859 |
690 removeLowPriorityTransitionsFor: state |
860 removeLowPriorityTransitionsFor: state |
|
861 | transitions | |
691 state hasPriority ifFalse: [ ^ self ]. |
862 state hasPriority ifFalse: [ ^ self ]. |
692 state isFinal ifFalse: [ ^ self ]. |
863 state isFinal ifFalse: [ ^ self ]. |
693 |
864 "TODO JK: I can probably cut some transitions from multivalu as well" |
694 state transitions do: [ :t | |
865 state isMultivalue ifTrue: [ ^ self ]. |
|
866 |
|
867 transitions := state transitions copy. |
|
868 transitions do: [ :t | |
695 (t priority < state priority) ifTrue: [ |
869 (t priority < state priority) ifTrue: [ |
696 state removeTransition: t |
870 state removeTransition: t |
697 ] |
871 ] |
698 ] |
872 ] |
699 ! |
873 ! |