Code:
#ifndef _COMPILER_H_
#define _COMPILER_H_
/*
* compiler.h
*
*/
#define TRUE 1
#define FALSE 0
#define NOOPSTMT 100
#define PRINTSTMT 101
#define ASSIGNSTMT 102
#define IFSTMT 103 // This is used for all control statements (if, while, repeat)
#define GOTOSTMT 104
#define KEYWORDS 7
#define RESERVED 27
#define VAR 1
#define IF 2
#define WHILE 3
#define REPEAT 4
#define UNTIL 5
#define PRINT 6
#define ARRAY 7
#define PLUS 8
#define MINUS 9
#define DIV 10
#define MULT 11
#define EQUAL 12
#define COLON 13
#define COMMA 14
#define SEMICOLON 15
#define LBRAC 16
#define RBRAC 17
#define LPAREN 18
#define RPAREN 19
#define LBRACE 20
#define RBRACE 21
#define NOTEQUAL 22
#define GREATER 23
#define LESS 24
#define ID 25
#define NUM 26
#define ERROR 27
// This implementation does not allow tokens that are more
// than 100 characters long
#define MAX_TOKEN_LENGTH 100
// The following global variables are defined in compiler.c:
extern char token[MAX_TOKEN_LENGTH];
extern int ttype ;
//---------------------------------------------------------
// Data structures:
struct varNode
{
char* name;
int value;
};
struct gotoStatement
{
struct statementNode * target;
};
struct assignmentStatement
{
struct varNode * lhs;
struct varNode * op1;
struct varNode * op2;
int op; // PLUS, MINUS, MULT, DIV --> lhs = op1 op op2;
// 0 --> lhs = op1;
};
struct printStatement
{
struct varNode * id;
};
struct ifStatement
{
struct varNode * op1;
struct varNode * op2;
int relop; // GREATER, LESS, NOTEQUAL
struct statementNode * true_branch;
struct statementNode * false_branch;
};
struct statementNode
{
int stmt_type; // NOOPSTMT, PRINTSTMT, ASSIGNSTMT, IFSTMT, GOTOSTMT
struct assignmentStatement * assign_stmt; // NOT NULL iff stmt_type == ASSIGNSTMT
struct printStatement * print_stmt; // NOT NULL iff stmt_type == PRINTSTMT
struct ifStatement * if_stmt; // NOT NULL iff stmt_type == IFSTMT
struct gotoStatement * goto_stmt; // NOT NULL iff stmt_type == GOTOSTMT
struct statementNode * next; // next statement in the list or NULL
};
//---------------------------------------------------------
// Functions that are provided:
void print_debug(const char * format, ...);
void ungetToken();
int getToken();
/*
* You need to write a function with the signature that follows this comment.
* It is supposed to parse the input program and generate an intermediate
* representation for it. Write all your code in a separate file and include
* this header file.
*/
struct ifStatement * relop();
struct statementNode * parse_program_and_generate_intermediate_representation();
#endif /* _COMPILER_H_ */
///////////////////////////////////////parse_graph.c follows
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "compiler.h"
struct ifStatement* relop()
{
struct ifStatement* relo;
ttype = getToken();
if (ttype == GREATER)
{
relo = malloc(sizeof(struct ifStatement));
relo->relop = GREATER;
relo->op1 = malloc(sizeof(struct varNode));
relo->op2 = malloc(sizeof(struct varNode));
relo->true_branch = malloc(sizeof(struct statementNode));
relo->false_branch = malloc(sizeof(struct statementNode));
relo->true_branch = NULL;
relo->false_branch = NULL;
return relo;
}else
if (ttype == LESS)
{
relo = malloc(sizeof(struct ifStatement));
relo->relop = LESS;
relo->op1 = malloc(sizeof(struct varNode));
relo->op2 = malloc(sizeof(struct varNode));
relo->true_branch = malloc(sizeof(struct statementNode));
relo->false_branch = malloc(sizeof(struct statementNode));
relo->true_branch = NULL;
relo->false_branch = NULL;
return relo;
}else
if (ttype == NOTEQUAL)
{
relo = malloc(sizeof(struct ifStatement));
relo->relop = NOTEQUAL;
relo->op1 = malloc(sizeof(struct varNode));
relo->op2 = malloc(sizeof(struct varNode));
relo->true_branch = malloc(sizeof(struct statementNode));
relo->false_branch = malloc(sizeof(struct statementNode));
relo->true_branch = NULL;
relo->false_branch = NULL;
return relo;
}
}
struct varNode * primary()
{
struct varNode *primar;
ttype = getToken();
if (ttype == NUM)
{
primar = malloc(sizeof(struct varNode));
primar->value = atoi(token);
return primar;
}
if (ttype == ID)
{
primar = malloc(sizeof(struct varNode));
primar->name;
return primar;
}
}
struct assignmentStatement * oper()
{
struct assignmentStatement * opp;
ttype = getToken();
if (ttype == PLUS)
{
opp = malloc(sizeof(struct assignmentStatement));
opp->op = PLUS;
}
if (ttype == MINUS)
{
opp = malloc(sizeof(struct assignmentStatement));
opp->op = MINUS;
}
if (ttype == MULT)
{
opp = malloc(sizeof(struct assignmentStatement));
opp->op = MULT;
}
if (ttype == DIV)
{
opp = malloc(sizeof(struct assignmentStatement));
opp->op = DIV;
}
}
struct ifStatement * condition ()
{
struct ifStatement *cond;
ttype = getToken();
if(ttype == NUM | ttype == ID)
{
//printf("1");
ungetToken();
cond = malloc(sizeof(struct ifStatement));
cond->op1 = primary();
//cond->op1->value;
ttype = getToken();
if ( ttype == GREATER | ttype == LESS | ttype == NOTEQUAL )
{
ungetToken();
cond = relop();
cond->relop;
//printf("%d",cond->relop);
ttype = getToken();
if(ttype == NUM | ttype == ID)
{
ungetToken();
cond->op2 = primary();
//cond->op2->value);
return cond;
}
}
}
}
struct assignmentStatement * expr()
{
struct assignmentStatement * expr;
ttype = getToken();
if(ttype == NUM | ttype == ID)
{
ungetToken();
expr = malloc(sizeof(struct assignmentStatement));
//expr->lhs = NULL;
expr->op1 = primary();
//expr->op1->value;
//printf("%d",expr->op1->value);
ttype = getToken();
if (ttype == PLUS | ttype == MINUS | ttype == MULT | ttype == DIV)
{
ungetToken();
expr = oper();
//printf("%d", ttype);
ttype = getToken();
if(ttype == NUM | ttype == ID)
{
ungetToken();
expr->op2 = primary();
//printf("%d",expr->op2->value);
}
}
}
}
struct assignmentStatement * assign_stmt()
{
struct assignmentStatement * assign;
ttype = getToken();
if (ttype == ID)
{
assign = malloc(sizeof(struct assignmentStatement));
assign->lhs->name;
printf("%d\t", ttype);
ttype = getToken();
if (ttype == EQUAL)
{printf("%d\t", ttype);
ttype = getToken();
if (ttype == NUM | ttype == ID)
{//printf("%d\t", ttype);
ungetToken();
assign =expr();
printf("%d", assign->op1->value);
/*if(ttype == SEMICOLON)
{
ungetToken();
assign->op1 = primary();
printf("%d", assign->op1->value);return assign;
}
//assign = expr();
//printf("%d", assign->op1->value);
if (ttype == PLUS | ttype == MINUS | ttype == MULT | ttype == DIV)
{printf("%d\t", ttype);
//ttype = getToken();
printf("%d\t", ttype);
ungetToken();
ungetToken();
printf("%d\t", ttype);
assign = expr();
//assign->op1->value;
//printf("%d", assign->op1->value);
return assign;
}else { return assign;}*/
}
}
}
}
//////////////////
So for a project I am writing a compiler for a simple lang assuming there are no
lexical or semantic errors. My problem is when i test assign_stmt() in main on say
a = 4 + 4, the Id and the equal are parsed,but when i call assign = expr(); to parse the 4+4, i get a seg fault if i call printf(assign->op1->value); i cant figure out why this is occurring because if just call expr(); in main on 4+4 printf(exp->op1->value); then i receive the right answer, a 4. ANY HELP APPRECIATED
also getToken receives the next token in the list and ungetToken puts it back