1

I started doing exercise 2.4.5 in Dragon book second edition and found some answers in internet but they seems wrong for me First of all this is the exercise: Construct a syntax-directed translation scheme that translates postfix arithmetic expressions into equivalent prefix arithmetic expressions.

Answer from internet:

https://github.com/fool2fish/dragon-book-exercise-answers/blob/master/ch02/2.3/2.3.md

Production: expr -> expr expr op | digit

Translation scheme: expr -> {print(op)} expr expr op | digit {print(digit)}

I tried this scheme for two expressions 952*- and 95-2*. 952*- is transformed correctly to prefix expression (952*- => -9*52), but 95-2* not! (95-2* => -95*2, should be 95-2* => *-952)

I constructed my own scheme which seems that works correctly for both cases:

My translation scheme

I used Backus-Naur Form (BNF) in order to implement syntax directed translation with parameters

Exercise 2.3.5
(postfix 1 and 2 is used just to differ production instances)

root -> expr

expr -> expr1 term + expr2 | 
    expr1 term - expr2 | 
    term

term -> term fact * term |
    term fact / term |
    term

fact -> digit | 
    expr | 
    e

digit -> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

Translation scheme:

root -> expr { root.value = expr.prefix; print(root.value) }

expr -> expr1 term + expr2 { 
    expr.prefix = expr2.op || '+' || expr1.prefix || term.prefix || expr2.digits, 
    expr.op = '+',
    expr.digits = expr1.digits || term.digits || expr2.prefix   
}
expr -> expr1 term - expr2 { 
    expr.prefix = expr2.op || '-' || expr1.prefix || term.prefix || expr2.digits, 
    expr.op = '-',
    expr.digits = expr1.digits || term.digits || expr2.prefix   
}
expr -> term {
    expr.prefix = term.prefix,
    expr.op = term.op,
    expr.digits = term.digits 
}

term -> term1 fact * term2 {
    term.prefix = term2.op || '*' || term1.prefix || fact.prefix || term2.digits, 
    term.op = '*',
    term.digits = term1.digits || fact.digits || term2.prefix   
}
term -> term1 fact / term2 {
    term.prefix = term2.op || '/' || term1.prefix || fact.prefix || term2.digits, 
    term.op = '/',
    term.digits = term1.digits || fact.digits || term2.prefix   
}
term -> fact {
    term.prefix = fact.prefix,
    term.op = fact.op,
    term.digits = fact.digits 
}

fact -> digit {
    fact.prefix = e,
    fact.op = e,
    fact.digit = digit.value
}
fact -> expr {
    fact.prefix = expr.prefix,
    fact.op = expr.op,
    fact.digit = expr.digit
}
fact -> e {
    fact.prefix = e,
    fact.op = e,
    fact.digit = e
}

digit -> 0 { digit.value = 0 }
digit -> 1 { digit.value = 1 }
digit -> 2 { digit.value = 2 }
digit -> 3 { digit.value = 3 }
digit -> 4 { digit.value = 4 }
digit -> 5 { digit.value = 5 }
digit -> 6 { digit.value = 6 }
digit -> 7 { digit.value = 7 }
digit -> 8 { digit.value = 8 }
digit -> 9 { digit.value = 9 }

Experts! Please let me know is my translation scheme correct? And this internet answer is indeed wrong? Or I just missing something?

Thank you in advance!

I tried to evaluate translation scheme which I found in internet for values 952*-, 95-2* and it seems to be incorrect. In contrast my scheme works good, but I am not sure about other edge cases which my translation scheme may hide.

0 Answers0