Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- calculateFirstOf: word
- "dodaj Fi(wi) do Fi(wi) dla kazdej produkcji Ai -> wi, gdzie Fi jest zdefiniowana nastepujaco:"
- (word isEmpty)
- "Fi(e) = { e }"
- ifTrue: [|set| set := Set new. set add: ''. ^set ]
- ifFalse: [
- |znak|
- znak := word first.
- (nieterminale includes: znak)
- "Fi(a w' ) = { a } dla kazdego terminalu a"
- ifFalse: [|set| set := Set new. set add: znak. ^set]
- ifTrue: [
- ((zbiorPierwszychZnakow at: znak) includes: '')
- "Fi(A w' ) = Fi(A) dla kazdego nieterminalu A z e nie nalezacego do Fi(A)"
- ifFalse: [^(zbiorPierwszychZnakow at: znak)]
- "Fi(A w' ) = Fi(A) \ { e } U Fi(w' ) dla kazdego nieterminalu A z e nalezacym do Fi(A)"
- ifTrue: [|set|
- set := (zbiorPierwszychZnakow at: znak).
- set remove: ''.
- set addAll: (self calculateFirstOf: word allButFirst ).
- ^set
- ]
- ]
- ]
- start: s rules: r
- "parser wzorowany na podstawie ponizszego algorytmu"
- "https://en.wikipedia.org/wiki/LL_parser"
- |brakZmian|
- brakZmian := false.
- start := s.
- rules := r.
- nieterminale := Set new.
- terminale := Set new.
- zbiorPierwszychZnakow := Dictionary new.
- zbiorNastepujacy := Dictionary new.
- tablicaSterujaca := Dictionary new.
- r do: [:produkcja |
- zbiorPierwszychZnakow
- at: produkcja key put: Set new;
- at: produkcja value put: Set new.
- nieterminale add: produkcja key
- ].
- r do: [:produkcja |
- (produkcja value) do: [:znak |
- (nieterminale includes: znak)
- ifFalse: [ terminale add: znak ]
- ]
- ].
- [brakZmian] whileFalse: [
- brakZmian := true.
- r do: [ :produkcja | |setToAdd size|
- size := (zbiorPierwszychZnakow at: produkcja value) size.
- setToAdd := (self calculateFirstOf: produkcja value).
- (zbiorPierwszychZnakow at: produkcja value) addAll: setToAdd.
- (size = (zbiorPierwszychZnakow at: produkcja value) size) not
- ifTrue: [ brakZmian := false. ]
- ].
- r do: [:rule||size|
- size := (zbiorPierwszychZnakow at: (rule key)) size.
- (zbiorPierwszychZnakow at: (rule key)) addAll: (zbiorPierwszychZnakow at: (rule value)).
- size = (zbiorPierwszychZnakow at: (rule key)) size
- ifFalse: [ brakZmian := false. ]
- ]
- ].
- nieterminale do: [:nieterminal | zbiorNastepujacy at: nieterminal put: Set new ].
- (zbiorNastepujacy at: s) add: $$.
- brakZmian := false.
- [brakZmian] whileFalse: [
- brakZmian := true.
- rules do: [:produkcja | |rightSide|
- rightSide := produkcja value.
- rightSide doWithIndex: [:char :i |
- (nieterminale includes: char)
- ifTrue: [|rest|
- rest := rightSide copyFrom: i + 1.
- ((rest size) = 0)
- ifTrue: [ |size|
- size := (zbiorNastepujacy at: char) size.
- (zbiorNastepujacy at: char) addAll: (zbiorNastepujacy at: produkcja key).
- size = ((zbiorNastepujacy at: char) size)
- ifFalse: [ brakZmian := false ]
- ]
- ifFalse: [|set|
- set := self calculateFirstOf: rest.
- (set includes: '')
- ifTrue: [ |size|
- size := (zbiorNastepujacy at: char) size.
- (zbiorNastepujacy at: char) addAll: (zbiorNastepujacy at: produkcja key).
- size = ((zbiorNastepujacy at: char) size)
- ifFalse: [ brakZmian := false ]
- ].
- set do: [:elem |
- ((nieterminale includes: elem) not)
- ifTrue: [ |size|
- size := (zbiorNastepujacy at: char) size.
- (zbiorNastepujacy at: char) add: elem.
- size = ((zbiorNastepujacy at: char) size)
- ifFalse: [ brakZmian := false ]
- ]
- ]
- ]
- ]
- ]
- ]
- ].
- terminale do: [:terminal |
- rules do: [:produkcja | |produkcjaKlucze|
- produkcjaKlucze := (produkcja key) asString , terminal asString.
- Transcript show: produkcjaKlucze.
- Transcript cr.
- (((zbiorPierwszychZnakow at: produkcja value) includes: terminal) or: [ ((zbiorPierwszychZnakow at: produkcja value) includes: '') and: [ ((zbiorNastepujacy at: produkcja key) includes: terminal) ] ])
- ifTrue: [
- (tablicaSterujaca includesKey: produkcjaKlucze)
- ifTrue: [^nil ]
- ifFalse: [ tablicaSterujaca at: produkcjaKlucze put: produkcja value ].
- ].
- ]
- ]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement