Extra övningar på SDD:er/SDT:er Bakvända meningar Grammatik: sentence word sentence sentence ε sentence space sentence word char word char 1 char 2 word char 1 word 1 char 2 Symbolen sentence producerar serier av ett eller flera ord. Token char står för ett tecken ur { a, b,, ö }, och har attributet lexeme. Token space betyder ett mellanslag. Sätt ett attribut rev av strängtyp på sentence som håller den producerade meningen baklänges. Ge också regler för hur detta attribut får ett värde. Till din hjälp kan du använda strängsammanfogningsoperatorn. Gör också om din SDD till en SDT. Syskonnoder i träd Följande grammatik producerar strängrepresentationer av träd vars interna noder kan ha godtyckligt antal barn. tree branch branch internal ( children ) children branch children children leaf children children ε children children Med det här sättet att representera träd skrivs t.ex. ett träd bestående av en rotnod med tre lövnoder som barn ut såhär: internal (leaf leaf leaf), eller ett träd bestående av en rot med ett lövbarn och ett barn som ser ut som roten i det förra trädet: internal (internal (leaf leaf leaf) leaf) eller internal (leaf internal (leaf leaf leaf)). Sätt ett attribut sibs på grammatiksymbolerna internal och leaf som är av heltalstyp och anger hur många syskon noden har. Specificera också regler för hur detta attribut får sitt värde. Omvandla sedan din SDD till en SDT.
Palindrom Använd samma grammatik som i Bakvända meningar ovan, men lägg till ett booleskt attribut på sentence som anger om den producerade meningen blir samma sak baklänges eller inte. Gör en SDD och en SDT. Negativa och positiva deluttryck Grammatik: expr term expr expr 1 + expr 2 term factor term term 1 * term 2 factor num factor id factor factor 1 factor ( expr ) Token num står för numeriska konstanter och har ett attribut val som är ett positivt heltalsvärde. Token id står för identifierare, och identifierares värden går ju inte att veta förrän under körning. Inför attributet sign i expr som kan hålla värdena neg, 0, pos eller?, vilka anger om resultatet av det evaluerade uttrycket är negativt, lika med 0, positivt respektive omöjligt att avgöra i en statisk analys. Det sistnämnda attributvärdet kan behövas för uttryck som innehåller identifierare. Det enda man kan veta om dessa är ju t.ex. att x x är positivt eller att x 0 = 0, och som en utökning av uppgiften kan du lägga till regler som hanterar något eller några av dessa specialfall och på så sätt förbättrar analysens precision. Detta kan kräva att ytterligare attribut införs. Gör också en SDT.
Lösning Bakvända meningar SDD: PRODUKTION SEMANTISKA REGLER sentence word sentence sentence.rev = sentence.rev word.rev sentence ε sentence.rev = sentence space sentence sentence.rev = sentence.rev word char word.rev = char.lexeme word char 1 char 2 word.rev = char 2.lexeme char 1.lexeme word char 1 word 1 char 2 word.rev = char 2.lexeme word 1.rev char 1.lexeme Eftersom SDD:n ovan enbart använder syntetiserade attribut (S-attributed), kan en SDT för att evaluera attributen enkelt konstrueras genom att införa semantiska aktioner sist i alla produktioner. Lösning Syskonnoder i träd Vi använder attributet inh i children och children för att utföra en inkrementell summering av antalet barn i en syskonskara. Då basfallet i produktionen av syskon, som utgörs av regeln children ε, används, innehåller inh den färdiga summeringen av antalet barn, och detta attribut kan då kopieras tillbaka via det syntetiserade attributet count så att varje barn kan använda det för att sätta sibsattributet. SDD: PRODUKTION SEMANTISKA REGLER tree branch branch.sibs = 0 branch internal ( children ) internal.sibs = branch.sibs children.inh = 0 children branch children children.inh = children.inh + 1 branch.sibs = children.count 1 children.count = children.count children leaf children children.inh = children.inh + 1 leaf.sibs = children.count 1 children.count = children.count children ε children.count = children.inh children children children.inh = children.inh children.count = children.count SDT som evaluerar attributen ovan: tree { branch.sibs = 0 } branch branch internal ({ children.inh = 0 } children ){ internal.sibs = branch.sibs } children branch { children.inh = children.inh + 1 } children { branch.sibs = children.count 1; children.count = children.count }
children leaf { children.inh = children.inh + 1 } children { leaf.sibs = children.count 1; children.count = children.count } children ε { children.count = children.inh } children { children.inh = children.inh } children { children.count = children.count } Lösning Palindrom Till detta använder vi samma attribut rev som tidigare, men utökar också grammatiken med ett strängattribut orig som håller strängen i rättvänd ordning, som rev kan jämföras med. PRODUKTION SEMANTISKA REGLER sentence word sentence sentence.rev = sentence.rev word.rev sentence.orig = word.orig sentence.orig sentence.palin = if sentence.rev == sentence.orig then true else false sentence ε sentence.rev = sentence.orig = sentence space sentence sentence.rev = sentence.rev sentence.orig = sentence.orig word char word.rev = char.lexeme word.orig = char.lexeme word char 1 char 2 word.rev = char 2.lexeme char 1.lexeme word.orig = char 1.lexeme char 2.lexeme word char 1 word 1 char 2 word.rev = char 2.lexeme word 1.rev char 1.lexeme word.orig = char 1.lexeme word 1.orig char 2.lexeme Lösning Negativa och positiva deluttryck För att spara information om huruvida båda operanderna till en multiplikation är enstaka variabler med samma namn använder vi strängattributet var som håller variablernas namn. I de fall ett deluttryck inte är en enstaka variabel sätts var till. PRODUKTION expr term expr expr 1 + expr 2 term factor SEMANTISKA REGLER expr.sign = term.sign expr.var = term.var expr.sign = if expr 1.sign == expr 2.sign then expr 1.sign else if expr 1.sign == 0 then expr 2.sign else if expr 2.sign == 0 then expr 1.sign else? expr.var = term.sign = factor.sign term.var = factor.var term term 1 * term 2 term.sign = if term 1.var!= and term 1.var == term 2.var then pos else if term 1.sign == 0 or term 2.sign == 0 then 0 else if term 1.sign ==? or term 2.sign ==? then? else if term 1.sign == term 2.sign then pos else neg term.var =
factor num factor.sign = pos factor.var = factor id factor.sign =? factor.var = id.lexeme factor factor 1 factor.sign = if factor 1.sign == neg then pos else if factor 1.sign == 0 then 0 else if factor 1.sign == pos then neg else? factor.var = factor ( expr ) factor.sign = expr.sign factor.var = expr.var Eftersom SDD:n ovan är S-attributed, kan en SDT enkelt konstrueras genom att evaluera attributen i semantiska aktioner som ligger sist i produktionerna.