Compiler Labs

Embed Size (px)

Citation preview

  • 8/3/2019 Compiler Labs

    1/9

  • 8/3/2019 Compiler Labs

    2/9

    1. The web page will be submitted toflex, a version oflex creating a Scanner thatwill recognize the tokens described there. It is essentially a C program.

    2. Then the C compiler (cc), compiles this to create an executable scanner.3. This scanner runs the input program on the right producing a set of tokens.

    You can see this list of tokens at the bottom of the output page. You might have toscroll down in your browser to see them.

    Step 1 Click on the button and investigate the output.

    Edit the text and click me

    Lex Program Scanner Input

    %{

    #include

    %}%%

    [a-zA-Z][a-zA-Z0-9]* printf("WORD %s ",

    [a-zA-Z0-9\/.- ]+ printf("FILENAME %s ",

    \" printf("QUOTE ");

    \{ printf("OBRACE ");

    \} printf("EBRACE ");

    ; printf("SEMICOLON ");

    \n printf("\n");

    [ \t]+ /* ignore w hitespace */;

    %%

    int main (void) {yylex(); return 0;}

    int yyw rap (void) {return 1;}

    logging {

    category lame-servers { null; };

    category cname { null; };};

    zone "." {

    data = 100;

    real = +145.8764;

    type hint;

    file "/etc/bind/db.root";

    };

    QUESTION 1 Looking at the lex code and the output, what tokens seem to bedescribed there?

    Step 2 Change the input to the following and click on the button again:

    void input_a() {a = b3;xyz = a + b + c - p / q;a = xyz * ( p + q );p = a - xyz - p;}

    QUESTION 2 What tokens didn't get recognized?

    Step 3

    a. Change the lex file so that when it comes across an equal, it prints EQUAL.

  • 8/3/2019 Compiler Labs

    3/9

    b. Now change the lex file so that it recognizes all the tokens in the program inStep 2

    Step 4 Change the lex file so that it will also recognize an integerconsisting of 1 ormore digits

    Step 5 Using lex in Unix

    a. Create a file, lex.a containing your lex code from Step 4. (You can change itto print nicer output if you wish - in fact, I recommend this; Try printing the

    tokens as ordered pairs, e.g., (identifier, void))b. Generate the C Program which is the Scanner as follows:

    $ lex lex.a

    Now let's see what files are there:

    $ lslex.a lex.yy.cYou can see that lex has created a C program called lex.yy.c. This is ourScanner, but we have to compile it first:

    c. Compile the C Program which is the Scanner:$ cc lex.yy.c -ll$ lsa.out lex.a lex.yy.c

    a.out is the executable scanner. Let's try it out!

    d. Running the Scanner:$ ./a.out23integer

    Step 6 Now change your lex file so that it displays REALNUM for a real number.A real number can be defined as a plus or minus followed by a number of digitsfollowed by a dot ".", followed by a number of digits.

    You are now ready to do Project, Part 1!

    Compiler Parsing Lab

    In this lab you will use yacc (or its newer version) Bison as well as lex (flex) to createa parser for a small subset ofJavalet

  • 8/3/2019 Compiler Labs

    4/9

    The yacc (bison) program is in the left box, the related lex (flex) code is in the bottombox and the input program for the generated parser is in the right box.

    When you press the buttonEdit the text and click me, the following will happen:

    1. The yacc/bison code in the left box will be run by bison (yacc)2. The lex/flex code will be run by flex (lex)3. The C code created by flex will be compiled by cc, the C compiler4. The C code created by bison will be compiled by cc, the C compiler, creating

    an executable parser5. The input in the right box is executed by this parser producing a bottom-up

    parse(The parser prints the left hand side of productions just like you will inProject, Part 2)

    The results will be displayed on the bottom of the page.

    You might have to scroll down in your browser to see them.

    Step 1 Looking at the bison/yacc code in the left box, write the BNF in standard form.Hint: The first production is

    lines --> epsilon | lines line

    Step 2 It is really hard to see the bottom-up parse from the output, so change the inputto contain just the first statement 1 + 1; and press the button again. Now you shouldbe able to create a parse from the output (which is the reverse of a leftmostderivation). Show it as a parse tree.

    Step 3 Now, change the yacc/bison grammar in the left box so that it recognizes

    division. Note that the lex code already recognizes "/", calling the token DIVIDE. (Askus if you don't see this)Run an input to show that the division works (if it does! If not, fix your production)and show us your output. Draw the parse tree from the output.

    Step 4 In your written BNF, add productions to perform exponentiation, "^". Show itto us before you go on. Now add the bison code for ^ to the left box, enter a statementusing ^ in the right box and click on the button. Note that the lex code for "^" is

    already there with the token called POWER. Show us when it works.

    Step 5 Moving to unix/linux:

    Create the lex file, say, lex.2 Run lex.2 through lex (Type lex lex.2) to create lex.yy.c Now create the yacc file, say ly.y and run ly.y through yacc (Type yacc -d

    ly.y) This creates a file called yacc.tab.c and the "-d" creates a file ofdefinitions called y.tab.h. When these are compiled they produce our parser.Stop and look at these files and show them to us.

    Now compile these 2 C programs:

  • 8/3/2019 Compiler Labs

    5/9

    cc y.tab.c lex.yy.cwhich, as usual, creates the file a.out. This is the Parser!

    For now, we will run the Parser from the Command line.

    Type:

    ../a.out2 + 3 * 4

    Show us your output.

    Run a few more programs. Now you are ready to do Project, Part 2.

    Edit the text and click me

    Yacc/Bison Parsing Program Yacc/Bison Parsing Input

    %{

    #include

    %}

    %start lines

    %token NUMBER

    %token PLUS MINUS TIMES DIVI

    %token LEFT_PARENTHESISRIGHT_PARE

    %token END

    %left PLUS MINUS%left TIMES DIVIDE

    %right POWER

    %%

    lines: /* empty */

    | lines line /* do nothing */

    line: exp END { printf("found exp END\

    1+1;

    1+2*3;

    2*3(+5*6);

    2(*3+5*)6;

    Lex Scanner Program

  • 8/3/2019 Compiler Labs

    6/9

  • 8/3/2019 Compiler Labs

    7/9

    Theprinttree function prints this as: (+ 1 1)

    Step 2 Change the yacc/bison grammar so that it recognizes division and add thatnode to the AST tree.

    Run an expression as input to show that the division works.

    Step 3 Add the pow() function (^) to compute the power of two numbers; includeboth the syntax (the yacc productions) and semantics (the $$ = stuff)Again, run an example to show power works.

    Step 4 Now read (yes, read it first!) and begin Project Part 3. Have fun!

    Edit the text and click me

    Yacc/Bison Parsing Program Yacc/Bison Parsing Input

    %{

    #include

    typedef struct node

    {

    struct node *left;

    struct node *right;

    char *token;

    } node;

    node *mknode(node *left, node *right, char

    void printtree(node *tree);

    #define YYSTYPE struct node *

    %}

    %start lines

    %token NUMBER

    %token PLUS MINUS TIMES DIVI

    1+1;

    1+2*3;

    2*3+(5*6);

    2*(3+5)*6;

    Lex Scanner Program

  • 8/3/2019 Compiler Labs

    8/9

    %{

    #include "parsing_lab.h"

    %}

    %%

    [0-9]+ {yylval = (int)yytext; return

    /* cast pointer to int for compil

    [ \t\n] ;

    "+" return(PLUS);

    "-" return(MINUS);

    "*" return(TIMES);

    "/" return(DIVIDE);

    "^" return(POWER);

    "(" return(LEFT_PARENTHESIS);

    ")" return(RIGHT_PARENTHESIS);

    ";" return(END);

    %%

    Edit the text above, and click on the button to see the result.

    Compiler Lab #4 - Code generation

    This lab will prepare you to do Project, Part 4 which uses the abstract syntax treecreated in Project, part 3 to generate code.

    As in the other labs, the yacc (bison) program is in the left box and input to thatprogram is in the right box. The lex code is below.

    When you press the buttonEdit the text and click me, the following will happen.

    1. Like the other labs, the yacc code will be submitted to bison (yacc), flex (lex),the cc compiler, and the resultant program will be run on the input.

    2. The results will be displayed on the bottom of the page.You might have to scroll down in your browser to see them.

    Step 0 Run the input and look at the output. Note that pseudocode for a stack machineis produced.

    Step 1 Change the yacc/bison grammar so that it recognizes division and will dividean expression and add that node to the AST tree.Add an expression to the input and show that the division works.(You should have this from the last lab.) Make the divide operation print the correctpseudo-assembler in the generate function.

    Step 2 Now add code to generate pseudo assembly for the pow() funtion (^) to get the

    power of two numbers, adding the pow node to the ast tree (as done in the last lab).

  • 8/3/2019 Compiler Labs

    9/9

    Run an expression as input to show that power works. Add the pseudo code to run the power function. For simplicity you can assume the machine has an opcode that does power, or

    you can loop the multiplication.

    Step 3 On to Project, part 4! Now you are a compiler designer!

    Edit the text and click me

    Yacc/Bison Parsing Program Yacc/Bison Parsing Input

    %{

    #include

    typedef struct node

    {

    struct node *left;

    struct node *right;int tokcode;

    char *token;

    } node;

    node *mknode(node *left, node *right, int to

    void printtree(node *tree);

    void generate(node *tree);

    #define YYSTYPE struct node *

    %}

    %start lines

    1+1;

    1+2*3;

    2*3+(5*6);

    2*(3+5)*6;

    Lex Scanner Program

    %{

    #include "parsing_lab.h"

    %}

    %%

    [0-9]+ {yylval = (int)yytext; return

    /* cast pointer to int for compil

    [ \t\n] ;

    "+" return(PLUS);

    "-" return(MINUS);"*" return(TIMES);

    "/" return(DIVIDE);

    "^" return(POWER);

    "(" return(LEFT_PARENTHESIS);

    ")" return(RIGHT_PARENTHESIS);

    ";" return(END);

    %%

    Edit the text above, and click on the button to see the result.