bild
Skolan för
elektroteknik
och datavetenskap

Laboration 6 - Formelkoll

Detta program ska läsa in molekylformler och kolla att dom är syntaktiskt korrekta. I terminalfönstret ställs frågorna, t ex
   Molekyl: Si(C3(COOH)2)4(H2O)7
   Formeln är syntaktiskt korrekt
   Molekyl: Ag7(FyOj6)17
   Okänt atomnamn Fy vid radslutet Oj6)17
   Molekyl: H1SO4
   För litet tal vid radslutet SO4
   Molekyl: Ca(OH)NO3
   Saknad siffra vid radslutet NO3
   Molekyl: Na(OH
   Saknad högerparentes vid radslutet
   Molekyl: Nacl
   Saknad stor bokstav vid radslutet cl
När användaren trycker retur utan att ha skrivit någon formel ska slingan brytas och programmet avslutas.

Syntaxanalys

Syntaxen för molekylformler kan beskrivas så här i BNF-notation:
<formel>::= <mol> \n
<mol>   ::= <group> | <group><mol>
<group> ::= <atom> |<atom><num> | (<mol>) <num>
<atom>  ::= <LETTER> | <LETTER><letter>
<LETTER>::= A | B | C | ... | Z
<letter>::= a | b | c | ... | z
<num>   ::= 2 | 3 | 4 | ...
Ditt program ska läsa formeln tecken för tecken och med rekursiv medåkning kolla syntaxen. Eftersom det är lättast att läsa hela raden får du göra det och sedan lägga in alla tecken i en kö. Avsluta med returtecknet, så här.
   rad=raw_input("Molekyl:")
   for tkn in rad: q.put(tkn)
   q.put("\n")
Rekursiv medåkning innebär att huvudprogrammet gör anropet readformel(), att readformel() anropar readmol() som anropar readgroup() och sedan eventuellt sej själv, att readgroup() antingen anropar readatom() eller läser en parentes och anropar readmol() etc - allt enligt grammatiken. När ett syntaxbrott upptäcks genereras ett särfall (raise Exception,msg) som fångas i huvudprogrammet och där skrivs hela resten av kön ut.

Man måste ofta tjuvtitta på nästa tecken för att veta vilken gren man ska följa i syntaxträdet och därför bör du i klassen Queue lägga till metoden peek() som returnerar första värdet men låter kön vara oförändrad.










Frivillig extrauppgift

Molekylvikten kan din formelkoll samtidigt räkna ut om du låter alla metoder returnera ett tal, nämligen så här

  • readatom returnerar en atomvikt med hjälp av hashtabellen
  • readnum returnerar ett heltal
  • readgroup returnerar vikten av en molekylgrupp, t ex Na eller (OH)2
  • readmol returnerar vikten av en delmolekyl
  • readformel returnerar hela molekylvikten
Nu ska körningen se ut så här.
Molekyl:Si(C3(COOH)2)4(H2O)7
Formeln är syntaktiskt korrekt
Molekylvikt: 658.466



En jätteprestation av................................. enligt............................ den ...............


Sidansvarig: Magnus Rosell <rosell@csc.kth.se>
Uppdaterad 2006-09-29