*Semantic actions are under-lined
1) Assignment Statement
A1) A -> id = E { gen_instr (POPM, get_address(id)) }
A2) E -> T E’
A3) E’ -> + T { gen_intsr (ADD, nil) } E’
A4) E’ -> ε
A5) T -> F T’
A6) T’ -> *F { gen_instr (MUL, nil) } T’
A7) T’ -> ε
A8) F -> id { gen_instr (PUSHM, get_address(id) )
Procedure A ()
{
If token = id then
{
save = token;
lexer();
If token = “=” then
{
lexer();
E();
get_instr (POPM, get_address (save) );
}
else error_message ( “= expected” );
}
else error_massage ( “ id expected” );
}
Procedure E ():
{
T ();
E’();
}
2
Procedure E’();
{
If token = “+” the
n
{
lexer();
T();
gen_instr (ADD, nil);
E’();
}
}
;
Procedure T(); {
F();
T’(); }
Proc
edure T’()
{
If token = “*” then
{
lexer();
F();
gen_instr(MUL, nil);
T’();
}
}
Procedure F(); {
If token = id then
{
gen_instr(PUSHM, get_address (token));
lexer();
}
else error_message(“id expected”); };
3
Procedure gen_instr(op, oprnd)
/* instr_address shows the current insturction address is global / { Instr_table [instr_address].address = inst_address; Instr_table [instr_address].op = op; Instr_table [instr_address].oprnd = oprnd; Instr_address++; }; Example: x = a + bc
(addresses a = 5001 , b=5002, c=5003 and x = 5004)
INSTR_TABLE
address Op Oprnd
1 PUSHM 5001
2 PUSHM 5002
3 PUSHM 5003
4 MUL nil
5 ADD nil
6 POPM 5004
Print from INSTR_TABLE ignoring “nil”
4
- While Statement
W1) W -> while ( C ) S
W2) C - > E R E
W3) R -> == | > | <
Procedure while_statement();
{
If token = “while” then
{
addr = instr_address;
gen_instr(“LABEL”, nil);
lexer();
If token = “(“ then
{
lexer();
C ( );
If token = “)” then
{
lexer();
S();
gen_instr(JUMP, addr);
back_patch (instr_address);
lexer();
};
else error_message (“ ) expected”);
else error_message (“( expected”);
}
else error_message (“while expected”);
};
5
Procedure C ()
{
E();
If token in R then
{
op = token;
lexer();
E();
case op of
< : gen_instr (LES, nil);
push_jumpstack (instr_address); /* another stack need */
gen_instr (JUMPZ, nil);
:
== :
}
else error_message (“ R token expected”);
}
Procedure back_patch (jump_addr)
{
addr = pop_jumpstack();
Instr_table[addr].oprn = jump_addr;
}
6
Example: while ( i < max) i = i + 1;
with addresses I =5000, max = 5001
- LABEL nil
- PUSHM 5000
- PUSHM 5001
- LES nil
- JUMPZ 11 /* back patch */
- PUSHM 5000
- PUSHM 5001
- ADD nil
- POPM 5000
- JUMP 1
- …..
7 - if statement
I -> if ( C ) S fi
Procedure I ();
{
If token =”if” then
{
addr = instr_address();
lexer();
If token =”(“ then
{
lexer();
C( );
If token = “)” then
{
lexer();
S( );
back_patch(instr_address);
If token = “fi”
lexer();
else error_messgage (“fi expected “);
}
else error_message (“) expected “);
};
else error_message (“( expected”);
}
else error_message (“if expected”);
};
8
Example: if (a < b) a = c; fi
With addresses a = 5000, b = 5001, c = 5002 - PUSHM 5000
- PUSHM 5001
- LES nil
- JUMPZ 7
- PUSHM 5002
- POPM 5000
- LABEL
NOTE:
- You need work on , and statement
- DO NOT create your own instructions