2011-10-18 13 views
7

chcę analizowaćtokeny Znalezienie w Smalltalk String z PetitParser

'This,is,an,example,text' 

jak w findTokens

'This,is,an,example,text' findTokens: $, 
an OrderedCollection('This' 'is' 'an' 'example' 'text') 

ale nie mogę dowiedzieć się, jak to zrobić z PetitParser, delimitedBy: a separatedBy: didn” t pomógł mi próbowałem

(#any asParser delimitedBy: $, asParser) plus flatten parse: 'This,is,an,example,text' 

ale oczywiście nie pracował

Odpowiedz

1

Używam tego wzoru cały czas z PetitParser gdy chcę coś wykluczyć. Po prostu zdefiniuj "to, czego szukam" lub "co chcę wykluczyć" (cokolwiek łatwiej opisać) jako analizator składni, a następnie je neguję i przetwarzam w razie potrzeby.

s := 'This,is,an,example,text'. 
separator := $, asParser ==> [ :n | nil ]. 
token := separator negate plus flatten. 
p := (token separatedBy: separator) ==> [ :nodes | 
    nodes copyWithout: nil ]. 
p parse: s. 
+1

To 'copyWithout:' naprawdę wydaje się brzydkie ... Podejrzewam, że jest sposób na uniknięcie tego poprzez zdefiniowanie wariantu 'separatedBy:', który nie najpierw dodaj separatory do wyjścia ... Innym rozwiązaniem może być 'foldLeft:' ale jak widzę, wymaga to twojej klasy do zbierania tokenów. –

2

a #delimitedBy: b rozwija się do a , (b , a) star, więc Twój analizator składniowy ma taki sam komunikat "daj mi jedną znak oddzielony przecinkami".

To nie jest bardzo czytelny, ale to nie to, co chcesz:

((($, asParser not , #any asParser) ==> [:nodes | nodes second]) 
    plus flatten delimitedBy: $, asParser 

Pierwsza klauzula mówi „analizować wszystko, co nie jest przecinek”. Tak więc biorąc pod uwagę '12,24' otrzymujesz #('12' $, '24').

1

Spróbuj

(#word asParser plus flatten separatedBy: $, asParser) 
    ==> [:nodes| nodes copyWithout: $, ] 

Mam nadzieję, że zrozumiał, co chciałeś

+0

Tak, jedynym problemem z tym jest to, że jeśli słowo zawiera jakiekolwiek nie alfabetyczne znaki, które mogłyby przerwać parsowanie nie? – user1000565

+1

Tak, robi. Po prostu przypominałem twój przykład. Musisz określić, co naprawdę musisz przeanalizować. Jeśli to wszystko, co może ci się przydać za $, asParser neguje to, że Sean zasugerował: –

3

delimitedBy: można używać w połączeniu z withoutSeparators:

|text parser| 

text := 'This,is,an,example,text'. 
parser := (#word asParser plus flatten delimitedBy: ($, asParser)) withoutSeparators. 

parser parse: text 

Wydaje się być ostatnie ulepszenie PetitParser.