SE250:lab-9:dcho040
It's done!!!
- Including this lab, I think that making a programme needs about 90% thinking and 10% computer work.
- My plan was doing all 3 options but only this option was completed so far.
- This lab requires quite a lot of time but it was worth.
Understanding mkNode funciton
<html> <img src='http://daniel.hosting.paran.com/250_9_1.jpg'> </html>
Understanding Exp and p funcitons
<html> <img src='http://daniel.hosting.paran.com/250_9_3.jpg'> </html>
Understanding Parse structure
<html> <img src='http://daniel.hosting.paran.com/250_9_2.jpg'> </html>
code
add two more tokens
- tokenise.c
Token TOK_BT = '>'; Token TOK_LT = '<';
- tokenise.h
extern Token TOK_BT; extern Token TOK_LT;
- parse.c
BinOp* lookupBinOp( Token tok ) { static BinOp ops[] = { { &TOK_EQ, 2, RIGHT_ASSOC }, //added { &TOK_BT, 2, RIGHT_ASSOC }, { &TOK_LT, 2, RIGHT_ASSOC }, { &TOK_ADD, 3, LEFT_ASSOC }, { &TOK_SUB, 3, LEFT_ASSOC }, { &TOK_MUL, 4, LEFT_ASSOC }, { &TOK_DIV, 4, LEFT_ASSOC }, { 0 } };
add lookupStmtOp function to define the rules for Stmt
typedef struct { Token* tok1; Token* tok2; Token* tok3; } StmtOp; StmtOp* lookupStmtOp( Token tok ) { static StmtOp ops[] = { { &TOK_IF, &TOK_THEN, &TOK_ELSE }, { &TOK_WHILE, &TOK_DO, 0 }, { 0 } }; StmtOp* p; for( p = ops; p->tok1 != 0; p++ ) if( eqToken( tok, *p->tok1 ) ) return p; return 0; }
create Stmt, StmtSeq functions
Tree* Stmt( TokenStream* tokens ) { Token n = current( tokens ); StmtOp* op = lookupStmtOp( n ); advance( tokens ); if (op != 0) { Tree* parser1 = Exp( tokens, 0 ); expect(tokens, *op->tok2); Tree* parser2 = Stmt( tokens ); if(( op->tok3 == 0) || (!eqToken(*op->tok3, current(tokens)))) return mkNode2( n, parser1, parser2 ); else{ advance( tokens ); Tree* parser3 = Exp( tokens, 0 ); return mkNode3( n, parser1, parser2, parser3 ); } } else if (eqToken( n, TOK_OPENBRACE)) { Tree* t = StmtSeq( tokens ); expect( tokens , TOK_CLOSEBRACE ); return t; } else if ((isVariable(n)) && (eqToken(current(tokens), TOK_ASSIGN))) { Token m = current( tokens ); advance( tokens ); Tree* t = mkNode0(n); return mkNode2( m, t, Exp( tokens, 0 )); } else if ( eqToken( n, TOK_SKIP ) ) { return mkNode0( n ); } else error("no rules are applied in S parse"); return 0; } Tree* StmtSeq( TokenStream* tokens ) { Tree* t = Stmt( tokens ); if (eqToken(current(tokens), TOK_SEMICOLON)) { Token n = current( tokens ); advance( tokens); t = mkNode2(n, t, StmtSeq(tokens)); } return t; }
result
result from Linux(ubuntu)
gcc tokenise.c parser.c -o parser&& ./parser Parse("a=1"): =(a 1) a 1 =2 Parse("a=1;b=2;k;k;k"): ;(=(a 1) ;(=(b 2) ;(k ;(k k)))) a 1 =2 b 2 =2 k k k ;2 ;2 ;2 ;2 Parse("ia>btwtda=a*2ek"): i(>(a b) w(t =(a *(a 2))) k) a b >2 t a a 2 *2 =2 w2 k i3 Parse("ict{x=1;wtda=a*2}ek"): i(c ;(=(x 1) w(t =(a *(a 2)))) k) c x 1 =2 t a a 2 *2 =2 w2 ;2 k i3 Parse("junk that won't parse"): no rules are applied in S parse Incomplete parse <###> <###> Compilation finished at Mon Jun 2 20:25:18
results by diagram
<html> <img src='http://daniel.hosting.paran.com/250_9_4.jpg'> </html>
Discussion
- I think that, to learning or creating a programme, programmers should have some special ways to explain the codes
- Because the codes we are going to deal with are not be able to fully understand by just reading
- Understanding the theory, creating the codes based on theory... Programming is getting harder but more exciting.