Pek çok formalizm var, bu yüzden diğer kaynakları faydalı bulabilirken, gerekli olmadıklarını açıkça belirtmeyi umuyorum.
Bir RM, sonlu durumlu bir makineden ve her biri negatif olmayan bir tamsayıya sahip olan sınırlı sayıda adlandırılmış kayıttan oluşur. Metin girişi kolaylığı için bu görev, durumların da adlandırılmasını gerektirir.
Üç tür durum vardır: her ikisi de belirli bir sicile başvuru yapan artma ve azalış; ve sonlandırın. Bir artış durumu kayıt defterini arttırır ve kontrolü bir halefine geçirir. Bir azalma durumunun iki halefi vardır: Eğer kayıt sıfırı sıfır değilse, o zaman onu azaltır ve kontrolü ilk halefiye geçirir; Aksi halde (yani sicil sıfırdır) sadece ikinci ardılıya kontrolü geçer.
Bir programlama dili olarak "nezaket" için, sonlandırma durumları yazdırmak için kodlanmış bir dize alır (böylece olağanüstü sonlandırmayı belirtebilirsiniz).
Giriş stdin'den. Giriş formatı, durum başına bir satır ve ardından ilk kayıt içeriğinden oluşur. İlk satır ilk durumdur. Durum çizgileri için BNF:
line ::= inc_line
| dec_line
inc_line ::= label ' : ' reg_name ' + ' state_name
dec_line ::= label ' : ' reg_name ' - ' state_name ' ' state_name
state_name ::= label
| '"' message '"'
label ::= identifier
reg_name ::= identifier
Tanımlayıcı ve mesaj tanımında bazı esneklikler var. Programınız gerekir bir tanıtıcı olarak boş olmayan bir alfanümerik dize kabul ama olabilir isterseniz daha genel dizeleri kabul (örneğin eğer dil destekleri alt çizgilerle tanımlayıcılar ve bununla işe sizin için daha kolay). Benzer şekilde, mesaj için boş olmayan bir alfanümerik ve boşluk dizesini kabul etmelisiniz , ancak isterseniz kaçan yeni satırlara ve çift alıntı karakterlerine izin veren daha karmaşık dizeleri kabul edebilirsiniz .
İlk kayıt değerlerini veren son girdi satırı, boş olmayan bir boşlukla ayrılmış tanımlayıcı = int atama listesidir. Programda belirtilen tüm kayıtları başlatması gerekli değildir: başlatılmayanların 0 olduğu varsayılır.
Programınız girişi okumalı ve RM'yi simüle etmelidir. Bir sonlandırma durumuna ulaştığında, mesajı, yeni bir satırı ve ardından tüm kayıtların değerlerini (herhangi bir uygun, insan tarafından okunabilen, format ve herhangi bir sırayla) yayacaktır.
Not: resmi olarak kayıtlar sınırsız tamsayıları tutmalıdır. Ancak, hiçbir kaydın değerinin asla 2 ^ 30 değerini aşmayacağını varsaymak isterseniz.
Bazı basit örnekler
a + = b, a = 0s0 : a - s1 "Ok"
s1 : b + s0
a=3 b=4
Beklenen sonuçlar:
Ok
a=0 b=7
b + = a, t = 0
init : t - init d0
d0 : a - d1 a0
d1 : b + d2
d2 : t + d0
a0 : t - a1 "Ok"
a1 : a + a0
a=3 b=4
Beklenen sonuçlar:
Ok
a=3 b=7 t=0
Trickier-to-pars makineleri için test kutuları
s0 : t - s0 s1
s1 : t + "t is 1"
t=17
Beklenen sonuçlar:
t is 1
t=1
ve
s0 : t - "t is nonzero" "t is zero"
t=1
Beklenen sonuçlar:
t is nonzero
t=0
Daha karmaşık bir örnek
DailyWTF'den Josephus'un problem kodu mücadelesinden alınmıştır. Girdi n (asker sayısı) ve k (avans) ve r cinsinden çıktı, hayatta kalan kişinin (sıfır indeksli) pozisyonudur.
init0 : k - init1 init3
init1 : r + init2
init2 : t + init0
init3 : t - init4 init5
init4 : k + init3
init5 : r - init6 "ERROR k is 0"
init6 : i + init7
init7 : n - loop0 "ERROR n is 0"
loop0 : n - loop1 "Ok"
loop1 : i + loop2
loop2 : k - loop3 loop5
loop3 : r + loop4
loop4 : t + loop2
loop5 : t - loop6 loop7
loop6 : k + loop5
loop7 : i - loop8 loopa
loop8 : r - loop9 loopc
loop9 : t + loop7
loopa : t - loopb loop7
loopb : i + loopa
loopc : t - loopd loopf
loopd : i + loope
loope : r + loopc
loopf : i + loop0
n=40 k=3
Beklenen sonuçlar:
Ok
i=40 k=3 n=0 r=27 t=0
Resim olarak bu program, görsel düşünen ve sözdizimini kavramada yararlı olacağını düşünenler için:
Eğer bu golftan hoşlanıyorsanız, devam filmine bir göz atın .