Oluşturduğum bir biçimlendirme dili için bir ayrıştırıcı yazıyorum (python ile yazma, ancak bu gerçekten bu soru ile ilgili değil - aslında bu kötü bir fikir gibi görünüyorsa, daha iyi bir yol için bir öneri isterim) .
Burada ayrıştırıcılar hakkında okuyorum: http://www.ferg.org/parsing/index.html ve doğru anlarsam içeriği jetonlara bölen lexer'ı yazmaya çalışıyorum. Anlamakta zorlandığım şey, hangi token türlerini kullanmam gerektiği veya bunları nasıl oluşturacağım. Örneğin, bağlandığım örnekteki belirteç türleri şunlardır:
- STRING
- IDENTIFIER
- NUMARA
- BEYAZ BOŞLUK
- YORUM YAP
- EOF
- {Ve (gibi birçok simge kendi simge türleri olarak sayılır)
Yaşadığım sorun, daha genel token türlerinin benim için biraz keyfi görünmesi. Örneğin, IDENTIFIER'a karşı neden kendi ayrı token türünü STRING yapıyor? Bir dize STRING_START + (IDENTIFIER | WHITESPACE) + STRING_START olarak temsil edilebilir.
Bu, dilimin zorluklarıyla da ilgili olabilir. Örneğin, değişken bildirimleri olarak yazılır {var-name var value}
ve ile konuşlandırılır {var-name}
. Kendi jetonları gibi görünüyor '{'
ve '}'
olmalı, ancak VAR_NAME ve VAR_VALUE uygun jeton türleri mi yoksa ikisi de IDENTIFIER kapsamında mı olacak? Dahası, VAR_VALUE aslında boşluk içerebilir. Sonraki boşluk var-name
, bildirideki değerin başlangıcını belirtmek için kullanılır. Diğer tüm boşluklar, değerin bir parçasıdır. Bu boşluk kendi jetonu mu oluyor? Boşluk yalnızca bu bağlamda bu anlama sahiptir. Dahası, {
değişken bir bildirimin başlangıcı olmayabilir .. bağlama bağlıdır (yine bu kelime var!). {:
bir isim bildirimi başlatır ve{
bazı değerlerin bir parçası olarak bile kullanılabilir.
Benim dilim Python'a benzer, çünkü bloklar girintiyle oluşturulmuştur. Python'un INDENT ve DEDENT jetonlarını oluşturmak için lexer'ı nasıl kullandığı hakkında okuyordum (bu, daha fazla veya daha az başka dilde ne yapacağını {
ve }
ne yapacağını). Python bağlamdan bağımsız olduğunu iddia ediyor, bu da bana en azından lexer'ın jeton oluştururken akışta nerede olduğunu umursamaması gerektiği anlamına geliyor. Python'un lexer'ı, önceki karakterleri bilmeden belirli bir uzunlukta bir INDENT jetonu oluşturduğunu nasıl biliyor (örn. Önceki satırın yeni satır olduğunu, bu nedenle INDENT için boşluklar oluşturmaya başlayın)? Soruyorum çünkü bunu da bilmem gerekiyor.
Son sorum en aptal olanı: bir lexer neden gerekli? Bana öyle geliyor ki, ayrıştırıcı karakter karaktere gidebilir ve nerede olduğunu ve ne beklediğini anlayabilir. Lexer basitliğin faydasını ekliyor mu?