Syntax-directed translations in YACC -------------------------------------------------------------------- Exercise 1. Use the translation scheme in YACC to check whether the input file contains the sentence of the form: an bn cn ('a' raised to the power of n, 'b' raised to the power of n and 'c' raised to the power of n), where (n>=0). The scanner is as follows: %{ # include #include "ytab.h" %} %% "a" { return('a'); } "b" { return('b'); } "c" { return('c'); } \ |\n ; . {yyterminate();} The parser is partially given: %start S %% S : A B C ; A : A 'a' | ; B : B 'b' | ; C : C 'c' | ; %% #include yyerror(s) char s[15]; { printf("\n%s!\n", s); } Your task is to augument the given above parser. ----------------------------------------------------------------------------- Exercise 2. Use the YACC generator to create a translation scheme that given the sequence of decimal digits separated by spaces produces the sequence containig the same digits but separated by commas and embedded in parentheses. The sequence: 1 2 3 4 is copied to the output as: (1,2,3,4). The scanner is given below. %{ # include #include "ytab.h" %} %% [0-9] { yylval=atoi(yytext);return d; } \ |\n ; . {yyterminate();} Exercise 3. Let us consider a simple Pascal-like language to declare variables of types "integer" and "real". The program starts with the 'program' keyword followed by name (a sequence of letters and digits starting with a letter) and the colon ':'. Program body starts with 'var' followed by nonempty sequence of declarations. Each declaration consists of nonempty sequence of variable names followed by ':' and a word 'integer' or 'real'. Declarations are separated by ';'. The last declaration ends with '.' The example correct program looks like: program test; var a,Beta,c21:integer; c,wart:real. The given below program contains 2 bugs - a lexical one and a syntactical one: program xxx; var# a,beta,, c21:integer; c,wart:real. Use the YACC generator to obtain a translator to calculate for each variable its offset in the memory following the given below rules: - the first variable offset is "0", - a variable of type "integer" needs 2 bytes, - a variable of type "real" needs 4 bytes, - variables are expanded in the memory successively as they are declared in the program. The lexical analyser is given below. It assigns numeric identifiers to variables starting from "1". %{ #include "ytab.h" int nr; %} %% "program" {return( program);} "var" {return( var);} "integer" {return( integer);} "real" {return( real);} [a-zA-Z][0-9a-zA-Z]* { yylval=nr; nr++; return(nazwa); } ";" { return(';'); } ":" { return(':'); } \. { return('.'); } "," { return(','); } \ |\n ; . {yyterminate();} The scanner ignores spaces, newlines and tabs and gives 5 lexical items to be declared in '%token' specification in YACC. The example correct program may look like: program test; var a,Beta,c21,xyz:integer; c,wart:real; p,r:integer. The generated translator gives us the following result: NUMER ZMIENNEJ ADRES WZGLEDNY 1 0 2 2 3 4 4 6 5 8 6 12 7 16 8 18