SE250:lab-9:dols008

From Marks Wiki
Jump to navigation Jump to search

So apparently, as provided, the parser recognises a grammar. Actually it just crashes if you try to run it, because the unimplemented functions don't return anything. So I have to try to figure out how it's meant to work before it will do anything. Fun.

Right, I got some actual output using the code:

Tree* Stmt( TokenStream* tokens ) {
  if (isVariable(current(tokens))) {
	  Tree* var = mkNode0(current(tokens));
	  advance(tokens);
	  expect( tokens, TOK_ASSIGN );
	  return mkNode2(TOK_ASSIGN, var, Exp(tokens, 0));
  }
  error( "Bad statement" );
  return NULL;
}

Tree* StmtSeq( TokenStream* tokens ) {
  return Stmt(tokens);
}

It only parses 1 statement, but at least it seems to work. I had to move the Tree* t declaration because someone was using a non-standard compiler when they wrote this *glare*.

So I got multiple statements working. I don't know what k;k;k was supposed to mean... It doesn't seem to be in the grammar.

So it looks like k is meant to be skip. Fixed that. I'm working on if statements and multiple statement groups, but the example input seems to be wrong. a>b is not a valid expression, there is no such binary operator as >.

Here's my probably working code. I hope:

Tree* Stmt( TokenStream* tokens ) {
  Tree* A;
  Tree* B;
  if (eqToken(current(tokens), TOK_SKIP))
  {
	  advance(tokens);
	  return mkNode0(TOK_SKIP);
  }
  if (eqToken(current(tokens), TOK_OPENBRACE)) {
	  advance(tokens);
	  A = StmtSeq(tokens);
	  expect(tokens, TOK_CLOSEBRACE);
	  return A;
  }
  if (eqToken(current(tokens), TOK_IF)) {
	advance(tokens);
    A = Exp(tokens, 0);
	expect(tokens, TOK_THEN);
	B = Stmt(tokens);
	if (eqToken(current(tokens), TOK_ELSE)) {
		advance(tokens);
		return mkNode3(TOK_IF, A, B, Stmt(tokens));
	}
	return mkNode2(TOK_IF, A, B);
  }
  if (eqToken(current(tokens), TOK_WHILE)) {
	advance(tokens);
    A = Exp(tokens, 0);
	expect(tokens, TOK_DO);
	return mkNode2(TOK_WHILE, A, Stmt(tokens));
  }
  if (eqToken(current(tokens), TOK_PRINT)) {
	  advance(tokens);
	  return mkNode1(TOK_PRINT, Exp(tokens, 0));
  }
  if (isVariable(current(tokens))) {
	  A = mkNode0(current(tokens));
	  advance(tokens);
	  expect( tokens, TOK_ASSIGN );
	  return mkNode2(TOK_ASSIGN, A, Exp(tokens, 0));
  }
  return mkNode0(TOK_ERROR);
}

Tree* StmtSeq( TokenStream* tokens ) {
  Tree* statement = Stmt(tokens);
  if (eqToken(current(tokens), TOK_SEMICOLON)) {
    advance(tokens);
    return mkNode2(TOK_SEMICOLON, statement, StmtSeq(tokens));
  }
  return statement;
}

Spent a fair while discussing the three tasks with Braedon, trying to figure out how they go together. It looks like you can't do task three without both task one and two, so I guess I'll start on task 1.

Update: Check out the tokeniser me and Braedon have been working on here.