Programovací jazyky používané v SSSR (část 2 – SNOBOL)

Pavel Tišnovský 2. 3. 2010

Dnes si popíšeme další programovací jazyk, který byl používán nejenom na Západě, ale i v zemích RVHP, samozřejmě včetně SSSR. Byl vytvořen v Bellových laboratořích v průběhu let 1962 až 1967, se nazývá SNOBOL. Jedná se o jazyk specializovaný na zpracování textových dat, ale používal se i v jiných oborech.

Obsah

1. Programovací jazyk SNOBOL a Bellovy laboratoře

2. Rozšíření SNOBOLu

3. Základy programování v jazyku SNOBOL

4. Jednoduché programy

5. Použití příkazů skoku

6. Práce s poli a tabulkami

7. Obsah následující části seriálu

8. Literatura

9. Odkazy na Internetu

1. Programovací jazyk SNOBOL a Bellovy laboratoře

Bellovy laboratoře jsou v oblasti elektroniky a samozřejmě taktéž informatiky velmi známou institucí. Právě v Bellových laboratořích byl zkonstruován první tranzistor (William Shockley, Gerald Pearson, John Bardeen, Walter Brattain), vytvořena první verze dodnes široce používaného programovacího jazyka C (Dennis Ritchie) a v neposlední řadě taktéž funkční prototyp operačního systému UNIX (Ken Thompson, Dennis Ritchie, Brian Kernighan, Douglas McIlroy, Joe Ossanna a další). Kromě těchto známých projektů, z nichž například vynález tranzistoru byl odměněn Nobelovou cenou, však v Bellových laboratořích vzniklo i poměrně velké množství dalších více či méně úspěšných projektů. Jedním z těchto poněkud méně známých projektů je i programovací jazyk SNOBOL, který byl v Bellových laboratořích vyvíjen v průběhu let 1962 až 1967. Jeho autory jsou David J. Farber, Ralph E. Griswold a Ivan P. Polonsky.

snobol

Obrázek 1: Replika prvního tranzistoru vytvořeného týmem vedeným Williamem Shockleym v Bellových laboratořích.

2. Rozšíření SNOBOLu

První verze jazyka SNOBOL byla implementována na počítačích IBM 7090 (viz též pátou část tohoto seriálu, ve které jsme si stručně popsali celou řadu IBM 7000), v pozdější době však došlo k jeho rozšíření i na velké množství dalších počítačových architektur, například IBM System/360, PDP-10, UNIVAC 1108, GE 635, CDC 3600, CDC 6000, Atlas 2 a později též samozřejmě na osobní počítače (jedna z rozšiřujících variant tohoto jazyka nejenom pro PC se jmenuje SPITBOL). Jak již bylo zmíněno v perexu článku, používal se tento programovací jazyk poměrně intenzivně i v zemích RVHP, včetně SSSR, kde vzniklo několik implementací SNOBOLU 4. Tento jazyk je určený především pro zpracování textových dat, čemuž ostatně odpovídá i jeho název: zkratka SNOBOL značí StriNg Oriented SymBOlic Language. Zpracování textových dat (rozpoznání vzorů atd.) je podřízena syntaxe i sémantika tohoto programovacího jazyka. Kromě zpracování řetězců lze tento jazyk použít i pro manipulaci se symboly, podobně jako například programovací jazyk LISP. Některé z možností tohoto jazyka si ukážeme v následujících kapitolách.

snobol

Obrázek 2: Učebnice SNOBOLu, kterou napsali mj. i dva z autorů tohoto z dnešního pohledu poněkud zvláštního jazyka.

3. Základy programování v jazyku SNOBOL

Syntaxe programovacího jazyka SNOBOL je velmi jednoduchá, protože tento jazyk ve své základní podobě neobsahuje žádné podmíněné příkazy, programové smyčky ani jiné jazykové konstrukce známé z jiných (strukturovaných) jazyků. Namísto toho se struktura programů nejvíce podobá zápisu stavů a přechodů konečného automatu, což je ostatně při zpracovávání řetězců (či jiných dat) jeden ze základních nástrojů prakticky každého programátora. Nejprve si popišme základní syntaxi programovacího jazyka SNOBOL. Na každém programovém řádku se může nacházet až pět bloků, z nichž žádný není povinný:

  1. návěští (label)
  2. subjekt (subject)
  3. vzor (pattern)
  4. objekt (object)
  5. odkaz(y) na jiné příkazy (goto)

V případě, že se neprovádí vyhledávání řetězců podle zadaného vzoru, ani náhrada části řetězců za jiné řetězce, obsahuje programový řádek pouze trojici bloků:

  1. návěští (label)
  2. příkaz (statement)
  3. odkaz(y) na jiné příkazy (goto)

Nepovinné návěští (cíl skoku) je od příkazu odděleno mezerou, podmíněné či nepodmíněné odkazy jsou od příkazu odděleny dvojtečkou. V programech je možné používat běžné aritmetické výrazy (jejich části se od sebe musí oddělovat mezerou), proměnné (s automatickými konverzemi mezi celočíselným typem, reálným číslem a řetězcem) i některé speciální proměnné, jejichž použití ve skutečnosti vede k zavolání nějaké funkce operačního systému. Mezi speciální proměnné patří OUTPUT (standardní výstup) a INPUT (standardní vstup). Přiřazení nějaké hodnoty do proměnné OUTPUT způsobí její tisk na standardní výstup, naopak čtení z proměnné INPUT odpovídá načtení řetězce ze standardního vstupu (pojmy „standardní vstup“ a „standardní výstup“ nemusí odpovídat tomu, co si pod těmito souslovími představujeme v Unixu, neboť SNOBOL se používá na velkém množství různých platforem, které mají vstupně/výstupní část řešenou odlišným způsobem).

snobol

Obrázek 3: Další učebnice SNOBOLu, opět napsaná jedním z autorů tohoto jazyka.

4. Jednoduché programy

S využitím speciální proměnné OUTPUT je možné klasický program typu „Hello World“ zapsat ve SNOBOLu následujícím způsobem:

       OUTPUT = 'Hello World'
END

Jak jsme si již řekli v předchozí kapitole, lze načítání dat (řetězců) ze standardního vstupu provést jednoduše čtením „hodnoty“ proměnné INPUT (povšimněte si, jakým způsobem lze na výstupu spojit dva řetězce):

       OUTPUT = "Your name? "
       NAME = INPUT
       OUTPUT = "Hello " NAME
END

V programovacím jazyce SNOBOL je možné používat i aritmetické výrazy, ovšem musíme si dát pozor na to, že jednotlivé operátory musí být od operandů odděleny alespoň jednou mezerou (což na druhou stranu vede k větší čitelnosti programů):

       X = 3 * (1 + 2)
       Y = 2 * X / (X + 1)
       OUTPUT = "Result: " Y
END

5. Použití příkazů skoku

V předchozích dvou demonstračních programech se jednotlivé příkazy postupně prováděly jeden po druhém, ovšem v reálných aplikacích je zapotřebí používat nějakou formu větvení či smyček. Tyto činnosti je možné ve SNOBOLu implementovat pomocí nepodmíněných či podmíněných skoků. Za každý příkaz lze (po nezbytné dvojtečce) uvést jeden či více odkazů na jiné příkazy, přesněji řečeno na jejich návěští (label). Překladač rozeznává čtyři typy odkazů, z nichž první představuje skok provedený vždy (jedná se o nepodmíněný skok) a další tři typy odkazů představují podmíněné skoky nebo jejich kombinaci:

Forma zápisu Význam
:(label) skok provedený vždy
:S(label) skok provedený v případě, že příkaz skončil úspěšně
:F(label) skok provedený v případě neúspěšného provedení příkazu
:S(label1) F(label2) dvojice skoků – kombinace předchozích dvou možností

Důležité je, že všechny příkazy mohou ve SNOBOLu skončit úspěšně či neúspěšně. Například čtení ze standardního vstupu přes proměnnou INPUT může skončit neúspěchem v případě, že uživatel ukončil vstup dat, což se v Unixu provede klávesovou zkratkou CTRL+D (v DOSu CTRL+Z) atd. Pomocí podmíněných a nepodmíněných skoků lze vytvářet složitější programy, například postupné načítání řádků ze standardního vstupu až do doby, kdy uživatel vstup dat ukončí některou z výše uvedených klávesových zkratek (v programu je použit jak nepodmíněný skok na návěští ASK, tak i skok podmíněný na návěští DONE):

ASK
       OUTPUT = "Your name? "
       NAME = INPUT           :F(DONE)
       OUTPUT = "Hello " NAME :(ASK)
DONE
       OUTPUT = "Finished"
END

Další jednoduchý program, v němž je ukázáno použití proměnných a aritmetických výrazů, opisuje na standardní výstup řetězce, které přečetl ze standardního vstupu a na závěr ještě vypíše celkový počet zpracovaných textových řádků, například „THERE WERE 42 LINES“:

       N = 0
COPY   OUTPUT = INPUT           :F(DONE)
       N = N + 1                :(COPY)
DONE   OUTPUT = 'THERE WERE ' N ' LINES'
END

Následující program taktéž opisuje standardní vstup na standardní výstup, navíc však před každý řádek vypíše jeho délku oddělenou od zbytku řádku jednou mezerou:

LOOP   S = TRIM(INPUT)          :F(END)
       OUTPUT = SIZE(S) ' ' S   :(LOOP)
END

Jednodušší obdoba utility wc, která spočte jak celkový počet řádků, tak i počet znaků na všech řádcích:

       CHARS  = 0
       LINES  = 0
NEXTL  CHARS  = CHARS + SIZE(INPUT)    :F(DONE)
       LINES  = LINES + 1              :(NEXTL)
DONE   OUTPUT = CHARS ' characters'
       OUTPUT = +LINES ' lines read'
END
snobol

Obrázek 4: Učebnice SNOBOLu potřetí.

6. Práce s poli a tabulkami

Programovací jazyk SNOBOL umožňuje ve svých novějších verzích (SNOBOL 4) snadnou práci s poli a tabulkami. Pole se vytváří pomocí příkazu ARRAY, jemuž lze jako parametr předat rozměry všech jeho dimenzí. Přístup k prvkům polí se provádí, jak je tomu zvykem u většiny dnešních programovacích jazyků, zápisem indexu (či indexů) do hranatých závorek, popř. lze použít i závorky úhlové. V následujících příkladech je vytvořeno jednodimenzionální pole SEZNAM a dvoudimenzionální pole pojmenované POLE. Následně je do jednoho prvku pole přiřazena hodnota, přičemž SNOBOL nerozlišuje typ hodnoty, která se do pole přidává, což znamená, že například některé prvky pole mohou být řetězci, jiné prvky celočíselnými hodnotami a zbylé prvky reálnými čísly:

SEZNAM = ARRAY('42')
POLE = ARRAY('12,3')
SEZNAM[2] = 'POKUS'
SEZNAM<2> = 'POKUS'
POLE[2,3] = 1234

Pod pojmem „tabulky“ se ve SNOBOLu skrývají asociativní pole známé také pod názvem hešovací mapy, tedy datové struktury, se kterými se můžeme setkat prakticky ve všech současných mainstreamových programovacích jazycích. Celkový počet prvků není v tabulkách konstantní tak, jako je tomu u polí, což znamená, že počet prvků uložených v tabulce se může v průběhu provádění programu zvětšovat nebo i zmenšovat. Navíc se kromě celočíselných indexů mohou jako selektory použít i další hodnoty, především řetězce. Tímto způsobem se ve SNOBOLu vytváří například obdoby záznamů (struktur), viz následující příklad:

AUTOMOBIL = TABLE()
AUTOMOBIL['ZNACKA']='TRABANT'
AUTOMOBIL['TYP']=601
AUTOMOBIL['BARVA']='SEDIVA'
AUTOMOBIL['VYKON_HP']=26
AUTOMOBIL['VYBAVA']'='de Luxe'

Pro převod polí na tabulky a naopak se používá funkce CONVERT:

X = CONVERT(AUTOMOBIL, 'ARRAY')
Y = CONVERT(POLE, 'TABLE')
snobol

Obrázek 5: Další literatura o SNOBOLu, jejíž titul naznačuje, ve kterých oblastech se tento programovací jazyk taktéž používal.

7. Obsah následující části seriálu

V následující části seriálu o historii výpočetní techniky se opět budeme věnovat programovacím jazykům používaným v historii i v současnosti. Příště dokončíme popis programovacího jazyka SNOBOL (vysvětlíme si vyhledávání vzorů a nahrazování v řetězcích, což je nejdůležitější součást tohoto jazyka) a poté se již zaměříme především na programovací jazyk, který (spolu s programovacím jazykem C) snad nejvíce ovlivnil celou informatiku, a to jak v teoretické, tak i praktické rovině. Jedná se o jazyk LISP, který sice byl vytvořen již v roce 1958 (jedná se tedy o jeden z nejstarších vyšších programovacích jazyků vůbec), ovšem mnohé jeho dialekty se používají dodnes, tj. tento jazyk „žije“ již více než 50 let. V minulosti byl tento programovací jazyk tak oblíbený, že pro něj některé firmy, například Symbolics či BBN, vytvářely i specializované počítače, jejichž popisem se taktéž budeme v dalších částech tohoto seriálu zabývat.

snobol

Obrázek 6: Jedna z architektur počítačů specializovaných na vývoj v LISPu.

widgety

8. Literatura

  1. Ankrum,T. Scott
    „COBOL – A Best Practice (Sept, 2001)“
    COBOLReport.com
  2. Arranga,Edmund C.
    „The Viagrazation of COBOL“
    COBOLwebler.com
  3. Arranga, Edmund C. & Price, Wilson
    „Fresh from Y2K, What's next for COBOL? (March/April 2000)“
    IEEE Software
  4. Arranga et al
    „In COBOL's Defense : Roundtable Discussion (March/April 2000)“
    IEEE Software
  5. Badower, Justin
    „COBOL: Foundation of the future“
    COBOLwebler.com
  6. Brown, Gary DeWard
    „COBOL: The failure that wasn't“
    COBOLReport.com
  7. Burger,Thomas Wolfgang
    „COBOL in an open source future (May 2000)“
    IBM developerWorks : Linux : Linux articles
  8. Carr, Donald and Kizior, Ronald J.
    „The Case for Continued COBOL Education (March/April 2000)“
    IEEE Software
  9. Feiman, J.
    „The Gartner Programming Language Survey (October 2001)“
    Gartner Advisory
  10. Glass, Robert L.
    „Cobol – A Contradiction and an Enigma“
    COMMUNICATIONS OF THE ACM September 1997/Vol. 40, No. 9
  11. Griswold R. E., Poage J. F., Polonsky I. P.:
    „The SNOBOL4 Programming Language“
    second edition, Bell Telephone Laboratories, 1968, 1971
  12. Jones, Capers
    „The global economic impact of the year 2000 software problem“
    (Jan, 1997)
  13. Kappelman, Leon A.
    „Some Strategic Y2K Blessings (March/April 2000)“
    IEEE Software
  14. Kizior, Dr. Ronald J. and Carr, Donald and Halpern, Dr. Paul
    „What Professionals think of the Future of COBOL? “
  15. Murach, Mike
    „Is COBOL Dying … or Thriving? (February 2001)“
    The Cobol Newswire
  16. Pagnan, Martin
    „Can A Java Programmer Be Transitioned To Cobol? (Feb, 2002)“
    COBOLReport.com
  17. Reimann, Artur
    „COBOL, Language of Choice – Then and Now (January, 2001)“
    COBOLReport.com
  18. Sayles, Jonathan
    „COBOL and the Enterprise Business Application Programming Legacy“
    MicroFocus Ltd.
  19. Silverberg, Fred
    „COBOL and the Business Programming Paradigm“
    (1996)
  20. Sneed, Harry M.
    „The Evolution of COBOL“
    COBOLReport.com
  21. Wilkinson,Stephanie
    „From the Dustbin, Cobol Rises (May, 2001)“
    eWeek
  22. C.A.R. Hoare:
    „The Emperor's Old Clothes Communications of the ACM“
    1981
  23. IBM:
    „VS BASIC Language, Third edition“
  24. IBM:
    „VS Fortran Application Programming: Language reference“
  25. IBM:
    „IBM System/360 Operating System: ALGOL Language“
  26. B. Randell and L.J. Russell,
    „ALGOL 60 Implementation: The Translation and Use of ALGOL 60 Programs on a Computer“
    Academic Press, 1964. The design of the Whetstone Compiler.
  27. E. W, Dijkstra,
    „Algol 60 translation: an algol 60 translator for the x1 and making a translator for algol 60, report MR 35/61“
    Mathematisch Centrum, Amsterdam, 1961.
  28. Akin, Ed (2003):
    „Object Oriented Programming via Fortran 90/95 (1st ed.)“
    Cambridge University Press. ISBN 0–521–52408–3.
  29. Etter, D. M. (1990):
    „Structured FORTRAN 77 for Engineers and Scientists (3rd ed.)“
    The Benjamin/Cummings Publishing Company, Inc.. ISBN 0–8053–0051–1.
  30. Chapman, Stephen J. (2007):
    „Fortran 95/2003 for Scientists and Engineers (3rd ed.)“
    McGraw-Hill. ISBN 978–0–07–319157–7.
  31. Chapman, Stephen J. (2003):
    „Fortran 90/95 for Scientists and Engineers (2nd ed.)“
    McGraw-Hill. ISBN 0–07–282575–8.
  32. Chivers, Ian; Jane Sleightholme (2006):
    „Introduction to Programming with Fortran (1st ed.)“
    Springer. ISBN 1–84628–053–2.
  33. Ellis, T. M. R.; Ivor R. Phillips, Thomas M. Lahey (1994)
    „Fortran 90 Programming (1st ed.)“
    Addison Wesley. ISBN 0–201–54446–6.
  34. Kupferschmid, Michael (2002):
    „Classical Fortran: Programming for Engineering and Scientific Applications“
    Marcel Dekker (CRC Press). ISBN 0–8247–0802–4.
  35. McCracken, Daniel D. (1961):
    „A Guide to Fortran Programming“
    Wiley.
  36. McCracken, Daniel D. (1965):
    „A Guide to Fortran IV Programming“
    Wiley.
  37. Metcalf, Michael; John Reid, Malcolm Cohen (2004):
    „Fortran 95/2003 Explained“
    Oxford University Press. ISBN 0–19–852693–8.
  38. Nyhoff, Larry; Sanford Leestma (1995):
    „FORTRAN 77 for Engineers and Scientists with an Introduction to Fortran 90 (4th ed.)“
    Prentice Hall. ISBN 0–13–363003-X.

9. Odkazy na Internetu

  1. SNOBOL4 and SPITBOL Information
    http://www.sno­bol4.com/
  2. Vanilla Snobol4 Reference Manual
    http://burks.bton­.ac.uk/burks/lan­guage/snobol/cat­spaw/manual/con­tents.htm
  3. SNOBOL4.ORG – SNOBOL4 Resources
    http://www.sno­bol4.org/
  4. Snobol3 – Snobol 3 Interpreter Implemented in Java
    http://serl.cs­.colorado.edu/~den­nis/software/s3­.html
  5. Exploring Beautiful Languages – A guick look at SNOBOL
    http://langex­plr.blogspot.com/2007/12­/quick-look-at-snobol.html
  6. Rosetta Code: Roman_numerals
    http://rosetta­code.org/wiki/Ro­man_numerals
  7. Category:SNOBOL4
    http://rosetta­code.org/wiki/Ca­tegory:SNOBOL4
  8. An introduction to SNOBOL by James Ford
    http://drofmij­.awardspace.com/sno­bol/
  9. Rosetta Code – Category:COBOL
    http://rosetta­code.org/wiki/Ca­tegory:COBOL
  10. COmmon Business Oriented Language
    http://foldoc­.org/COBOL
  11. COBOL Compilers
    http://www-01.ibm.com/sof­tware/awdtool­s/cobol/
  12. Cobol: Not Dead Yet
    http://www.com­puterworld.com/s/ar­ticle/266156/C­obol_Not_Dead_Y­et?intsrc=kc_rfavs
  13. The future's bright … the future's Cobol
    http://features­.techworld.com/ap­plications/3056/the-futures-bright–the-futures-cobol/
  14. COBOL Example Programs
    http://www.csis­.ul.ie/COBOL/e­xamples/defau­lt.htm
  15. Introduction to COBOL
    http://www.csis­.ul.ie/COBOL/Cou­rse/COBOLIntro­.htm
  16. COBOL programming – tutorials, lectures, exercises, examples
    http://www.csis­.ul.ie/COBOL/
  17. Wikipedia: COBOL
    http://en.wiki­pedia.org/wiki/CO­BOL
  18. Humor on Computers, Systems and Programming
    http://www-crypto.htw-saarland.de/we­ber/misc/program­ming.html
  19. OpenCOBOL
    http://en.wiki­pedia.org/wiki/O­penCOBOL
  20. OpenCOBOL.org
    http://openco­bol.org/
  21. OpenCOBOL FAQ
    http://openco­bol.add1tocobol­.com/
  22. TinyCOBOL
    http://tiny-cobol.sourcefor­ge.net/
  23. TinyCOBOL FAQ
    http://tiny-cobol.sourcefor­ge.net/docs/faq/
  24. JTC1/SC22/WG4 – COBOL
    http://ra.dku­ug.dk/jtc1/sc2­2/wg4/
  25. COBOL on COGS
    http://www.co­boloncogs.org/IN­DEX.HTM
  26. Cobol Coders: Going, Going, Gone?
    http://www.com­puterworld.com/s/ar­ticle/266228/C­obol_Coders_Go­ing_Going_Gone_
  27. Rosetta Code – Category:Fortran
    http://rosetta­code.org/wiki/For­tran
  28. Rosetta Code – Category:Lisp
    http://rosetta­code.org/wiki/Ca­tegory:Lisp
  29. Algol 68 – 25 Years in the USSR
    http://www.com­puter-museum.ru/english/al­gol68.htm
  30. Charles Simonyi
    http://en.wiki­pedia.org/wiki/Char­les_Simonyi
  31. Charles Simonyi
    http://cs.wiki­pedia.org/wiki/Char­les_Simonyi
  32. Charles Simonyi returns to space
    http://www.char­lesinspace.com/
  33. Charles Simonyi
    http://www.sha­mit.org/charles_si­monyi.htm
  34. Minsk Family of Computers
    http://www.com­puter-museum.ru/english/min­sk0.htm
  35. Minsk family of computers
    http://en.wiki­pedia.org/wiki/Min­sk_family_of_com­puters
Našli jste v článku chybu?
Podnikatel.cz: I vám můžou vykrást značku. Braňte se

I vám můžou vykrást značku. Braňte se

Lupa.cz: Jak udělat formulář, aby ho vyplnil i negramotný?

Jak udělat formulář, aby ho vyplnil i negramotný?

Podnikatel.cz: Babišovi se nedá věřit, stěžovali si hospodští

Babišovi se nedá věřit, stěžovali si hospodští

Vitalia.cz: Voda z Vltavy před a po úpravě na pitnou

Voda z Vltavy před a po úpravě na pitnou

Podnikatel.cz: ČSSZ posílá přehled o důchodovém kontě

ČSSZ posílá přehled o důchodovém kontě

DigiZone.cz: Wimbledon na Nova Sport až do 2019

Wimbledon na Nova Sport až do 2019

Vitalia.cz: Antibakteriální mýdla nepomáhají, spíš škodí

Antibakteriální mýdla nepomáhají, spíš škodí

DigiZone.cz: Parlamentní listy: kde končí PR...

Parlamentní listy: kde končí PR...

Vitalia.cz: Nová vakcína proti chřipce se aplikuje nosem

Nová vakcína proti chřipce se aplikuje nosem

Vitalia.cz: Běháte a nehubnete? 6 častých chyb

Běháte a nehubnete? 6 častých chyb

Měšec.cz: „Ukradli“ jsme peníze z bezkontaktních karet

„Ukradli“ jsme peníze z bezkontaktních karet

Vitalia.cz: Tohle všechno se dá usušit

Tohle všechno se dá usušit

Root.cz: Hořící telefon Samsung Note 7 zapálil auto

Hořící telefon Samsung Note 7 zapálil auto

Lupa.cz: Blíží se konec Wi-Fi sítí bez hesla?

Blíží se konec Wi-Fi sítí bez hesla?

DigiZone.cz: DVB-T2 ověřeno: seznam TV zveřejněn

DVB-T2 ověřeno: seznam TV zveřejněn

DigiZone.cz: Nova opět stahuje „milionáře“

Nova opět stahuje „milionáře“

DigiZone.cz: Sat novinky: NASA Ultra HD (4K)

Sat novinky: NASA Ultra HD (4K)

Vitalia.cz: Tahák, jak vyzrát nad zápachem z úst

Tahák, jak vyzrát nad zápachem z úst

120na80.cz: Co je padesátkrát sladší než cukr?

Co je padesátkrát sladší než cukr?

Vitalia.cz: Tradiční čínská medicína a rakovina

Tradiční čínská medicína a rakovina