Compare commits

..

No commits in common. "master" and "scanner" have entirely different histories.

21 changed files with 120 additions and 2399 deletions

Binary file not shown.

Binary file not shown.

12
INSTRUCTIONS.txt Normal file
View File

@ -0,0 +1,12 @@
To compile this under Linux:
gcc -o platy_gnu buffer.c buffer.h platy_bt.c -Wall -ansi -pedantic
To use:
./platy_gnu ass1.pls [f|a|m]
f: fixed increment mode
a: additive increment mode
m: multiplicative mode
NOTE: Change buffer.h to use malloc.h instead of mm_maloc.h if running on anything that isn't macOS

View File

@ -1,328 +0,0 @@
# PLATYPUS Language Specification
### 2.1 Input Elements and Tokens
<input character> ->
ASCII characters but not SEOF
<input> ->
<input elements> SEOF
<input elements> ->
<input element> | <input elements> <input element>
<token> ->
<variable identifier> | <keyword> | <floating-point literal>
| <integer literal> | <string literal> | <separator> | <operator>
### 2.2 White Space
<white space> ->
ASCII SP character (space)
| ASCII HT character (horizontal tab)
| ASCII VT character (vertical tab)
| ASCII FF character (form feed)
| <line terminator>
<line terminator> ->
CR | LF | CR LF
### 2.3 Comments
<comment> ->
!< <opt_characters in line> <line terminator>
<characters in line> ->
<comment character> | <characters in line> <comment character>
<comment character> ->
<input character> but not <line terminator>
### 2.4 Variable Identifiers
<variable identifier> ->
<arithmetic variable identifier> | <string variable identifier>
<arithmetic identifier> ->
<letter> <opt_letters or digits>
<opt_letters or digits> ->
ε | <letters or digits>
<letters or digits> ->
<letter or digit> | <letters or digits> <letter or digit>
<letter> ->
[a-z] | [A-Z]
<letter or digit> ->
<letter> | <digit>
<string variable identifier> ->
<arithmetic variable identifier>#
### 2.5 Keywords
<keyword> ->
PLATYPUS | IF | THEN | ELSE | USING | REPEAT | INPUT | OUTPUT
### 2.6 Integer Literals
<integer literal> ->
<decimal integer literal> | <octal integer literal>
<decimal integer literal> ->
0 | <non-zero digit> <opt_digits>
<opt_digits> ->
ε | <digits>
<digits> ->
<digit> | <digits> <digit>
<digit> ->
0 | <non-zero digit>
<non-zero digit> -> one of
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
<octal integer literal> ->
0 <octal digit> <octal digits>
<octal digit> ->
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
<octal digits> ->
<octal digit> | <octal digits> <octal digit>
### 2.7 Floating-point Literals
<floating-point literal> ->
<decimal integer literal> . <opt_digits>
### 2.8 String Literals
<opt_string literal> ->
ε | <string literal>
<string literal> ->
"<opt_string characters>"
<opt_string characters> ->
ε | <string characters>
<string characters> ->
<input character> | <string characters> <input character>
### 2.9 Separators
<separator> ->
( | ) | { | } | , | ; | " |.
### 2.10 Operators
<operator> ->
<arithmetic operator> | <string concatenation operator>
| <relational operator> | <logical operator>
| <assignment operator>
<arithmetic operator> ->
+ | - | * | /
<string concatenation operator> ->
<<
<relational operator> ->
> | < | == | <>
<logical operator> ->
.AND. | .OR.
<assignment operator> ->
=
## 3. The PLATYPUS Syntactic Specification
### 3.1 PLATYPUS Program
<program> ->
PLATYPUS {<opt_statements>} SEOF
<opt_statements> ->
ε | <statements>
<statements> ->
<statement> | <statements> <statement>
### 3.2 Statements
<statement> ->
<assignment statement>
| <selection statement>
| <iteration statement>
| <input statement>
| <output statement>
### 3.3 Assignment Statement
<assignment statement> ->
<assignment expression> ;
<assignment expression> ->
<arithmetic variable identifier> = <arithmetic expression>
| <string variable identifier> = <string expression>
#### 3.2.2 Selection Statement (`if` statement)
<selection statement> ->
IF (<conditional expression>) THEN <opt_statements>
ELSE {<opt_statements>};
#### 3.2.3 Iteration Statement (the loop statement)
<iteration statement> ->
USING (<assignment expression> , <conditional expression>, <assignment expression>) REPEAT { <opt_statements> };
#### 3.2.4 Input Statement
<input statement> ->
INPUT (<variable list>);
<opt_variable list> ->
ε | <variable list>
/** New Variable List version below
<variable list> ->
<variable identifier> | <variable list>,<variable identifier>
**/
<variable list> ->
<variable identifier> <variable list'>
<variable list'> ->
, <variable identifier> <variable list'> | E
#### 3.2.5 Output Statement
<output statement> ->
OUTPUT(<opt_variable list> | <opt_string literal>);
### 3.3 Expressions
#### 3.3.1 Arithmetic Expressions
<arithmetic expression> ->
<unary arithmetic expression>
| <additive arithmetic expression>
<unary arithmetic expression> ->
- <primary arithmetic expression>
| + <primary arithmetic expression>
/** New Version of Additive Arithmetic Expressions below
<additive arithmetic expression> ->
<additive arithmetic expression> + <multiplicative arithmetic expression>
| <additive arithmetic expression> - <multiplicative arithmetic expression>
| <multiplicative arithmetic expression>
**/
<additive arihtmetic expression> ->
<multiplicative arithmetic expression> <additive arithmetic expression'>
<additive arithmetic expression'> ->
+ <multiplicative arithmetic expression> <additive arithmetic expression'>
| - <multiplicative arithmetic expression> <additive arithmetic expression'>
/** New Version of Mult. Arithmetic Expressions below
<multiplicative arithmetic expression> ->
<multiplicative arithmetic expression> * <primary arithmetic expression>
| <multiplicative arithmetic expression> / <primary arithmetic expression>
| <primary arithmetic expression>
**/
<multiplicative arithmetic expression> ->
<primary arithmetic expression> <multiplicative arithmetic expression'>
<multiplicative arithmetic expression'> ->
* <primary arithmetic expression> <multiplicative arithmetic expression'>
| / <primary arithmetic expression> <multiplicative arithmetic expression'>
<primary arithmetic expression> ->
<variable identifier>
| <floating-point literal>
| <integer literal>
| (<arithmetic expression>)
#### 3.3.2 String Expression
/** New version of String Expressions below
<string expression> ->
<primary string expression>
| <string expression> << <primary string expression>
**/
<string expression> ->
<primary string expression> <string expression'>
<string expression'> ->
<< <primary string expression> <string expression'> | E
<primary string expression> ->
<string variable identifier>
| <string literal>
#### 3.3.3 Conditional Expression
<conditional expression> ->
<logical OR expression>
/** New Logical OR and Logical AND expressions below
<logical OR expression> ->
<logical AND expression>
| <logical OR expression> .OR. <logical AND expression>
<logical AND expression> ->
<relational expression>
| <logical AND expression> .AND. <relational expression>
**/
<logical OR expression> ->
<logical AND expression> <logical OR expression'>
<logical OR expression'> ->
.OR. <logical AND expression> <logical OR expression'>
<logical AND expression> ->
<relational expression> <logical AND expression'>
<logical AND expression'> ->
.AND. <relational expression> <logical AND expression'>
#### 3.3.4 Relational Expressions
/** New version of Relational expressions below
<relational expression> ->
<primary a_relational expression> <relational operator> <primary a_relational expression>
| <primary s_relational expression> <relational operator> <primary s_relational expression>
**/
<relational expression> ->
<primary a_relational expression> <primary a_relational expression'>
| <primary s_relational expression> <primary s_relational expression'>
<primary a_relational expression> ->
<floating-point literal>
| <integer literal>
| <variable identifier>
<primary a_relational expression'> ->
== <primary a_relational expression>
| <> <primary a_relational expression>
| > <primary a_relational expression>
| < <primary a_relational expression>
<primary s_relational expression> ->
<string literal> | <string variable identifier>
<primary s_relational expression'> ->
== <primary s_relational expression>
| <> <primary s_relational expression>
| > <primary s_relational expression>
| < <primary s_relational expression>

Binary file not shown.

View File

@ -1,5 +1,5 @@
# PLATYPUS
*Frontend compiler for the PLATYPUS language specification*
*Buffer Descriptor for the PLATYPUS language specification*
## Building
@ -8,12 +8,12 @@
*gcc (tested in version 6.3.x) or clang (tested under LLVM clang-0800.0.42.1)*
- `make [gcc | clang]`
- No argument will build both versions (this is an aftermath of having to check behaviour in the binary from multiple compilers)
- It is safe to modify the default to either gcc or clang if you wish.
- **NOTE: I haven't tested or created make targets for the final implementation yet. This is somewhat buried deep into the backburner**
- Default is to build both versions (this is an aftermath of testing behaviour from different compilers)
- It is safe to modify the default to either gcc or clang if you don't have one of them
- **NOTE: I haven't tested or created make targets for the scanner yet.**
### Windows
#### Requires
- `msvc` (tested under Visual Studio 2015 with Update 3, however VS 2012 and 2013 shouldn't behave abnormally either, nor should 2017)
- `msvc` (tested under Visual Studio 2015 with Update 3, however VS2013 shouldn't behave abnormally either, nor should 2017)
- Disable language extensions (use ANSI C)
---
## Running
@ -31,10 +31,10 @@
# Notes
**This is in no way complete, or ready for production in any shape or form.** It works up to the parser, but still contains incorrect grammar parsing and some edge cases that causes crashes.
This is in no way complete, it is missing a scanner implementation, parser, symbol table, etc.
You can modify the initial capacity and increment factor defined in `platy.c` (should really make that a command line parameter in a future release)
You can modify the initial capacity and increment factor defined in `platy_bt.c` (should really make that a command line parameter in a future release)
- Increment factor range for additive mode: `1 - 255`. (setting this to 0 implies fixed mode, regardless of the mode given in the command line)
- Initial capacity range (in bytes): `0 - 32767 (SHRT_MAX)`
- This is an issue caused by my environment's install locations for the C include libraries:
- **`buffer.h` contains an `#ifdef` directive checking if `WIN32` exists. Due to an upgrade issue with GCC in macOS (possibly only in my machine), `malloc.h` is actually named `mm_maloc.h`. If your system uses `malloc.h`, you can safely delete the check and use the regular filename instead.**
- This is due to my environment's install locations for the C include libraries:
- **Inside `buffer.h`, there is a `#DEFINE` line for `MACOS_DEP`. If you are using a Linux system or Windows and your malloc.h is actually named malloc.h, you can leave `#undef MACOS_DEP` alone, otherwise comment it out.**

View File

@ -4,7 +4,7 @@
* Author: Victor Fernandes, 040772243
* Course: CST8152 - Compilers, Lab Section: 011
* Date: February 1, 2017
* Professor: S^R
* Professor: Svillen Ranev
* A character buffer utility with three modes of self-incrementation
through dynamic memory allocation, and ability to set a mark flag.
* Function list: b_create, b_isfull, b_isempty, b_size, b_capacity,

View File

@ -22,12 +22,11 @@
/* standard header files */
#include <stdio.h> /* standard input/output */
#ifndef WIN32
#ifdef MACOS_DEP
#include <mm_malloc.h> /* for dynamic memory allocation.*/
#else
#include <malloc.h>
#endif
#include <limits.h> /* implementation-defined data type ranges and limits */
/* constant definitions */

View File

@ -7,8 +7,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "buffer", "buffer\buffer.vcx
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scanner", "scanner\scanner.vcxproj", "{C53261F2-8A2D-4F75-8E54-DBFD16A621BB}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Stable", "Stable\Stable.vcxproj", "{C2CCF0F1-D771-4F57-89EA-F76727169CE3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
COMPILERS|x64 = COMPILERS|x64
@ -43,18 +41,6 @@ Global
{C53261F2-8A2D-4F75-8E54-DBFD16A621BB}.Release|x64.Build.0 = Release|x64
{C53261F2-8A2D-4F75-8E54-DBFD16A621BB}.Release|x86.ActiveCfg = Release|Win32
{C53261F2-8A2D-4F75-8E54-DBFD16A621BB}.Release|x86.Build.0 = Release|Win32
{C2CCF0F1-D771-4F57-89EA-F76727169CE3}.COMPILERS|x64.ActiveCfg = Release|x64
{C2CCF0F1-D771-4F57-89EA-F76727169CE3}.COMPILERS|x64.Build.0 = Release|x64
{C2CCF0F1-D771-4F57-89EA-F76727169CE3}.COMPILERS|x86.ActiveCfg = Debug|Win32
{C2CCF0F1-D771-4F57-89EA-F76727169CE3}.COMPILERS|x86.Build.0 = Debug|Win32
{C2CCF0F1-D771-4F57-89EA-F76727169CE3}.Debug|x64.ActiveCfg = Debug|x64
{C2CCF0F1-D771-4F57-89EA-F76727169CE3}.Debug|x64.Build.0 = Debug|x64
{C2CCF0F1-D771-4F57-89EA-F76727169CE3}.Debug|x86.ActiveCfg = Debug|Win32
{C2CCF0F1-D771-4F57-89EA-F76727169CE3}.Debug|x86.Build.0 = Debug|Win32
{C2CCF0F1-D771-4F57-89EA-F76727169CE3}.Release|x64.ActiveCfg = Release|x64
{C2CCF0F1-D771-4F57-89EA-F76727169CE3}.Release|x64.Build.0 = Release|x64
{C2CCF0F1-D771-4F57-89EA-F76727169CE3}.Release|x86.ActiveCfg = Release|Win32
{C2CCF0F1-D771-4F57-89EA-F76727169CE3}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

874
parser.c
View File

@ -1,874 +0,0 @@
/* File Name: parser.c
* The PLATYPUS parsing program for the final assignment of
How To Train Your Dragon (AKA Compilers)
* Compiler: GNU GCC 6
* Author: Victor Fernandes, 040772243
* Course: CST8152 - Compilers, Lab Section: 011
* Date: April 21, 2017
* Professor: Svillen Ravev
* Version: 0.1
*/
#include "parser.h"
/* Global variables for the parser */
Token lookahead;
int synerrno; /* Error counter */
Buffer *sc_buf; /* Scanner buffer */
extern char *kw_table[]; /* Keyword table with matching enum */
extern STD sym_table; /* The symbol table */
extern Buffer *str_LTBL; /* String literal table */
extern int line; /* Line position of the Scanner */
extern Token malar_next_token(Buffer *); /* Scanner function to get the next token */
/* Begins the source file parsing
* Author: Victor Fernandes, 040772243
* Version: 0.0.1
* Called functions: malar_next_token, program, match, gen_incode
* Parameters: pBuffer - The input buffer
* Return value: N/A
*/
void parser(pBuffer in_buf)
{
synerrno = 0;
sc_buf = in_buf;
lookahead = malar_next_token(sc_buf);
program();
match(SEOF_T, NO_ATTR);
gen_incode("PLATY: Source file parsed");
}
/* Matches the given token code+attribute pair to the current lookahead token
* Author: Victor Fernandes, 040772243
* Version: 0.0.1
* Called functions: syn_eh, syn_printe, malar_next_token
* Parameters: pr_token_code, pr_token_attribute
* Return value:
* Algorithm:
*/
void match(int pr_token_code, int pr_token_attribute)
{
if (pr_token_code != lookahead.code)
{
syn_eh(pr_token_code);
return;
}
switch (pr_token_code)
{
case ART_OP_T:
case REL_OP_T:
case LOG_OP_T:
case KW_T:
if (pr_token_attribute != lookahead.attribute.get_int)
{
break;
}
default:
if (lookahead.code == SEOF_T)
return;
lookahead = malar_next_token(sc_buf);
if (lookahead.code == ERR_T)
{
++synerrno;
syn_printe();
lookahead = malar_next_token(sc_buf);
}
return;
}
syn_eh(pr_token_code);
}
/* Error "recovery" function for the parser
* Author: Victor Fernandes, 040772243
* Version: 0.0.1
* Called functions: syn_printe, malar_next_token, exit
* Parameters: int pr_token_code
* Return value:
* Algorithm: Outputs a standard syn_printe error, and steps through
the source file with the Scanner until it finds the next matching
code needed by pr_token_code.
*/
void syn_eh(int pr_token_code)
{
syn_printe();
++synerrno;
while (lookahead.code != SEOF_T)
{
lookahead = malar_next_token(sc_buf);
if (lookahead.code == pr_token_code)
{
if (lookahead.code != SEOF_T)
{
lookahead = malar_next_token(sc_buf);
}
return;
}
}
if (pr_token_code != SEOF_T)
exit(synerrno);
}
/* Outputs an error message to stdout using the current lookahead token
* Author: Victor Fernandes, 040772243
* Version: 0.0.1
* Called functions: printf, b_setmark
* Parameters: N/A
*/
void syn_printe()
{
printf("PLATY: Syntax error: Line:%3d\n***** Token code: %3d Attribute: ", line, lookahead.code);
switch (lookahead.code)
{
case ERR_T:
printf("%s\n", lookahead.attribute.err_lex);
break;
case SEOF_T:
printf("NA\n");
break;
case AVID_T:
case SVID_T:
printf("%s\n", sym_table.pstvr[lookahead.attribute.get_int].plex);
break;
case FPL_T:
printf("%5.1f\n", lookahead.attribute.flt_value);
break;
case INL_T:
printf("%d\n", lookahead.attribute.get_int);
break;
case STR_T:
printf("%s\n", b_setmark(str_LTBL, lookahead.attribute.str_offset));
break;
case SCC_OP_T:
printf("NA\n");
break;
case ASS_OP_T:
printf("NA\n");
break;
case ART_OP_T:
printf("%d\n", lookahead.attribute.get_int);
break;
case REL_OP_T:
printf("%d\n", lookahead.attribute.get_int);
break;
case LOG_OP_T:
printf("%d\n", lookahead.attribute.get_int);
break;
case LPR_T:
printf("NA\n");
break;
case RPR_T:
printf("NA\n");
break;
case LBR_T:
printf("NA\n");
break;
case RBR_T:
printf("NA\n");
break;
case KW_T:
printf("%s\n", kw_table[lookahead.attribute.get_int]);
break;
case COM_T:
printf("NA\n");
break;
case EOS_T:
printf("NA\n");
break;
default:
printf("PLATY: Scanner error: invalid token code: %d\n", lookahead.code);
}
}
/* Generates a message to stdout (can be later modified to generate C code)
* Author: Victor Fernandes, 040772243
* Version: 0.0.1
* Called functions: printf
* Parameters: char* code
* Return value: N/A
*/
void gen_incode(char *code)
{
printf("%s\n", code);
}
/*
* Grammar functions ahoy
*/
/*
* <additive_arithmetic_expression> ->
<multiplicative_arithmetic_expression> <additive_arithmetic_expression_prime>
FIRST Set = {AVID_T, FPL_T, INL_T, (}
*/
void additive_arithmetic_expression()
{
multiplicative_arithmetic_expression();
additive_arithmetic_expression_prime();
}
/*
* <additive_arithmetic_expression> ->
<multiplicative_arithmetic_expression> <additive_arithmetic_expression_prime>
FIRST Set = {AVID_T, FPL_T, INL_T, (}
*/
void additive_arithmetic_expression_prime()
{
if (lookahead.code == ART_OP_T &&
lookahead.attribute.arr_op != MULT &&
lookahead.attribute.arr_op != DIV)
{
match(lookahead.code, lookahead.attribute.arr_op);
multiplicative_arithmetic_expression();
additive_arithmetic_expression_prime();
gen_incode("PLATY: Additive arithmetic expression parsed");
}
}
/*
* <opt_LPR_T> <unary_arithmetic_expression> <opt_RPR_T> |
<opt_LPR_T> <additive_arithmetic_expression> <opt_RPR_T>
FIRST Set = {-, +, AVID_T, FPL_T, INL_T, (}
*/
void arithmetic_expression()
{
/* GCC complains that PLUS and MINUS enums aren't handled,
but this is automatically handled in additive_arithmetic_expression()
*/
switch (lookahead.code)
{
case ART_OP_T:
switch (lookahead.attribute.arr_op)
{
case MULT:
case DIV:
syn_printe();
return;
}
unary_arithmetic_expression();
break;
case AVID_T:
case FPL_T:
case INL_T:
case LPR_T:
additive_arithmetic_expression();
break;
case EOS_T:
return;
default:
syn_printe();
return;
}
gen_incode("PLATY: Arithmetic expression parsed");
}
/*
* <assignment_expression> ->
AVID = <arithmetic_expression> | SVID = <string_expression>
FIRST Set = {AVID, SVID}
*/
void assignment_expression()
{
switch (lookahead.code)
{
case AVID_T:
match(AVID_T, NO_ATTR);
match(ASS_OP_T, NO_ATTR);
arithmetic_expression();
gen_incode("PLATY: Assignment expression (arithmetic) parsed");
break;
case SVID_T:
match(SVID_T, NO_ATTR);
match(ASS_OP_T, NO_ATTR);
string_expression();
gen_incode("PLATY: Assignment expression (string) parsed");
break;
default:
syn_printe();
}
}
/*
* <assignment_statement> ->
<assignment_expression> ;
FIRST Set = {AVID, SVID}
*/
void assignment_statement()
{
assignment_expression();
match(EOS_T, NO_ATTR);
gen_incode("PLATY: Assignment statement parsed");
}
/*
* <conditional_expression> ->
<logical_or_expression>
FIRST Set = {AVID_T, SVID_T, INL_T, SVID_T, STR_T}
*/
void conditional_expression()
{
logical_or_expression();
gen_incode("PLATY: Conditional expression parsed");
}
/*
* <input_statement> ->
INPUT ( <variable_list> );
FIRST Set = {INPUT}
*/
void input_statement()
{
match(KW_T, INPUT);
match(LPR_T, NO_ATTR);
variable_list();
match(RPR_T, NO_ATTR);
match(EOS_T, NO_ATTR);
gen_incode("PLATY: Input statement parsed");
}
/*
* <iteration_statement> ->
USING ( <assignment_expression>, <conditional_expression>, <assignment_expression> ) REPEAT { <opt_statements> } ;
FIRST Set = {USING}
*/
void iteration_statement()
{
match(KW_T, USING);
match(LPR_T, NO_ATTR);
assignment_expression();
match(COM_T, NO_ATTR);
assignment_expression();
match(RPR_T, NO_ATTR);
match(KW_T, REPEAT);
match(LBR_T, NO_ATTR);
opt_statements();
match(RBR_T, NO_ATTR);
match(EOS_T, NO_ATTR);
gen_incode("PLATY: USING statement parsed");
}
/*
* <logical_and_expression> ->
<relational_expression> <logical_and_expression_prime>
FIRST Set = {AVID_T, FPL_T, INL_T, SVID_T, STR_T}
*/
void logical_and_expression()
{
relational_expression();
logical_and_expression_prime();
}
/*
* <logical_and_expression_prime> ->
.AND. <relational_expression> <logical_and_expression_prime> | E
FIRST Set = { .AND., E}
*/
void logical_and_expression_prime()
{
if (lookahead.code == LOG_OP_T &&
lookahead.attribute.log_op == AND)
{
match(LOG_OP_T, AND);
relational_expression();
logical_and_expression_prime();
gen_incode("PLATY: Logical AND expression parsed");
}
}
/*
* <logical_or_expression> ->
<logical_and_expression> <logical_or_expression_prime>
FIRST Set = {AVID_T, FPL_T, INL_T, SVID_T, STR_T}
*/
void logical_or_expression()
{
logical_and_expression();
logical_or_expression_prime();
}
/*
* <logical_or_expression_prime> ->
.OR. <logical_and_expression> <logical_or_expression_prime>
FIRST Set = { .OR., E }
*/
void logical_or_expression_prime()
{
if (lookahead.code == LOG_OP_T &&
lookahead.attribute.log_op == OR)
{
logical_and_expression();
logical_or_expression_prime();
gen_incode("PLATY: Logical OR expression parsed");
}
}
/*
* <multiplicative_arithmetic_expression> ->
<primary_arithmetic_expression> <multiplicative_arithmetic_expression_prime>
FIRST Set = {AVID_T, FPL_T, INL_T, (}
*/
void multiplicative_arithmetic_expression()
{
primary_arithmetic_expression();
multiplicative_arithmetic_expression_prime();
}
/*
* <multiplicative_arithmetic_expression_prime> ->
<primary_arithmetic_expression> <multiplicative_arithmetic_expression_prime>
FIRST Set = {*, /, E}
*/
void multiplicative_arithmetic_expression_prime()
{
if (lookahead.code == ART_OP_T &&
lookahead.attribute.arr_op != PLUS &&
lookahead.attribute.arr_op != MINUS)
{
match(lookahead.code, lookahead.attribute.arr_op);
primary_arithmetic_expression();
multiplicative_arithmetic_expression_prime();
gen_incode("PLATY: Multiplicative arithmetic expression parsed");
}
}
/*
* <opt_statements> ->
<statements> | E
FIRST Set = {AVID_T, SVID_T, IF, USING, INPUT, OUTPUT, E}
*/
void opt_statements()
{
switch (lookahead.code)
{
case KW_T:
switch (lookahead.attribute.kwt_idx)
{
case PLATYPUS:
case ELSE:
case THEN:
case REPEAT:
gen_incode("PLATY: Opt_statements parsed");
return;
}
case AVID_T:
case SVID_T:
statements();
break;
default:
gen_incode("PLATY: Opt_statements parsed");
}
}
/*
* <output_statement> ->
OUTPUT ( <output_statement_prime> );
<output_statement_prime> ->
<variable_list> | <STR_T>
FIRST(<output_statement>) = {OUTPUT}
FIRST Set = {AVID_T, SVID_T, E}
This can be done in one function
*/
void output_statement()
{
match(KW_T, OUTPUT);
match(LPR_T, NO_ATTR);
switch (lookahead.code)
{
case AVID_T:
case SVID_T:
variable_list();
break;
case STR_T:
match(STR_T, NO_ATTR);
gen_incode("PLATY: Output list (string literal) parsed");
break;
default:
gen_incode("PLATY: Output list (empty) parsed");
}
match(RPR_T, NO_ATTR);
match(EOS_T, NO_ATTR);
gen_incode("PLATY: OUTPUT statement parsed");
}
/*
* <primary_a_relational_expression> ->
AVID_T | FPL_T | INL_T
FIRST Set = {AVID_T, FPL_T, INL_T}
*/
void primary_a_relational_expression()
{
switch (lookahead.code)
{
case AVID_T:
case FPL_T:
case INL_T:
match(lookahead.code, NO_ATTR);
break;
case LOG_OP_T:
break;
default:
syn_printe();
}
gen_incode("PLATY: Primary a_relational expression parsed");
}
/*
* <primary_arithmetic_expression> ->
AVID_T | FPL_T | INL_T | ( <arithmetic_expression> )
FIRST Set = {AVID_T, FPL_T, INL_T, (}
*/
void primary_arithmetic_expression()
{
switch (lookahead.code)
{
case AVID_T:
case FPL_T:
case INL_T:
match(lookahead.code, lookahead.attribute.arr_op);
break;
case LPR_T:
match(lookahead.code, lookahead.attribute.arr_op);
arithmetic_expression();
match(RPR_T, NO_ATTR);
default:
syn_printe();
return;
}
gen_incode("PLATY: Primary arithmetic expression parsed");
}
/*
* <primary_s_relational_expression> ->
<primary_string_expression>
FIRST Set = {SVID_T, STR_T}
*/
void primary_s_relational_expression()
{
switch (lookahead.code)
{
case SVID_T:
case AVID_T:
primary_string_expression();
break;
default:
syn_printe();
}
gen_incode("PLATY: Primary s_relational expression parsed");
}
/*
* <primary_string_expression> ->
SVID_T | STR_T
FIRST Set = {SVID_T, STR_T}
*/
void primary_string_expression()
{
switch (lookahead.code)
{
case SVID_T:
case STR_T:
match(lookahead.code, NO_ATTR);
break;
default:
syn_printe();
}
gen_incode("PLATY: Primary string expression parsed");
}
/*
* <program> ->
PLATYPUS { <opt_statements> }
FIRST Set = {PLATYPUS}
*/
void program()
{
match(KW_T, PLATYPUS);
match(LBR_T, NO_ATTR);
opt_statements();
match(RBR_T, NO_ATTR);
gen_incode("PLATY: Program parsed");
}
/*
* <relational_expression> ->
<primary_a_relational_expression> <primary_a_relational_expression>
| <primary_s_relational_expression> <primary_s_relational_expression_prime>
FIRST Set = {AVID_T, FPL_T, INL_T, SVID_T, STR_T}
*/
void relational_expression()
{
switch (lookahead.code)
{
case AVID_T:
case FPL_T:
case INL_T:
primary_a_relational_expression();
relational_expression_prime();
break;
case SVID_T:
case STR_T:
primary_s_relational_expression();
relational_expression_prime_string();
break;
default:
syn_printe();
}
gen_incode("PLATY: Relational expression parsed");
}
/*
* <relational_expression_prime> ->
== <primary_a_relational_expression>
| <> <primary_a_relational_expression>
| > <primary_a_relational_expression>
| < <primary_a_relational_expression>
FIRST Set = { ==, <>, >, <}
*/
void relational_expression_prime()
{
if (lookahead.code == REL_OP_T)
{
switch (lookahead.attribute.rel_op)
{
case EQ:
case NE:
case GT:
case LT:
match(lookahead.code, lookahead.attribute.arr_op);
primary_a_relational_expression();
return;
}
}
syn_printe();
}
/*
* <relational_expression_prime_string> ->
== <primary_s_relational_expression>
| <> <primary_s_relational_expression>
| > <primary_s_relational_expression>
| < <primary_s_relational_expression>
FIRST Set = {==, <>, >, <}
*/
void relational_expression_prime_string()
{
if (lookahead.code == REL_OP_T)
{
switch (lookahead.attribute.rel_op)
{
case EQ:
case NE:
case GT:
case LT:
match(lookahead.code, lookahead.attribute.arr_op);
primary_s_relational_expression();
return;
}
}
syn_printe();
}
/*
* <selection_statement> ->
IF ( <conditional_expression> ) THEN <opt_statements> ELSE { <opt_statements> } ;
FIRST Set = {IF}
*/
void selection_statement()
{
match(KW_T, IF);
match(LPR_T, NO_ATTR);
conditional_expression();
match(RPR_T, NO_ATTR);
match(KW_T, THEN);
opt_statements();
match(KW_T, ELSE);
match(LBR_T, NO_ATTR);
opt_statements();
match(RBR_T, NO_ATTR);
match(EOS_T, NO_ATTR);
gen_incode("PLATY: IF statement parsed");
}
/*
* <statement> ->
<assignment_statement>
| <selection_statement>
| <iteration_statement>
| <input_statement>
| <output_statement>
FIRST Set = {AVID_T, SVID_T, IF, USING, INPUT, OUTPUT}
*/
void statement()
{
switch (lookahead.code)
{
case AVID_T:
case SVID_T:
assignment_statement();
break;
case KW_T:
switch (lookahead.attribute.kwt_idx)
{
case IF:
selection_statement();
break;
case USING:
iteration_statement();
break;
case INPUT:
input_statement();
break;
case OUTPUT:
output_statement();
break;
default:
syn_printe();
}
break;
default:
syn_printe();
}
}
/*
* <statements> ->
<statement> <statements_prime>
FIRST Set = {AVID_T, SVID_T, IF, USING, INPUT, OUTPUT}
*/
void statements()
{
statement();
statements_prime();
}
/*
* <statements_prime> ->
<statement> <statements_prime> | E
FIRST Set = {AVID_T, SVID_T, IF, USING, INPUT, OUTPUT}
*/
void statements_prime()
{
switch (lookahead.code)
{
case KW_T:
switch (lookahead.attribute.kwt_idx)
{
case PLATYPUS:
case ELSE:
case THEN:
case REPEAT:
return;
}
case AVID_T:
case SVID_T:
statement();
statements_prime();
break;
}
}
/*
* <string_expression> ->
<primary_string_expression> <string_expression_prime>
FIRST Set = {SVID_T, STR_T}
*/
void string_expression()
{
primary_string_expression();
string_expression_prime();
gen_incode("PLATY: String expression parsed");
}
/*
* <string_expression_prime>
<< <primary_string_expression> <stirng_expression_prime> | E
FIRST Set = {<< , E}
*/
void string_expression_prime()
{
if (lookahead.code == SCC_OP_T)
{
match(SCC_OP_T, NO_ATTR);
primary_string_expression();
string_expression_prime();
}
}
/*
* <unary_arithmetic_expression> ->
- <primary_arithmetic_expression>
| + <primary_arithmetic_expression>
FIRST Set = {-, +}
*/
void unary_arithmetic_expression()
{
/* Again, GCC complains about PLUS and MINUS enums */
switch (lookahead.code)
{
case ART_OP_T:
switch (lookahead.attribute.arr_op)
{
case MULT:
case DIV:
syn_printe();
return;
}
match(lookahead.code, lookahead.attribute.arr_op);
primary_arithmetic_expression();
gen_incode("PLATY: Unary arithmetic expression parsed");
break;
default:
syn_printe();
return;
}
}
/*
* <variable_identifier> ->
AVID_T | SVID_T
FIRST Set = {AVID_T, SVID_T}
*/
void variable_identifier()
{
switch (lookahead.code)
{
case AVID_T:
case SVID_T:
match(lookahead.code, NO_ATTR);
break;
default:
syn_printe();
}
}
/*
* <variable_list> ->
<variable_identifier> <variable_list_prime>
FIRST Set = {AVID_T, SVID_T}
*/
void variable_list()
{
variable_identifier();
variable_list_prime();
gen_incode("PLATY: Variable list parsed");
}
/*
* <variable_list_prime> ->
, <variable_identifier> <variable_list_prime> | E
FIRST Set = {AVID_T, SVID_T, E}
*/
void variable_list_prime()
{
if (lookahead.code != COM_T)
return;
match(COM_T, NO_ATTR);
variable_identifier();
variable_list_prime();
}

View File

@ -1,72 +0,0 @@
/* File Name: parser.h
* Parser function definitions for the PLATYPUS Compiler
* Author: Victor Fernandes, 040772243
* Course: CST8152 - Compilers, Lab Section: 011
* Date: April 17, 2017
* Professor: S^R
* Version: 0.1
*/
#ifndef PARSER_H_
#define PARSER_H_
#include "token.h"
#include "stable.h"
#include "buffer.h"
/* Keyword enum to match kw_table in table.h */
enum kw {
NO_ATTR = -1,
ELSE,
IF,
INPUT,
OUTPUT,
PLATYPUS,
REPEAT,
THEN,
USING
};
/* Main parser functions */
void parser(Buffer* const);
void gen_incode(char*);
void match(int, int);
void syn_eh(int);
void syn_printe(void);
/* Literally the entire grammar */
void additive_arithmetic_expression(void);
void additive_arithmetic_expression_prime(void);
void arithmetic_expression(void);
void assignment_expression(void);
void assignment_statement(void);
void conditional_expression(void);
void input_statement(void);
void iteration_statement(void);
void logical_and_expression(void);
void logical_and_expression_prime(void);
void logical_or_expression(void);
void logical_or_expression_prime(void);
void multiplicative_arithmetic_expression(void);
void multiplicative_arithmetic_expression_prime(void);
void opt_statements(void);
void output_statement(void);
void primary_a_relational_expression(void);
void primary_arithmetic_expression(void);
void primary_s_relational_expression(void);
void primary_string_expression(void);
void program(void);
void relational_expression(void);
void relational_expression_prime(void);
void relational_expression_prime_string(void);
void selection_statement(void);
void statement(void);
void statements(void);
void statements_prime(void);
void string_expression(void);
void string_expression_prime(void);
void unary_arithmetic_expression(void);
void variable_identifier(void);
void variable_list(void);
void variable_list_prime(void);
#endif

266
platy.c
View File

@ -1,266 +0,0 @@
/* File name: platy.c
* Purpose:This is the main program for Assignment#4 - Platypus Parser
* CST8152 - Compilers
* Version: 1.17.01
* Author: S^R
* Date: 18 March 2017
*/
/* The #define _CRT_SECURE_NO_WARNINGS should be used in MS Visual Studio projects
* to suppress the warnings about using "unsafe" functions like fopen()
* and standard sting library functions defined in string.h.
* The define does not have any effect in other compilers projects.
*/
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h> /* Constants for calls to exit()*/
#include <string.h>
#include <stdarg.h>
#include "buffer.h"
#include "token.h"
#include "stable.h" /*Do not remove this line. SiR */
#include "stable.h" /*Do not remove this line. SiR */
/* Input buffer parameters */
#define INIT_CAPACITY 200 /* initial buffer capacity */
#define INC_FACTOR 15 /* increment factor */
/* String Literal Table parameters */
#define STR_INIT_CAPACITY 100 /* initial string literal table capacity */
#define STR_CAPACITY_INC 50 /* initial string literal table capacity inc */
/* Symbol Table default size */
#define ST_DEF_SIZE 100
/*check for ANSI C compliancy */
#define ANSI_C 0
#if defined(__STDC__)
#undef ANSI_C
#define ANSI_C 1
#endif
/* Global objects - variables */
static Buffer *sc_buf; /* pointer to input (source) buffer */
Buffer * str_LTBL; /* this buffer implements String Literal Table */
/* it is used as a repository for string literals */
int scerrnum; /* run-time error number = 0 by default (ANSI) */
STD sym_table; /* Symbol Table Descriptor */
/*external objects */
extern int synerrno /* number of syntax errors reported by the parser */;
extern int line; /* source code line number - defined in scanner.c */
/* function declarations (prototypes) */
extern void parser(Buffer * sc_buf);
/* For testing purposes */
extern void scanner_init(Buffer * sc_buf);
/* extern Token malpar_next_token(Buffer * sc_buf);*/
void err_printf(char *fmt, ...);
void display (Buffer *ptrBuffer);
long get_filesize(char *fname);
void garbage_collect(void);
/* main function takes a PLATYPUS source file as
* an argument at the command line.
* usage: parser source_file_name [-stz size][-sts:A | -sts:D]
*/
int main(int argc, char ** argv){
FILE *fi; /* input file handle */
int loadsize = 0; /*the size of the file loaded in the buffer */
int st_def_size = ST_DEF_SIZE; /* Sumbol Table default size */
char sort_st = 0; /*Symbol Table sort switch */
int ansi_c = !ANSI_C; /* ANSI C flag */
/* Check if the compiler option is set to compile ANSI C */
/* __DATE__, __TIME__, __LINE__, __FILE__, __STDC__ are predefined preprocessor macros*/
if(ansi_c){
err_printf("Date: %s Time: %s",__DATE__, __TIME__);
err_printf("ERROR: Compiler is not ANSI C compliant!\n");
exit(1);
}
/*check for correct arrguments - source file name */
if (argc <= 1){
/* __DATE__, __TIME__, __LINE__, __FILE__ are predefined preprocessor macros*/
err_printf("Date: %s Time: %s",__DATE__, __TIME__);
err_printf("Runtime error at line %d in file %s", __LINE__, __FILE__);
err_printf("%s%s%s",argv[0],": ","Missing source file name.");
err_printf("%s%s%s","Usage: ", "parser", " source_file_name [-stz size][-sts:A | -sts:D]");
exit(EXIT_FAILURE);
}
/* check for optional switches - symbol table size and/or sort */
if (argc == 3){
if (strcmp(argv[2],"-sts:A") && strcmp(argv[2],"-sts:D") ){
err_printf("%s%s%s",argv[0],": ","Invalid switch.");
err_printf("%s%s\b\b\b\b%s","Usage: ", argv[0], " source file name [-stz size][-sts:A | -sts:D]");
exit(EXIT_FAILURE);
}
if(strcmp(argv[2],"-sts:A"))
sort_st = 'D';
else
sort_st = 'A';
}
/* symbol table size specified */
if (argc == 4){
if (strcmp(argv[2],"-stz")){
err_printf("%s%s%s",argv[0],": ","Invalid switch.");
err_printf("%s%s\b\b\b\b%s","Usage: ", argv[0], " source file name [-stz size][-sts:A | -sts:D]");
exit(EXIT_FAILURE);
}
/* convert the symbol table size */
st_def_size = atoi(argv[3]);
if (st_def_size <= 0){
err_printf("%s%s%s",argv[0],": ","Invalid switch.");
err_printf("%s%s\b\b\b\b%s","Usage: ", argv[0], " source file name [-stz size][-sts:A | -sts:D]");
exit(EXIT_FAILURE);
}
}
if (argc == 5){
if (strcmp(argv[2],"-stz")){
err_printf("%s%s%s",argv[0],": ","Invalid switch.");
err_printf("%s%s\b\b\b\b%s","Usage: ", argv[0], " source file name [-stz size][-sts:A | -sts:D]");
exit(EXIT_FAILURE);
}
/* convert the symbol table size */
st_def_size = atoi(argv[3]);
if (st_def_size <= 0){
err_printf("%s%s%s",argv[0],": ","Invalid switch.");
err_printf("%s%s\b\b\b\b%s","Usage: ", argv[0], " source file name [-stz size][-sts:A | -sts:D]");
exit(EXIT_FAILURE);
}
if (strcmp(argv[4],"-sts:A")&& strcmp(argv[4],"-sts:D") ){
err_printf("%s%s%s",argv[0],": ","Invalid switch.");
err_printf("%s%s\b\b\b\b%s","Usage: ", argv[0], " source file name [-stz size][-sts:A | -sts:D]");
exit(EXIT_FAILURE);
}
if(strcmp(argv[4],"-sts:A"))
sort_st = 'D';
else
sort_st = 'A';
}
/* create a source code input buffer - multiplicative mode */
sc_buf = b_create(INIT_CAPACITY,INC_FACTOR,'m');
if (sc_buf == NULL){
err_printf("%s%s%s",argv[0],": ","Could not create source buffer");
exit(EXIT_FAILURE);
}
/* create symbol table */
sym_table = st_create(st_def_size);
if (!sym_table.st_size){
err_printf("%s%s%s",argv[0],": ","Could not create symbol table");
exit (EXIT_FAILURE);
}
/*open source file */
if ((fi = fopen(argv[1],"r")) == NULL){
err_printf("%s%s%s%s",argv[0],": ", "Cannot open file: ",argv[1]);
exit (1);
}
/* load source file into input buffer */
printf("Reading file %s ....Please wait\n",argv[1]);
loadsize = b_load (fi,sc_buf);
if(loadsize == R_FAIL1)
err_printf("%s%s%s",argv[0],": ","Error in loading buffer.");
/* close source file */
fclose(fi);
/*find the size of the file */
if (loadsize == LOAD_FAIL){
printf("The input file %s %s\n", argv[1],"is not completely loaded.");
printf("Input file size: %ld\n", get_filesize(argv[1]));
}
/* pack and display the source buffer */
if(b_pack(sc_buf)){
display(sc_buf);
}
/* create string Literal Table */
str_LTBL = b_create(INIT_CAPACITY,INC_FACTOR,'a');
if (str_LTBL == NULL){
err_printf("%s%s%s",argv[0],": ","Could not create string buffer");
exit(EXIT_FAILURE);
}
/*registrer exit function */
atexit(garbage_collect);
/*Testbed for buffer, scanner,symbol table and parser*/
/* Initialize scanner */
scanner_init(sc_buf);
/* Add SEOF (EOF) to input buffer */
b_addc(sc_buf, EOF);
/* Start parsing */
printf("\nParsing the source file...\n\n");
parser(sc_buf);
/* print Symbol Table */
/*
if(sym_table.st_size && sort_st){
st_print(sym_table);
if(sort_st){
printf("\nSorting symbol table...\n");
st_sort(sym_table,sort_st);
st_print(sym_table);
}
}
*/
return (EXIT_SUCCESS); /* same effect as exit(0) */
}/*end of main */
/* Error printing function with variable number of arguments
*/
void err_printf( char *fmt, ... ){
va_list ap;
va_start(ap, fmt);
(void)vfprintf(stderr, fmt, ap);
va_end(ap);
/* Move to new line */
if( strchr(fmt,'\n') == NULL )
fprintf(stderr,"\n");
}
/* The function return the size of an open file
*/
long get_filesize(char *fname){
FILE *input;
long flength;
input = fopen(fname, "r");
if(input == NULL){
err_printf("%s%s","Cannot open file: ",fname);
return 0;
}
fseek(input, 0L, SEEK_END);
flength = ftell(input);
fclose(input);
return flength;
}
/* The function display buffer contents
*/
void display (Buffer *ptrBuffer){
printf("\nPrinting input buffer parameters:\n\n");
printf("The capacity of the buffer is: %d\n",b_capacity(ptrBuffer));
printf("The current size of the buffer is: %d\n",b_size(ptrBuffer));
printf("\nPrinting input buffer contents:\n\n");
b_print(ptrBuffer);
}
/* the functions frees the allocated memory */
void garbage_collect(void){
if(synerrno)
printf("\nSyntax errors: %d\n",synerrno);
printf("\nCollecting garbage...\n");
b_free(sc_buf);
b_free(str_LTBL);
st_destroy(sym_table);
}

View File

@ -1,7 +1,7 @@
/* File name: platy_bt.c
* Purpose:This is the main program for Assignment #1, CST8152, Winter 17
* Version: 1.17.1
* Author: S^R
* Author: Svillen Ranev
* Date: 9 January 2017
*/

View File

@ -2,7 +2,7 @@
* Purpose:This is the main program for Assignment #2 - Scanner
* CST8152 - Compilers
* Version: 1.17.1
* Author: S^R
* Author: Svillen Ranev
* Date: 30 January 2017
*/
@ -201,10 +201,10 @@ void print_token(Token t){
printf("SEOF_T\n" );
break;
case AVID_T:
printf("AVID_T\t\t%d\n",t.attribute.vid_offset);
printf("AVID_T\t\t%s\n",t.attribute.vid_lex);
break;
case SVID_T:
printf("SVID_T\t\t%d\n",t.attribute.vid_offset);
printf("SVID_T\t\t%s\n",t.attribute.vid_lex);
break;
case FPL_T:
printf("FPL_T\t\t%f\n",t.attribute.flt_value);

View File

@ -1,275 +0,0 @@
/* File name: platy_tt.c
* Purpose:This is the main program for Assignment #3 - Symbol Table
* CST8152 - Compilers
* Version: 1.17.01
* Author: S^R
* Date: 1 March 2017
*/
/* The #define _CRT_SECURE_NO_WARNINGS should be used in MS Visual Studio projects
* to suppress the warnings about using "unsafe" functions like fopen()
* and standard sting library functions defined in string.h.
* The define does not have any effect in other compiler projects.
*/
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h> /* Constants for calls to exit()*/
#include <string.h>
#include <stdarg.h>
#include "buffer.h"
#include "token.h"
#include "stable.h" /*Do not remove this line. SiR */
/* constant definitions */
/* Input buffer parameters */
#define INIT_CAPACITY 200 /* initial buffer capacity */
#define INC_FACTOR 15 /* increment factor */
/* String Literal Table parameters */
#define STR_INIT_CAPACITY 100 /* initial string literal table capacity */
#define STR_CAPACITY_INC 50 /* initial string literal table capacity inc */
/* Symbol Table default size */
#define ST_DEF_SIZE 100
/*check for ANSI C compliancy */
#define ANSI_C 0
#if defined(__STDC__)
#undef ANSI_C
#define ANSI_C 1
#endif
/* Global objects - variables */
static Buffer *sc_buf; /* pointer to input (source) buffer */
Buffer * str_LTBL; /* this buffer implements String Literal Table */
/* it is used as a repository for string literals */
int scerrnum; /* run-time error number = 0 by default (ANSI) */
STD sym_table; /* Symbol Table Descriptor */
/*external objects */
extern int line; /* source code line numbers - defined in scanner.c */
extern int scanner_init(Buffer * sc_buf);
extern Token malar_next_token(Buffer * sc_buf);
/*function declarations */
void err_printf(char *fmt, ...);
void display (Buffer *ptrBuffer);
long get_filesize(char *fname);
void garbage_collect(void);
/* The main function takes a PLATYPUS source file and optional switches
* as command line arguments.
* usage: stable source_file_name [-stz size][-sts:A | -sts:D]
*/
int main(int argc, char ** argv){
FILE *fi; /* input file handle */
Token t; /* token produced by the scanner */
int loadsize = 0; /*the size of the file loaded in the buffer */
int st_def_size = ST_DEF_SIZE; /* Sumbol Table default size */
char sort_st = 0; /*Symbol Table sort switch */
int ansi_c = !ANSI_C; /* ANSI C flag */
/* Check if the compiler option is set to compile ANSI C */
/* __DATE__, __TIME__, __LINE__, __FILE__, __STDC__ are predefined preprocessor macros*/
if(ansi_c){
err_printf("Date: %s Time: %s",__DATE__, __TIME__);
err_printf("ERROR: Compiler is not ANSI C compliant!\n");
exit(1);
}
/*check for correct arrguments - source file name */
if (argc <= 1){
/* __DATE__, __TIME__, __LINE__, __FILE__ are predefined preprocessor macros*/
err_printf("Date: %s Time: %s",__DATE__, __TIME__);
err_printf("Runtime error at line %d in file %s", __LINE__, __FILE__);
err_printf("%s%s%s",argv[0],": ","Missing source file name.");
err_printf("%s%s%s","Usage: ", "stable", " source_file_name [-stz size][-sts:A | -sts:D]");
exit(EXIT_FAILURE);
}
/* check for optional switches - symbol table size and/or sort */
if (argc == 3){
if (strcmp(argv[2],"-sts:A") && strcmp(argv[2],"-sts:D") ){
err_printf("%s%s%s",argv[0],": ","Invalid switch.");
err_printf("%s%s\b\b\b\b%s","Usage: ", argv[0], " source file name [-stz size][-sts:A | -sts:D]");
exit(EXIT_FAILURE);
}
/*set sort switch*/
if(strcmp(argv[2],"-sts:A"))
sort_st = 'D';
else
sort_st = 'A';
}
/* symbol table size specified */
if (argc == 4){
if (strcmp(argv[2],"-stz")){
err_printf("%s%s%s",argv[0],": ","Invalid switch.");
err_printf("%s%s\b\b\b\b%s","Usage: ", argv[0], " source file name [-stz size][-sts:A | -sts:D]");
exit(EXIT_FAILURE);
}
/* convert the symbol table size */
st_def_size = atoi(argv[3]);
if (st_def_size <= 0){
err_printf("%s%s%s",argv[0],": ","Invalid switch.");
err_printf("%s%s\b\b\b\b%s","Usage: ", argv[0], " source file name [-stz size][-sts:A | -sts:D]");
exit(EXIT_FAILURE);
}
}
if (argc == 5){
if (strcmp(argv[2],"-stz")){
err_printf("%s%s%s",argv[0],": ","Invalid switch.");
err_printf("%s%s\b\b\b\b%s","Usage: ", argv[0], " source file name [-stz size][-sts:A | -sts:D]");
exit(EXIT_FAILURE);
}
/* convert the symbol table size */
st_def_size = atoi(argv[3]);
if (st_def_size <= 0){
err_printf("%s%s%s",argv[0],": ","Invalid switch.");
err_printf("%s%s\b\b\b\b%s","Usage: ", argv[0], " source file name [-stz size][-sts:A | -sts:D]");
exit(EXIT_FAILURE);
}
if (strcmp(argv[4],"-sts:A")&& strcmp(argv[4],"-sts:D") ){
err_printf("%s%s%s",argv[0],": ","Invalid switch.");
err_printf("%s%s\b\b\b\b%s","Usage: ", argv[0], " source file name [-stz size][-sts:A | -sts:D]");
exit(EXIT_FAILURE);
}
if(strcmp(argv[4],"-sts:A"))
sort_st = 'D';
else
sort_st = 'A';
}
/* create a source code input buffer - multiplicative mode */
sc_buf = b_create(INIT_CAPACITY,INC_FACTOR,'m');
if (sc_buf == NULL){
err_printf("%s%s%s",argv[0],": ","Could not create source buffer");
exit(EXIT_FAILURE);
}
/* create symbol table */
sym_table = st_create(st_def_size);
if (!sym_table.st_size){
err_printf("%s%s%s",argv[0],": ","Could not create symbol table");
exit (EXIT_FAILURE);
}
/*open source file */
if ((fi = fopen(argv[1],"r")) == NULL){
err_printf("%s%s%s%s",argv[0],": ", "Cannot open file: ",argv[1]);
exit (1);
}
/* load source file into input buffer */
printf("Reading file %s ....Please wait\n",argv[1]);
loadsize = b_load (fi,sc_buf);
if(loadsize == R_FAIL1)
err_printf("%s%s%s",argv[0],": ","Error in loading buffer.");
/* close source file */
fclose(fi);
/*find the size of the file */
if (loadsize == LOAD_FAIL){
printf("The input file %s %s\n", argv[1],"is not completely loaded.");
printf("Input file size: %ld\n", get_filesize(argv[1]));
}
/* pack and display the source buffer */
if(b_pack(sc_buf)){
display(sc_buf);
}
/* create string Literal Table */
str_LTBL = b_create(INIT_CAPACITY,INC_FACTOR,'a');
if (str_LTBL == NULL){
err_printf("%s%s%s",argv[0],": ","Could not create string buffer");
exit(EXIT_FAILURE);
}
/*registrer exit function */
atexit(garbage_collect);
/*Testbed for the scanner and the symbol table*/
/* add SEOF to input program buffer*/
b_addc(sc_buf,'\0');
/* Initialize the scanner*/
if(scanner_init(sc_buf)){;
err_printf("%s%s%s",argv[0],": ","Empty program buffer - scanning canceled");
exit(1);
}
printf("Scanning source file...\n\n");
do{
t= malar_next_token(sc_buf);
}while(t.code != SEOF_T);
/* print Symbol Table */
if(sym_table.st_size){
st_print(sym_table);
if(sort_st){
printf("\nSorting symbol table...\n");
st_sort(sym_table,sort_st);
st_print(sym_table);
}
}
/*Test bed for type and update functions */
/*Test bed for bonus*/
return (0); /* same effect as exit(EXIT_SUCCESS) */
}
/* Error printing function with variable number of arguments
*/
void err_printf( char *fmt, ... ){
va_list ap;
va_start(ap, fmt);
(void)vfprintf(stderr, fmt, ap);
va_end(ap);
/* Move to new line */
if( strchr(fmt,'\n') == NULL )
fprintf(stderr,"\n");
}
/* The function return the size of an open file
*/
long get_filesize(char *fname){
FILE *input;
long flength;
input = fopen(fname, "r");
if(input == NULL){
err_printf("%s%s","Cannot open file: ",fname);
return 0;
}
fseek(input, 0L, SEEK_END);
flength = ftell(input);
fclose(input);
return flength;
}
/* The function display buffer contents
*/
void display (Buffer *ptrBuffer){
printf("\nPrinting input buffer parameters:\n\n");
printf("The capacity of the buffer is: %d\n",b_capacity(ptrBuffer));
printf("The current size of the buffer is: %d\n",b_size(ptrBuffer));
printf("The reallocation flag is: %d\n",b_rflag(ptrBuffer));
printf("\nPrinting input buffer contents:\n\n");
b_print(ptrBuffer);
}
/* The function frees all dynamically allocated memory.
This function is always called
despite how the program terminates - normally or abnormally.
*/
void garbage_collect(void){
printf("\nCollecting garbage...\n");
b_free(sc_buf);
b_free(str_LTBL);
st_destroy(sym_table);
}

View File

@ -5,7 +5,7 @@
* scanner_init() must be called before using the scanner.
* The file is incomplete;
* Author: Victor Fernandes, 040772243
* Provided by: S^R
* Provided by: Svillen Ranev
* Version: 1.17.1
* Date: 30 January 2017
* Function list: scanner_init, malar_next_token, get_next_state, char_class,
@ -32,7 +32,6 @@
/* project header files */
#include "buffer.h"
#include "token.h"
#include "stable.h"
#include "table.h"
#define DEBUG /* for conditional processing */
@ -45,8 +44,8 @@
It is defined in platy_st.c */
extern Buffer * str_LTBL; /*String literal table */
int line; /* current line number of the source code */
extern int synerrno; /* defined in platy_st.c - run-time error number */
extern STD sym_table; /* symbol table */
extern int scerrnum; /* defined in platy_st.c - run-time error number */
/* Local(file) global objects - variables */
static Buffer *lex_buf; /*pointer to temporary lexeme buffer*/
@ -74,7 +73,7 @@ int scanner_init(Buffer * sc_buf) {
b_reset(str_LTBL);
line = 1;
return EXIT_SUCCESS;/*0*/
/* synerrno = 0; *//*no need - global ANSI C */
/* scerrnum = 0; *//*no need - global ANSI C */
}
/* Reads the source code buffer and generates a token
* Author: Victor Fernandes
@ -107,8 +106,7 @@ Token malar_next_token(Buffer * sc_buf)
pBuffer err_lex_buf;
if (sc_buf == NULL) {
synerrno
= 1;
scerrnum = 1;
return aa_table[ES]("RUN TIME ERROR: "); /* WHOOPS */
}
@ -176,7 +174,7 @@ Token malar_next_token(Buffer * sc_buf)
if (c == '<') { /* It's a comment line */
/* Consume chars until line ends */
for (; c != '\0' && c != '\r' && c != '\n' && c != 255; c = b_getc(sc_buf));
++line;
line++;
continue;
}
else { /* Bad character, pump out an error token */
@ -188,7 +186,6 @@ Token malar_next_token(Buffer * sc_buf)
t.attribute.err_lex[2] = '\0';
/* Consume the rest of the caracters to ignore the line*/
for (; c != '\0' && c != '\r' && c != '\n' && c != 255; c = b_getc(sc_buf));
++line;
return t;
}
case '=':
@ -268,7 +265,7 @@ Token malar_next_token(Buffer * sc_buf)
b_retract_to_mark(sc_buf);
lex_buf = b_create(20, 8, 'a');
lex_buf = b_create(1, 1, 'a');
/* Copy the scanned lexeme into lexical buffer */
for (; lexstart < lexend; ++lexstart) {
@ -280,8 +277,7 @@ Token malar_next_token(Buffer * sc_buf)
t = aa_table[state](b_setmark(lex_buf, 0));
}
else {
synerrno
= 1;
scerrnum = 1;
t = aa_table[ES]("RUN TIME ERROR: ");
return t;
}
@ -374,10 +370,9 @@ int char_class(char c)
Return values: Token
*/
Token aa_func02(char lexeme[]) {
unsigned kw_idx, offset; /* Variable to contain keyword table index */
unsigned int i, kw_idx; /* Variable to contain keyword table index */
Token t;
char v_type;
/*char* temp_str;*/
char* temp_str;
#ifdef DEBUG
printf("Lexeme: '%s'\n", lexeme);
@ -392,11 +387,17 @@ Token aa_func02(char lexeme[]) {
/* Not a keyword? Must be AVID*/
t.code = AVID_T;
/*if ((temp_str = (char*)calloc(VID_LEN + 1, sizeof(char))) == NULL) {
if ((temp_str = (char*)calloc(VID_LEN + 1, sizeof(char))) == NULL) {
return aa_table[ES]("RUN TIME ERROR: ");
}
strncpy(temp_str, lexeme, VID_LEN);*/
for (i = 0; i < (VID_LEN) && i < strlen(lexeme); i++) {
temp_str[i] = lexeme[i];
}
strncpy(t.attribute.vid_lex, temp_str, VID_LEN);
t.attribute.vid_lex[strlen(temp_str)] = '\0';
free(temp_str);
switch (lexeme[0]) { /* Read first character of lexeme for implicit type (not used yet?)*/
case 'i':
@ -404,21 +405,11 @@ Token aa_func02(char lexeme[]) {
case 'd':
case 'n':
/* Integer */
v_type = 'I';
break;
default:
/* Floating point*/
v_type = 'F';
break;
}
if ((offset = st_install(sym_table, lexeme, v_type, line)) == -1){
printf("Error: Install failed - Symbol Table is full.\n");
st_store(sym_table);
free(lexeme);
exit(1);
}
t.attribute.vid_offset = offset;
/*free(temp_str);*/
return t;
}
@ -433,25 +424,24 @@ Token aa_func02(char lexeme[]) {
*/
Token aa_func03(char lexeme[]) {
Token t;
unsigned offset;/*
unsigned int i;
char* temp_str;
if ((temp_str = (char*)calloc(VID_LEN + 2, sizeof(char))) == NULL) {
return aa_table[ES]("RUN TIME ERROR: ");
}*/
/*strncpy(temp_str, lexeme, VID_LEN);*/
lexeme[strlen(lexeme) - 1] = '#'; /* Add # to end of the SVID */
if ((offset = st_install(sym_table, lexeme, 'S', line)) == -1){
printf("Error: Install failed - Symbol Table is full.\n");
st_store(sym_table);
free(lexeme);
exit(1);
}
t.code = SVID_T;
t.attribute.vid_offset = offset;
/*free(temp_str);*/
for (i = 0; i < (VID_LEN) && i < strlen(lexeme); i++) {
temp_str[i] = lexeme[i];
}
temp_str[strlen(temp_str) - 1] = '#'; /* Add# to end of the SVID */
temp_str[strlen(temp_str)] = '\0';
strncpy(t.attribute.vid_lex, temp_str, VID_LEN);
t.attribute.vid_lex[strlen(temp_str)] = '\0';
free(temp_str);
t.code = SVID_T;
return t;
}
@ -520,7 +510,7 @@ Token aa_func10(char lexeme[]) {
t.code = INL_T;
new_olval = atool(lexeme);
if (new_olval < 0 || new_olval > PLT_SHRT_MAX) {
if (new_olval < 0 || new_olval > 32767) {
t = aa_table[ES](lexeme);
return t;
}
@ -559,12 +549,11 @@ Token aa_func12(char lexeme[]) {
*/
Token aa_func13(char lexeme[]) {
Token t;
unsigned int i = strlen(lexeme);
unsigned int i;
t.code = ERR_T;
/*
for (i = 0; i < (ERR_LEN) && i < strlen(lexeme); i++)
t.attribute.err_lex[i] = lexeme[i];
*/
if (strlen(lexeme) > ERR_LEN) {
t.attribute.err_lex[i - 1] = '.';
t.attribute.err_lex[i - 2] = '.';

382
stable.c
View File

@ -1,382 +0,0 @@
/* Filename: stable.c
* Compiler: msvc (Visual Studio 2015)
* Store and provide functions for the symbol table database
* CST8152, Assignment #3
* Professor: S^R
* Author: Victor Fernandes, 040772243
* Version: 0.1
* Date: 24 March 2017
*/
#include "stable.h"
#define PLSBD_SZ 128
#define PLSBD_INC 64
#define DEBUG
#undef DEBUG
/* Forward function declarations */
static void st_setsize(void);
static void st_incoffset(void);
extern STD sym_table;
/* Create a symbol table
* Author: Victor Fernandes, 040772243
* Version: 0.0.1
* Called functions: malloc, b_create, free
* Parameters:
int - size of the symbol table
* Return value:
STD - The symbol table
* Algorithm:
*/
STD st_create(int st_size) {
STD new_stable;
new_stable.plsBD = NULL;
new_stable.pstvr = (STVR*)malloc((size_t)st_size * sizeof(STVR));
if (st_size <= 0 || (new_stable.pstvr == NULL)) {
new_stable.st_size = 0;
}
new_stable.plsBD = b_create(PLSBD_SZ, PLSBD_INC, 'a');
if (new_stable.plsBD == NULL) {
free(new_stable.plsBD);
new_stable.st_size = 0;
}
new_stable.st_size = st_size;
new_stable.st_offset = 0;
return new_stable;
}
/* Install a new entry in the symbol table
* Author: Victor Fernandes, 040772243
* Version: 0.0.1
* Called functions: st_lookup, b_setmark, b_size, b_addc, b_rflag, st_incoffset
* Parameters:
STD - The symbol table
char - The lexeme to be stored
char - the type of the lexeme
int - the line in the source file where the lexeme was found
* Return value:
int - the element offset of where the symbol table is pointing to
-1 if an internal error occurs
* Algorithm:
*/
int st_install(STD s_table, char *lexeme, char type, int line) {
int offset = -1, i, j, lex_len, lex_offset = 0, flag = 0;
/* Cannot add new entry, table full */
if (s_table.st_offset >= s_table.st_size)
return -1;
/* Look for an existing entry in the symbol table */
if (s_table.st_offset > 0)
offset = st_lookup(s_table, lexeme);
if (offset > -1)
return offset;
/* Add lexeme to the symbol table's lexeme buffer */
lex_len = strlen(lexeme);
for (i = 0; i <= lex_len; ++i) {
if (!b_addc(s_table.plsBD, lexeme[i]))
return -1;
if (b_rflag(s_table.plsBD) == SET_R_FLAG) { /* Trigger reassignment loop once lexeme is stored */
flag = 1;
}
}
/* If reallocation happened...*/
if (flag == 1) {
for (j = 0; j < s_table.st_offset; ++j) {
s_table.pstvr[j].plex = b_setmark(s_table.plsBD, (short) s_table.pstvr[j].i_value.str_offset);
}
}
/* Set proper pointer values on symbol table */
/* Get buffer offset location of the lexeme stored */
lex_offset = b_size(s_table.plsBD) - (strlen(lexeme) + 1);
s_table.pstvr[s_table.st_offset].plex = b_setmark(s_table.plsBD, (short) lex_offset);
s_table.pstvr[s_table.st_offset].o_line = line;
s_table.pstvr[s_table.st_offset].i_value.str_offset = lex_offset;
/* Set the default mask before setting the rest of the masks */
s_table.pstvr[s_table.st_offset].status_field = DFT_MASK;
switch (type) {
case 'I': /* Integer type */
s_table.pstvr[s_table.st_offset].status_field |= INT_MASK;
s_table.pstvr[s_table.st_offset].i_value.int_val = 0;
break;
case 'F': /* Floating point type */
s_table.pstvr[s_table.st_offset].status_field |= FLT_MASK;
s_table.pstvr[s_table.st_offset].i_value.fpl_val = 0.0f;
break;
case 'S': /* String type */
s_table.pstvr[s_table.st_offset].status_field |= STR_MASK;
s_table.pstvr[s_table.st_offset].i_value.int_val = -1;
s_table.pstvr[s_table.st_offset].i_value.fpl_val = -1.0f;
break;
default:
return -1; /* Not supposed to fall into here */
}
/* Increment the symbol table offset */
st_incoffset();
return s_table.st_offset;
}
/* Look up the lexeme string in the symbol table's buffer
* Author: Victor Fernandes
* Version: 0.1
* Called functions: b_setmark, strcmp, strlen
* Parameters:
STD - The symbol table
char - The lexeme to be searched
* Return value:
int - the element offset index in the symbol table
-1 if no element was found
*/
int st_lookup(STD s_table, char *lexeme) {
int i; /* idx: index location for symbol table, i: increment counter*/
#ifdef DEBUG
printf("Looking up %s...", lexeme);
#endif
for (i = s_table.st_offset - 1; i >= 0; --i) {
if (strcmp(lexeme, s_table.pstvr[i].plex) == 0) {
#ifdef DEBUG
printf("YES\n");
#endif
return i;
}
}
#ifdef DEBUG
printf("NO\n");
#endif
return -1; /* Found nothing */
}
/* Change the data type indicator of the variable entry located in vid_offset.
* Author: Victor Fernandes
* Version: 0.1
* Called functions: N/A
* Parameters:
STD - The symbol table
int - the offset location of the VID
char - the new type of the VID
* Return value:
1 if change successful, -1 if no change was made or internal error
*/
int st_change_type(STD s_table, int vid_offset, char v_type) {
/* Do nothing if update flag has already been set */
if ((s_table.pstvr[vid_offset].status_field & U_MASK)) return -1;
/* Reset to new type with default mask and update flag
Note: Can separate the statements to set the update flag at the
end, but this resets AND updates at once
*/
/*sym_table.pstvr[vid_offset].status_field = sym_table.pstvr[vid_offset].status_field & DFT_U_MASK;*/
s_table.pstvr[vid_offset].status_field &= DFT_U_MASK;
switch (v_type) {
case 'I': /* Integer type */
s_table.pstvr[vid_offset].status_field |= INT_MASK;
break;
case 'F': /* Floating point type */
s_table.pstvr[vid_offset].status_field |= FLT_MASK;
break;
case 'S': /* String type, do nothing as it cannot be changed */
break;
default:
return -1; /* Not supposed to fall into here */
}
return 1;
}
/* Change the i_value of the variable located by vid_offset to new Value
* Author: Victor Fernandes, 040772243
* Version: 0.0.1
* Called functions: N/A
* Parameters:
STD - The symbol table
int - the offset location of the VID
Value - the new value of the VID
* Return value: the offset location of the VID
*/
int st_change_value(STD s_table, int vid_offset, Value value) {
s_table.pstvr[vid_offset].i_value = value;
return vid_offset;
}
/* Get the type of the variable specified by vid_offset
* Author: Victor Fernandes, 040772243
* Version: 0.0.1
* Called functions: N/A
* Parameters:
STD - The symbol table
int - the offset of the VID in the table
* Return value:
char - the type of the VID ('I','F', or 'S')
-1 if there is an invalid value set
*/
char st_get_type(STD s_table, int vid_offset) {
unsigned short mask;
mask = s_table.pstvr[vid_offset].status_field & CHK_MASK;
switch (mask) {
case INT_MASK:
return 'I';
case FLT_MASK:
return 'F';
case STR_MASK:
return 'S';
default:
return -1; /* Not supposed to fall into here */
}
}
/* Return the i_value of the variable specified by vid_offset
* Author: Victor Fernandes, 040772243
* Version: 0.0.1
* Called functions:
* Parameters:
STD - The symbol table
int - the offset of the VID in the table
* Return value:
Value - the value of the VID
Incorrect parameters will cause undefined behaviour
*/
Value st_get_value(STD s_table, int vid_offset) {
return s_table.pstvr[vid_offset].i_value;
}
/* Free memory used by the symbol table
* Author: Victor Fernandes, 040772243
* Version: 0.0.1
* Called functions: free, b_free
* Parameters:
STD - The symbol table
*/
void st_destroy(STD s_table) {
if (s_table.pstvr != NULL) {
free(s_table.pstvr);
s_table.pstvr = NULL;
}
b_free(s_table.plsBD);
}
/* Print the contents of the symbol table to standard output
* Author: Victor Fernandes, 040772243
* Version: 0.0.1
* Called functions: printf
* Parameters:
STD - The symbol table
* Return value:
int - the number of items printed to stdout
*/
int st_print(STD s_table) {
int i;
if (s_table.st_size <= 0) return -1;
printf("Symbol Table\n____________\nLine Number\tVariable Identifier\n");
for (i = 0; i <= s_table.st_offset - 1 ; ++i)
printf("%2d\t\t%s\n", s_table.pstvr[i].o_line, s_table.pstvr[i].plex);
return i;
}
/* Store the symbol table to a file named $stable.ste.
It overwrites any existing file named $stable.ste.
* Author: Victor Fernandes, 040772243
* Version: 0.0.1
* Called functions: fopen, fprintf, st_get_type, fclose, printf
* Parameters:
STD - The symbol table
* Return value:
int - the number of items stored
-1 if the file stream cannot be opened
*/
int st_store(STD s_table) {
FILE *out; /* The target file*/
int i;
/* Windows does not like fopen, and fopen_s is Windows-only. This will ensure the
* use of the proper function call if PLATYPUS is being built on a non-windows system.
* Best approach is to add _CRT_SECURE_NO_WARNINGS to the preprocessor definitions, but
* this works, too.
*/
#ifdef _WIN32
if (fopen_s(&out, ST_FILE_NAME, "w+") != 0 || out == NULL)
#else
if ((out = fopen(ST_FILE_NAME, "w+")) == NULL)
#endif
return -1; /* Can't open file, stop. */
fprintf(out, "%d", s_table.st_size);
for (i = 0; i < s_table.st_offset; ++i) {
fprintf(out, " %4X %d %s %d",
s_table.pstvr[i].status_field, /* Status flag */
(int)strlen(s_table.pstvr[i].plex), /* Length of lexeme */
s_table.pstvr[i].plex, /* The lexeme itself */
s_table.pstvr[i].o_line); /* Line number */
/* Initial value */
char type = st_get_type(s_table, i);
switch (type) {
case 'I':
case 'F':
case 'S':
fprintf(out, " %c", type);
}
}
fclose(out);
printf("Symbol Table stored\n");
return i;
}
/* Internal function to set the table size to 0.
* Author: Victor Fernandes, 040772243
* Version: 0.0.1
* Called functions: N/A
* Parameters: N/A
* Return value: N/A
*/
static void st_setsize(void) {
sym_table.st_size = 0;
}
/* Internal function to increment st_offset by 1.
* Author: Victor Fernandes, 040772243
* Version: 0.0.1
* Called functions: N/A
* Parameters: N/A
* Return value: N/A
*/
static void st_incoffset(void) {
++sym_table.st_offset;
}
/* Sorts the table by variable name in ascending/descending order
* Author: Victor Fernandes, 040772243
* Version: 0.0.1
* Called functions:
* Parameters:
* Return value:
* Algorithm:
*/
int st_sort(STD s_table, char s_order) {
/* Compiler warning about unused parameters,
* this is fine for this dummy method
*/
return 0; /* SYKE! */
}

View File

@ -1,66 +0,0 @@
/* Filename: stable.h
* Compiler: msvc (Visual Studio 2015)
* Function declarations for the symbol table
* CST8152, Assignment #3
* Professor: S^R
* Author: Victor Fernandes, 040772243
* Version: 0.1
* Date: 24 March 2017
*/
#ifndef STABLE_H_
#define STABLE_H_
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "buffer.h"
/* Masks
16-bit field MSB-> 15 14 13 12 | 11 10 9 8 | 7 6 5 4 | 3 2 1 0 <-LSB
0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0
*/
#define DFT_MASK 0xFFF8 /* Default mask */
#define U_MASK 0x0001 /* Update mask */
#define INT_MASK 0x0004 /* Integer mask */
#define FLT_MASK 0x0002 /* Floating point mask */
#define STR_MASK 0x0006 /* String mask*/
#define CHK_MASK 0x0006 /* Type check mask */
#define DFT_U_MASK 0xFFF9 /* Default mask with update flag */
#define ST_FILE_NAME "$stable.ste"
typedef union InitialValue {
int int_val; /* Integer variable initial value */
float fpl_val; /* Floating-point variable initial value */
int str_offset; /* String variable initial value (location offset) */
} Value;
typedef struct SymbolTableVidRecord {
unsigned short status_field; /* Variable record status field */
char *plex; /* Pointer to lexeme (VID name) in CA (character array) */
int o_line; /* Line of first occurence */
Value i_value; /* Variable initial value */
void *reserved; /* Reserved for future use, not needed right now */
} STVR;
typedef struct SymbolTableDescriptor {
STVR *pstvr; /* Pointer to array of STVR */
int st_size; /* Size in number of STVR elements */
int st_offset; /* Offset in number of STVR elements */
Buffer *plsBD; /* Pointer to the lexeme storage buffer descriptor */
} STD;
STD st_create(int);
int st_install(STD, char*, char, int);
int st_lookup(STD, char*);
int st_change_type(STD, int, char);
int st_change_value(STD, int, Value);
char st_get_type(STD, int);
Value st_get_value(STD, int);
void st_destroy(STD);
int st_print(STD);
int st_store(STD);
int st_sort(STD, char);
#endif

114
table.h
View File

@ -4,7 +4,7 @@
* Author: Victor Fernandes, 040772243
* Version: 1.17.1
* Date: 30 January 2017
* Provided by: S^R
* Provided by: Svillen Ranev
*/
#ifndef TABLE_H_
@ -38,31 +38,29 @@
#define ESWR 13 /* Error state (no retract) */
#define IS -1 /* Invalid state */
/*Avoid platform dependency and use fixed 2-byte short */
#define PLT_SHRT_MAX 32767
/* State transition table definition */
#define TABLE_COLUMNS 7
/*transition table - type of states defined in separate table */
int st_table[][TABLE_COLUMNS] = {
/* INPUT COLUMNS:
COLUMN # | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
|[a-zA-Z]| 0 |[1-7]|[8-9]| . | # | other |
*/
/* State 0 */ {1, 6 , 4 , 4 , IS , IS , IS},
/* State 1 */ {1, 1 , 1 , 1 , 2 , 3 , 2 },
/* State 2 */ {IS, IS , IS, IS, IS , IS , IS},
/* State 3 */ {IS, IS , IS, IS, IS , IS , IS},
/* State 4 */ {ES, 4 , 4 , 4 , 7 , 5 , 5 },
/* State 5 */ {IS, IS , IS, IS, IS , IS , IS},
/* State 6 */ {ES, 9 , 9 , ES, 7 , ES , 5 },
/* State 7 */ {8 , 7 , 7 , 7, 8 , 8 , 8 },
/* State 8 */ {IS, IS , IS, IS, IS , IS , IS},
/* State 9 */ {ES, 9 , 11, ES, ES , ES , 10},
/* State 10 */ {IS, IS , IS, IS, IS , IS , IS},
/* State 11 */ {ES, 11 , 11, ES, ES , ES , 10},
/* State 12 */ {IS, IS , IS, IS, IS , IS , IS},
/* State 13 */ {IS, IS , IS, IS, IS , IS , IS}
/* INPUT COLUMNS:
COLUMN # | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
|[a-zA-Z]| 0 |[1-7]|[8-9]| . | # | other |
*/
/* State 0 */ {1, 6 , 4 , 4 , ES , ES , ES},
/* State 1 */ {1, 1 , 1 , 1 , 2 , 3 , 2 },
/* State 2 */ {IS, IS , IS, IS, IS , IS , IS},
/* State 3 */ {IS, IS , IS, IS, IS , IS , IS},
/* State 4 */ {ES, 4 , 4 , 4 , 7 , 5 , 5 },
/* State 5 */ {IS, IS , IS, IS, IS , IS , IS},
/* State 6 */ {ES, 9 , 9 , ES, 7 , ES , 5 },
/* State 7 */ {8 , 7 , 7 , 7, 8 , 8 , 8 },
/* State 8 */ {IS, IS , IS, IS, IS , IS , IS},
/* State 9 */ {ES, ES , 11, ES, ES , ES , 10},
/* State 10 */ {IS, IS , IS, IS, IS , IS , IS},
/* State 11 */ {ES, 11 , 11, ES, ES , ES , 10},
/* State 12 */ {IS, IS , IS, IS, IS , IS , IS},
/* State 13 */ {IS, IS , IS, IS, IS , IS , IS}
};
/* Accepting state table definition */
@ -72,20 +70,20 @@ int st_table[][TABLE_COLUMNS] = {
int as_table[] = {
/* State 0 */ NOAS,
/* State 1 */ NOAS,
/* State 2 */ ASWR,
/* State 3 */ ASNR,
/* State 4 */ NOAS,
/* State 5 */ ASWR,
/* State 6 */ NOAS,
/* State 7 */ NOAS,
/* State 8 */ ASWR,
/* State 9 */ NOAS,
/* State 10 */ ASWR,
/* State 11 */ NOAS,
/* State 12 */ ASNR,
/* State 13 */ ASWR
/* State 0 */ NOAS,
/* State 1 */ NOAS,
/* State 2 */ ASWR,
/* State 3 */ ASNR,
/* State 4 */ NOAS,
/* State 5 */ ASWR,
/* State 6 */ NOAS,
/* State 7 */ NOAS,
/* State 8 */ ASWR,
/* State 9 */ NOAS,
/* State 10 */ ASWR,
/* State 11 */ NOAS,
/* State 12 */ ASNR,
/* State 13 */ ASWR
};
@ -113,21 +111,21 @@ typedef Token(*PTR_AAF)(char *lexeme);
PTR_AAF aa_table[] = {
/* State 0 */ NULL,
/* State 1 */ NULL,
/* State 2 */ aa_func02,
/* State 3 */ aa_func03,
/* State 4 */ NULL,
/* State 5 */ aa_func05,
/* State 6 */ NULL,
/* State 7 */ NULL,
/* State 8 */ aa_func08,
/* State 9 */ NULL,
/* State 10 */ aa_func10,
/* State 11 */ NULL,
/* State 12 */ aa_func12,
/* State 13 */ aa_func13
/* State 0 */ NULL,
/* State 1 */ NULL,
/* State 2 */ aa_func02,
/* State 3 */ aa_func03,
/* State 4 */ NULL,
/* State 5 */ aa_func05,
/* State 6 */ NULL,
/* State 7 */ NULL,
/* State 8 */ aa_func08,
/* State 9 */ NULL,
/* State 10 */ aa_func10,
/* State 11 */ NULL,
/* State 12 */ aa_func12,
/* State 13 */ aa_func13
};
/* Keyword lookup table (.AND. and .OR. are not keywords) */
@ -135,14 +133,14 @@ PTR_AAF aa_table[] = {
#define KWT_SIZE 8
char * kw_table[] = {
"ELSE",
"IF",
"INPUT",
"OUTPUT",
"PLATYPUS",
"REPEAT",
"THEN",
"USING"
"ELSE",
"IF",
"INPUT",
"OUTPUT",
"PLATYPUS",
"REPEAT",
"THEN",
"USING"
};
#endif

View File

@ -12,7 +12,7 @@
*/
### FUNCTION DEFINITIONS ###
/*
/* Purpose:
* Author: Victor Fernandes, 040772243
* Version: 0.0.1
* Called functions:

View File

@ -4,7 +4,7 @@
* Author: Victor Fernandes, 040772243
* Version: 1.17.1
* Date: 30 January 2017
* Provided by: S^R
* Provided by: Svillen Ranev
* The file is complete and MUST NOT be modified.
*/
#ifndef TOKEN_H_
@ -62,7 +62,7 @@ typedef union TokenAttribute{
short str_offset; /* sring literal offset from the beginning of */
/* the string literal buffer (str_LTBL->cb_head) */
float flt_value; /* floating-point literal attribute (value) */
int vid_offset; /* the vid_offset member replaces vid_lex */
char vid_lex[VID_LEN+1]; /* variable identifier token attribute */
char err_lex[ERR_LEN+1]; /* error token attribite */
} TA;