forked from xjuric29/ifj
-
Notifications
You must be signed in to change notification settings - Fork 0
/
expr.h
206 lines (178 loc) · 8.11 KB
/
expr.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
/**
* @file expr.h
* @author Jiri Furda (xfurda00)
* @brief Header file for precedent analysis of expressions
* @todo
*/
#ifndef EXPR_H
#define EXPR_H
// --- Debugging ---
#ifdef DEBUG
#define DEBUG_PRINT printf
#else
#define DEBUG_PRINT(...)
#endif
// --- Includes ---
// Libraries
#include <stdio.h>
#include <string.h>
// Module dependency
#include "stack.h"
#include "str.h"
#include "scanner.h"
#include "symtab.h"
#include "parser.h"
#include "ilist.h"
#include "tokstack.h"
// --- Constants ---
// Internal values
#define PREC_TABLE_SIZE 16 /// Defines size of precedent table (legal indexes are 0..SIZE-1)
#define RULES_COUNT 14 /// Number of all the grammar rules used
#define EXPR_ERROR -1 /// Internal return value for error
#define EXPR_SUCCESS 1 /// Intarnal return value for success
#define EXPR_TRUE 1 /// Intarnal return value for true
#define EXPR_FALSE 0 /// Intarnal return value for false
#define TOK_FAIL TOK_endOfFile /// Representing error return with type tokenType_t (@warning If you change this here, you must change it also in tokstack.h!)
#define TOK_BOOLEAN 100 /// Boolean data type for tokStack (@warning If you change this here, you must change it also in tokstack.h!)
#define RESULT_ASSIGNMENT 'R' /// Representing result assignment with type char (in expr_convertTypes())
// External return values (@todo This is already defined somewhere for sure)
#define EXPR_RETURN_SUCC 0
#define EXPR_RETURN_ERROR_SYNTAX 2 // e.g. Missing operator/rule not found
#define EXPR_RETURN_ERROR_SEM 3 // e.g. Varibale not defined
#define EXPR_RETURN_ERROR_TYPES 4 // e.g. Wrong data types combination
#define EXPR_RETURN_ERROR_INTERNAL 99 // e.g. malloc fail
// Internal return value
#define EXPR_RETURN_NOMORETOKENS 123 /// Representing end of expression input
#define EXPR_RETURN_STARTOVER 124 /// Representing instruction to start over (used when there is TOK_semicolon in CONTEXT_PRINT)
/**
* @brief Enum structure for determinating next move of the algorith
*/
typedef enum
{
ACTION_shift,
ACTION_reduce,
ACTION_specialShift,
ACTION_illegal /// Trying to perform an illegal action
} precTableAction_t;
/**
* @brief Enum structure for navigating in precedental table, []...legal combinations
* @todo Expand for more values (Now using only 6 from example in lecture)
*/
typedef enum
{
TERM_plus, /// Plus "+" [int+int = int, int+double = double, double+int = double, double+double = double, str+str = str]
TERM_minus, /// Minus "-" [int-int = int, int-double = double, double-int = double, double-double = double]
TERM_divInt, /// Integer division "\" [int\int = int]
TERM_mul, /// Multiplication "*" [int*int = int, int*double = double, double*int = double, double*double = double]
TERM_div, /// Division "/" [int/int = double, int/double = double, double/int = double, double/double = double]
TERM_lBrac, /// Left bracket "("
TERM_rBrac, /// Right bracket ")"
TERM_id, /// Identificator (@todo Not sure)
// Special
TERM_stackEnd, /// End of stack = "$"
// Logic operators
TERM_equal, /// Operator "="
TERM_notEqual, /// Operator "<>"
TERM_less, /// Operator "<"
TERM_lessEqual, /// Operator "<="
TERM_greater, /// Operator ">"
TERM_greaterEqual, /// Operator ">="
TERM_string, /// String "str"
// Special special
TERM_expr, /// Expression = "E" (in rule)
} precTableIndex_t;
// --- Functions ---
/**
* @brief Main function for evaluating expressions (logical or arithmectical) called by parser to transfer token proceeding to this module.
*
* First of all this function create and initialize stack and other needed variables.
* It's main function is to read all tokens and proceed them to expr_doOperation() untill it found the first one that doesn't belong to the expression.
* When the non-expression token is found, it's sent back to parser to be proceed and this module is shut down.
*
* Communicating with parser
* When this function is called by parser, parser sends first token that belong to expression via pointer.
* When this module is shutting down, it puts first token that DOESN'T belong to the expression back to the pointer.
*
* @param *parserToken Pointer to token used for communicating with parser
* @return (@todo)
*/
int expr_main(int context, token_t *parserToken, st_globalTable_t *st_global, string *func_name, st_element_t *variable);
/**
* @brief Core function for expression token processing.
*
* This does all the magic stuff that happens in this module. It's first step is to find out precedent table indexes.
* That is done using converting external token types (defined in scanner.h) to internal ones used in this module (e.g. TERM_plus), that gives us the column index.
* The row index is based on character on top of the stack, therefore it's gained using expr_getIndexFromChar() function.
* Now we have all required informations to check the precedent table to find out our next move, this is done by calling expr_readTable() function.
* Based on the result we call corresponding function, that means one of these: expr_shift / expr_reduce / expr_specialshift / expr_error
*
* @warning TOK_endOfFile doesn't represent it's original purpose but here it symbolizes there are no more tokens to load that would belong to the expression
*
* @param *stack Pointer to stack for the algorithm
* @param tokenToken Type of now proceessed token
* @return 1 = no error (@todo)
*/
int expr_algorithm(myStack_t *stack, tokStack_t *tokStack, token_t tokenType, int context, int skipMaskingAsID, int *resetTempStr);
/**
* @brief Find action for corresponding row (character on top of the stack) and column (loaded token type).
*
* Does nothing unexcepted, if you are not dumb it tells you what is the next move for the algrithm.
* But if you ask for some fantasy stuff it punches you in the face.
*
* @param row Index corresponding to character on top of the stack
* @param col Index corresponding to loaded token
* @return next action of the algorithm
*/
precTableAction_t expr_readTable(precTableIndex_t rowIndex, precTableIndex_t colIndex);
/**
* @brief Convert char to index
*
* Find corresponding index in the precedent table for the character paramater.
*
* @param character Char you want index for
* @return Index in precedent table
*/
precTableIndex_t expr_getIndexFromChar(char character);
/**
* @brief Convert index to char
*
* Find corresponding character based on the index in the precedent table.
*
* @param index Index in precedent table you want corresponding char for
* @return Real character
*/
char expr_getCharFromIndex(precTableIndex_t index);
// @todo Comment these functions
int expr_shift(myStack_t *stack, char character);
/**
* @brief Algortihm operation reduce
*
* @todo Description
*
* @param *stack Pointer to stack for the algorithm
* @return EXPR_RETURN_SUCC when successful
* EXPR_RETURN_ERROR_INTERNAL when couldn't add char to handle string
* EXPR_RETURN_ERROR_SYNTAX when rule not found
*/
int expr_reduce(myStack_t *stack, tokStack_t *tokStack, token_t token);
int expr_specialShift(myStack_t *stack, char character);
int expr_searchRule(string handle);
int expr_isAlgotihmFinished(myStack_t *stack, int tokenType); // For successful end there should be only "$E" in the stack
int expr_generateInstruction(tokStack_t *tokStack, char terminal, token_t token);
int expr_generateResult(tokStack_t *tokStack, int context, st_globalTable_t *st_global, string *func_name, st_element_t *variable);
int expr_convertTypes(tokStack_t *tokStack, char terminal);
tokenType_t expr_elTypeConvert(type_t el_type);
int expr_finishAlgorithm(myStack_t *stack, tokStack_t *tokStack, token_t token, int context, int *resetTempStr);
/**
* @brief Check if token be used as begining of expression
* @param firstToken Token structure to be checked
* @return EXPR_TRUE if can be first, EXPR_FALSE if cannot
*/
int expr_isFirstValid(token_t firstToken);
/**
* @brief Prints an error to stderr
* @todo Peacefully end the module
* @param msg Message for debugging (without new line at the end)
*/
void expr_error(char *msg);
#endif