-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparser.h
215 lines (175 loc) · 8.95 KB
/
parser.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
/*
Turtle
Created by Ashley Haggan
University of Bristol
2015
This is the header file for my Turtle parser. All function descriptions will be in this file and a function description will accompany each function.
The parser will parse any file written in the assigned Turtle formal grammer. It will also parse some additional language features. These features are documented in my extention report.
The parser also contains some interpreting functions which assign new draw conditions to a draw linked list. This is used in ashley_sdl.c to draw the required program in SDL.
The Prog struct is quite large, because I took a test driven approach to writing the program I made a decision that most functions should return and integer and take a pointer to the program as an argument. There are a few exception to this.
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<ctype.h>
#define M_PI 3.14159265358979323846
#define strings_match(A, B) (strcmp(A, B) == 0)
#define WORD_LENGTH 20 //Maximum length of a word used in a turtle file, if an input word is longer than this an error is given
//Return values of most functions, used in both parsing and whitebox testing.
#define TRUE 1
#define FALSE 0
//Dimentions of the SDL window, used in Parser to set the middle of the window as a sarting point
#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 700
//Function used to convert degrees to radians
#define DEGTORAD(x) ((x) * M_PI/180)
//Number of letters in the alphabet
#define LETTERS 26
//Number of conditions needed for interpreting a loop
#define CONDITIONS 3
//Maximum length of a COLOUR used in a turtle file, if an input word is longer than this an error is given
#define LONGEST_COLOUR 10
//Number of colours currently parsed and interpreted
#define COLOUR_CHOICE 4
//Struct used to create a linked list containing the user entered program
typedef struct words{
char current[WORD_LENGTH];
struct words *next;
struct words *previous;
}words;
//Struct containing information needed to draw the interpreted program in SDL
//This is used in the parser to create a linked list of coordinates and colours to draw
typedef struct draw{
double current_x;
double current_y;
int red;
int blue;
int green;
struct draw *next;
struct draw *previous;
}draw;
//Used to create a stack of numbers to perform reverse polish operations
typedef struct polish_list{
double number;
struct polish_list *previous;
}polish_list;
//stack pointer for the above stack
typedef struct stack{
polish_list *pointer;
}stack;
//Conditions used to interpret the users loop operations
enum condition{letter, start, stop};
typedef enum condition condition;
//Contains all the information needed by the various functions within the parser and interpreter
typedef struct Prog{
draw start_coordinate;
draw *coordinate; //Keeps coordinate information used to draw the Turtle image
words start_word;
words *current_word; //Records the current word in the program
char colour[LONGEST_COLOUR];
int current_angle;
double current_length;
int test;
int assign;
FILE *file_pointer;
double variable[LETTERS]; //array containing each of the program variables
double result;
//Used to hold the start and stop values for a loop and the letter being used for the loop
condition loop[CONDITIONS];
stack *polish;
}Prog;
/*
The main function in the parser, calls functions to read/store the given file and initialises the program struct
This function chooses whether the user has asked for a test or has entered a text file to parse.
If the user has entered their own file, if it is parsed correctly the main function will call the draw_turtle funnction and display their program in SDL.
*/
/*
Functions called outside the parser
*/
//This function is called if a user has intered a file to be parsed. It scans the file into the linked list and then sends the linked list to the parser to parse. Returns TRUE if parsed correctly.
int parse(Prog *program);
//Called by the main function to check the users input to the command line, returns NULL or the file pointer to the users file
FILE* check_input(Prog *program, int argc, char **argv);
//Sets all the initial values to the program struct, such as the start of both linked lists and the first draw coordinates
void initialise_program(Prog *program);
/*
Functions used at the end of the program to free all malloced space
*/
void free_space(Prog *program);
/*
These functions form the parser
*/
//Checks for an opening brace then calls instrctlst to check the rest
int validate(Prog *program);
//Checks either for an ending brace or a valid instruction
int instrctlst(Prog *program);
//Checks for a valid instruction given in formal grammer, if the program doesn't have a correct ending displays error message
int instruction(Prog *program);
//function assigns a current length value to the program struct the calls assign_draw to add this new coordinate to the draw linked list
int fd(Prog *program);
//functions update the current angle value to the program struct adds for right turn and subtracts for left.
int lt(Prog *program);
int rt(Prog *program);
//Function checks for "SET" instruction, if present determines whether user is setting a letter, the colour or an incorrect program
int set(Prog *program);
//Called if a user wants to set a letter, assigns the value to the program's variable array. Returns FALSE if input in incorrect.
int set_letter(Prog *program);
//Called if user is setting the colour and updates the colour element of the program. Returns FALSE if input in incorrect.
int set_colour(Prog *program);
//Function checks for "DO" instruction followed by a valid letter, it then checks if the loop condition valid then calls a function to perform the loop.
int loop(Prog *program);
//checks a valid "FROM A TO B" condition, A and B could be any allowed number or variable
int loop_condition(Prog *program);
//Checks that the loop goes from a lower to higher value then runs the DO program for the required iterations.
int perform_loop(Prog *program);
//Function returns the integer values of the current variable or number, returns -1 if FALSE to allow for an input of 0 in the loop
int get_parameter(Prog *program);
//Function checks for "IF" instruction followed by a valid letter or colour, it then calls the relevant letter or colour function which will check the condition
int if_condition(Prog *program);
/*
Functions will return TRUE if the grammer is correct, the functions will set an assign flag to off if the if condition is not met. This will mean that the program in the if statement will be read, but wont set of assign any values to be drawn by the interpreter.
*/
int if_letter(Prog *program);
int if_colour(Prog *program);
//Function checks for a ';' or calls functions which check for a variable/number or an operation, if all these are false, returns an error message.
int polish(Prog *program);
//Function calls the is_var and is_number functions and will return TRUE if the current word is a variable or a number
int varnum(Prog *program);
//Function returns TRUE if the current word is a variable A-Z
int is_var(Prog *program);
//Function returns TRUE if the current word is a number
int is_number(Prog *program);
//Function checks the stack, to make sure there are enough numbers in it to perform an operation, it then calls each operation function in turn to check for a valid operation.
int op(Prog *program);
//Checks that the current and previous stack pointers are not NULL(i.e. contains at least two values)
int check_stack(Prog *program);
/*
The operation functions check for thier operations sign, if found, they pop two numbers off the stack and perform their specific operation.
*/
int multiply(Prog *program);
int divide(Prog *program);
int subtract(Prog *program);
int add(Prog *program);
//returns the current number on top of the program->polish stack and frees the space that was occupied by it.
double pop(Prog *program);
//pushes the given number to the top of the the given stack
void push(stack *tmp_pointer, double number);
/*
Test function: - Performs whitebox tests on each function in turn
- Performs a blackbox test on the parser as a whole, by passing test files to the parse function
*/
void test(void);
/*
Function used to interpret the commands in the file that is being parsed
*/
//Adds the x and y coordinates of the next point to draw to the draw linked list, it calls the make positive, assign colour and set_new_xy
void assign_draw(Prog *program);
//Takes an angle, returns % 360 if above 0, or recursively calls itself with the current angle + 360.
int make_positive(int angle);
//Assigns the corresponding RGB parts of the colour element of the program struct to the current draw struct.
void assign_colour(Prog *program);
//Uses the current_angle and current_length elements of the porgram struct
void set_new_xy(Prog *program);
//Function contained in ashley_sdl.c and uses the draw array to draw the program file on the screen in SDL
void draw_turtle(Prog *program);