Compare commits
No commits in common. "master" and "scanner" have entirely different histories.
BIN
Ass04_W17.pdf
BIN
Ass04_W17.pdf
Binary file not shown.
Binary file not shown.
|
@ -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
|
|
@ -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.
18
README.md
18
README.md
|
@ -1,5 +1,5 @@
|
||||||
# PLATYPUS
|
# PLATYPUS
|
||||||
*Frontend compiler for the PLATYPUS language specification*
|
*Buffer Descriptor for the PLATYPUS language specification*
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
|
@ -8,12 +8,12 @@
|
||||||
*gcc (tested in version 6.3.x) or clang (tested under LLVM clang-0800.0.42.1)*
|
*gcc (tested in version 6.3.x) or clang (tested under LLVM clang-0800.0.42.1)*
|
||||||
|
|
||||||
- `make [gcc | clang]`
|
- `make [gcc | clang]`
|
||||||
- No argument will build both versions (this is an aftermath of having to check behaviour in the binary from multiple compilers)
|
- 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 wish.
|
- 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 final implementation yet. This is somewhat buried deep into the backburner**
|
- **NOTE: I haven't tested or created make targets for the scanner yet.**
|
||||||
### Windows
|
### Windows
|
||||||
#### Requires
|
#### 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)
|
- Disable language extensions (use ANSI C)
|
||||||
---
|
---
|
||||||
## Running
|
## Running
|
||||||
|
@ -31,10 +31,10 @@
|
||||||
|
|
||||||
# Notes
|
# 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)
|
- 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)`
|
- 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:
|
- This is due to 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.**
|
- **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.**
|
||||||
|
|
2
buffer.c
2
buffer.c
|
@ -4,7 +4,7 @@
|
||||||
* Author: Victor Fernandes, 040772243
|
* Author: Victor Fernandes, 040772243
|
||||||
* Course: CST8152 - Compilers, Lab Section: 011
|
* Course: CST8152 - Compilers, Lab Section: 011
|
||||||
* Date: February 1, 2017
|
* Date: February 1, 2017
|
||||||
* Professor: S^R
|
* Professor: Svillen Ranev
|
||||||
* A character buffer utility with three modes of self-incrementation
|
* A character buffer utility with three modes of self-incrementation
|
||||||
through dynamic memory allocation, and ability to set a mark flag.
|
through dynamic memory allocation, and ability to set a mark flag.
|
||||||
* Function list: b_create, b_isfull, b_isempty, b_size, b_capacity,
|
* Function list: b_create, b_isfull, b_isempty, b_size, b_capacity,
|
||||||
|
|
3
buffer.h
3
buffer.h
|
@ -22,12 +22,11 @@
|
||||||
/* standard header files */
|
/* standard header files */
|
||||||
#include <stdio.h> /* standard input/output */
|
#include <stdio.h> /* standard input/output */
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifdef MACOS_DEP
|
||||||
#include <mm_malloc.h> /* for dynamic memory allocation.*/
|
#include <mm_malloc.h> /* for dynamic memory allocation.*/
|
||||||
#else
|
#else
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <limits.h> /* implementation-defined data type ranges and limits */
|
#include <limits.h> /* implementation-defined data type ranges and limits */
|
||||||
|
|
||||||
/* constant definitions */
|
/* constant definitions */
|
||||||
|
|
|
@ -7,8 +7,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "buffer", "buffer\buffer.vcx
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scanner", "scanner\scanner.vcxproj", "{C53261F2-8A2D-4F75-8E54-DBFD16A621BB}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scanner", "scanner\scanner.vcxproj", "{C53261F2-8A2D-4F75-8E54-DBFD16A621BB}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Stable", "Stable\Stable.vcxproj", "{C2CCF0F1-D771-4F57-89EA-F76727169CE3}"
|
|
||||||
EndProject
|
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
COMPILERS|x64 = COMPILERS|x64
|
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|x64.Build.0 = Release|x64
|
||||||
{C53261F2-8A2D-4F75-8E54-DBFD16A621BB}.Release|x86.ActiveCfg = Release|Win32
|
{C53261F2-8A2D-4F75-8E54-DBFD16A621BB}.Release|x86.ActiveCfg = Release|Win32
|
||||||
{C53261F2-8A2D-4F75-8E54-DBFD16A621BB}.Release|x86.Build.0 = 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
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
874
parser.c
874
parser.c
|
@ -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();
|
|
||||||
}
|
|
72
parser.h
72
parser.h
|
@ -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
266
platy.c
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* File name: platy_bt.c
|
/* File name: platy_bt.c
|
||||||
* Purpose:This is the main program for Assignment #1, CST8152, Winter 17
|
* Purpose:This is the main program for Assignment #1, CST8152, Winter 17
|
||||||
* Version: 1.17.1
|
* Version: 1.17.1
|
||||||
* Author: S^R
|
* Author: Svillen Ranev
|
||||||
* Date: 9 January 2017
|
* Date: 9 January 2017
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* Purpose:This is the main program for Assignment #2 - Scanner
|
* Purpose:This is the main program for Assignment #2 - Scanner
|
||||||
* CST8152 - Compilers
|
* CST8152 - Compilers
|
||||||
* Version: 1.17.1
|
* Version: 1.17.1
|
||||||
* Author: S^R
|
* Author: Svillen Ranev
|
||||||
* Date: 30 January 2017
|
* Date: 30 January 2017
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -201,10 +201,10 @@ void print_token(Token t){
|
||||||
printf("SEOF_T\n" );
|
printf("SEOF_T\n" );
|
||||||
break;
|
break;
|
||||||
case AVID_T:
|
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;
|
break;
|
||||||
case SVID_T:
|
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;
|
break;
|
||||||
case FPL_T:
|
case FPL_T:
|
||||||
printf("FPL_T\t\t%f\n",t.attribute.flt_value);
|
printf("FPL_T\t\t%f\n",t.attribute.flt_value);
|
||||||
|
|
275
platy_tt.c
275
platy_tt.c
|
@ -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);
|
|
||||||
}
|
|
79
scanner.c
79
scanner.c
|
@ -5,7 +5,7 @@
|
||||||
* scanner_init() must be called before using the scanner.
|
* scanner_init() must be called before using the scanner.
|
||||||
* The file is incomplete;
|
* The file is incomplete;
|
||||||
* Author: Victor Fernandes, 040772243
|
* Author: Victor Fernandes, 040772243
|
||||||
* Provided by: S^R
|
* Provided by: Svillen Ranev
|
||||||
* Version: 1.17.1
|
* Version: 1.17.1
|
||||||
* Date: 30 January 2017
|
* Date: 30 January 2017
|
||||||
* Function list: scanner_init, malar_next_token, get_next_state, char_class,
|
* Function list: scanner_init, malar_next_token, get_next_state, char_class,
|
||||||
|
@ -32,7 +32,6 @@
|
||||||
/* project header files */
|
/* project header files */
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
#include "stable.h"
|
|
||||||
#include "table.h"
|
#include "table.h"
|
||||||
|
|
||||||
#define DEBUG /* for conditional processing */
|
#define DEBUG /* for conditional processing */
|
||||||
|
@ -45,8 +44,8 @@
|
||||||
It is defined in platy_st.c */
|
It is defined in platy_st.c */
|
||||||
extern Buffer * str_LTBL; /*String literal table */
|
extern Buffer * str_LTBL; /*String literal table */
|
||||||
int line; /* current line number of the source code */
|
int line; /* current line number of the source code */
|
||||||
extern int synerrno; /* defined in platy_st.c - run-time error number */
|
extern int scerrnum; /* defined in platy_st.c - run-time error number */
|
||||||
extern STD sym_table; /* symbol table */
|
|
||||||
/* Local(file) global objects - variables */
|
/* Local(file) global objects - variables */
|
||||||
static Buffer *lex_buf; /*pointer to temporary lexeme buffer*/
|
static Buffer *lex_buf; /*pointer to temporary lexeme buffer*/
|
||||||
|
|
||||||
|
@ -74,7 +73,7 @@ int scanner_init(Buffer * sc_buf) {
|
||||||
b_reset(str_LTBL);
|
b_reset(str_LTBL);
|
||||||
line = 1;
|
line = 1;
|
||||||
return EXIT_SUCCESS;/*0*/
|
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
|
/* Reads the source code buffer and generates a token
|
||||||
* Author: Victor Fernandes
|
* Author: Victor Fernandes
|
||||||
|
@ -107,8 +106,7 @@ Token malar_next_token(Buffer * sc_buf)
|
||||||
pBuffer err_lex_buf;
|
pBuffer err_lex_buf;
|
||||||
|
|
||||||
if (sc_buf == NULL) {
|
if (sc_buf == NULL) {
|
||||||
synerrno
|
scerrnum = 1;
|
||||||
= 1;
|
|
||||||
return aa_table[ES]("RUN TIME ERROR: "); /* WHOOPS */
|
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 */
|
if (c == '<') { /* It's a comment line */
|
||||||
/* Consume chars until line ends */
|
/* Consume chars until line ends */
|
||||||
for (; c != '\0' && c != '\r' && c != '\n' && c != 255; c = b_getc(sc_buf));
|
for (; c != '\0' && c != '\r' && c != '\n' && c != 255; c = b_getc(sc_buf));
|
||||||
++line;
|
line++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else { /* Bad character, pump out an error token */
|
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';
|
t.attribute.err_lex[2] = '\0';
|
||||||
/* Consume the rest of the caracters to ignore the line*/
|
/* Consume the rest of the caracters to ignore the line*/
|
||||||
for (; c != '\0' && c != '\r' && c != '\n' && c != 255; c = b_getc(sc_buf));
|
for (; c != '\0' && c != '\r' && c != '\n' && c != 255; c = b_getc(sc_buf));
|
||||||
++line;
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
case '=':
|
case '=':
|
||||||
|
@ -268,7 +265,7 @@ Token malar_next_token(Buffer * sc_buf)
|
||||||
|
|
||||||
b_retract_to_mark(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 */
|
/* Copy the scanned lexeme into lexical buffer */
|
||||||
for (; lexstart < lexend; ++lexstart) {
|
for (; lexstart < lexend; ++lexstart) {
|
||||||
|
@ -280,8 +277,7 @@ Token malar_next_token(Buffer * sc_buf)
|
||||||
t = aa_table[state](b_setmark(lex_buf, 0));
|
t = aa_table[state](b_setmark(lex_buf, 0));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
synerrno
|
scerrnum = 1;
|
||||||
= 1;
|
|
||||||
t = aa_table[ES]("RUN TIME ERROR: ");
|
t = aa_table[ES]("RUN TIME ERROR: ");
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
@ -374,10 +370,9 @@ int char_class(char c)
|
||||||
Return values: Token
|
Return values: Token
|
||||||
*/
|
*/
|
||||||
Token aa_func02(char lexeme[]) {
|
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;
|
Token t;
|
||||||
char v_type;
|
char* temp_str;
|
||||||
/*char* temp_str;*/
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("Lexeme: '%s'\n", lexeme);
|
printf("Lexeme: '%s'\n", lexeme);
|
||||||
|
@ -392,11 +387,17 @@ Token aa_func02(char lexeme[]) {
|
||||||
|
|
||||||
/* Not a keyword? Must be AVID*/
|
/* Not a keyword? Must be AVID*/
|
||||||
t.code = AVID_T;
|
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: ");
|
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?)*/
|
switch (lexeme[0]) { /* Read first character of lexeme for implicit type (not used yet?)*/
|
||||||
case 'i':
|
case 'i':
|
||||||
|
@ -404,21 +405,11 @@ Token aa_func02(char lexeme[]) {
|
||||||
case 'd':
|
case 'd':
|
||||||
case 'n':
|
case 'n':
|
||||||
/* Integer */
|
/* Integer */
|
||||||
v_type = 'I';
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Floating point*/
|
/* Floating point*/
|
||||||
v_type = 'F';
|
|
||||||
break;
|
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;
|
return t;
|
||||||
}
|
}
|
||||||
|
@ -433,25 +424,24 @@ Token aa_func02(char lexeme[]) {
|
||||||
*/
|
*/
|
||||||
Token aa_func03(char lexeme[]) {
|
Token aa_func03(char lexeme[]) {
|
||||||
Token t;
|
Token t;
|
||||||
unsigned offset;/*
|
unsigned int i;
|
||||||
char* temp_str;
|
char* temp_str;
|
||||||
if ((temp_str = (char*)calloc(VID_LEN + 2, sizeof(char))) == NULL) {
|
if ((temp_str = (char*)calloc(VID_LEN + 2, sizeof(char))) == NULL) {
|
||||||
return aa_table[ES]("RUN TIME ERROR: ");
|
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;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -520,7 +510,7 @@ Token aa_func10(char lexeme[]) {
|
||||||
t.code = INL_T;
|
t.code = INL_T;
|
||||||
new_olval = atool(lexeme);
|
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);
|
t = aa_table[ES](lexeme);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
@ -559,12 +549,11 @@ Token aa_func12(char lexeme[]) {
|
||||||
*/
|
*/
|
||||||
Token aa_func13(char lexeme[]) {
|
Token aa_func13(char lexeme[]) {
|
||||||
Token t;
|
Token t;
|
||||||
unsigned int i = strlen(lexeme);
|
unsigned int i;
|
||||||
t.code = ERR_T;
|
t.code = ERR_T;
|
||||||
/*
|
|
||||||
for (i = 0; i < (ERR_LEN) && i < strlen(lexeme); i++)
|
for (i = 0; i < (ERR_LEN) && i < strlen(lexeme); i++)
|
||||||
t.attribute.err_lex[i] = lexeme[i];
|
t.attribute.err_lex[i] = lexeme[i];
|
||||||
*/
|
|
||||||
if (strlen(lexeme) > ERR_LEN) {
|
if (strlen(lexeme) > ERR_LEN) {
|
||||||
t.attribute.err_lex[i - 1] = '.';
|
t.attribute.err_lex[i - 1] = '.';
|
||||||
t.attribute.err_lex[i - 2] = '.';
|
t.attribute.err_lex[i - 2] = '.';
|
||||||
|
|
382
stable.c
382
stable.c
|
@ -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! */
|
|
||||||
}
|
|
66
stable.h
66
stable.h
|
@ -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
114
table.h
|
@ -4,7 +4,7 @@
|
||||||
* Author: Victor Fernandes, 040772243
|
* Author: Victor Fernandes, 040772243
|
||||||
* Version: 1.17.1
|
* Version: 1.17.1
|
||||||
* Date: 30 January 2017
|
* Date: 30 January 2017
|
||||||
* Provided by: S^R
|
* Provided by: Svillen Ranev
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TABLE_H_
|
#ifndef TABLE_H_
|
||||||
|
@ -38,31 +38,29 @@
|
||||||
#define ESWR 13 /* Error state (no retract) */
|
#define ESWR 13 /* Error state (no retract) */
|
||||||
#define IS -1 /* Invalid state */
|
#define IS -1 /* Invalid state */
|
||||||
|
|
||||||
/*Avoid platform dependency and use fixed 2-byte short */
|
|
||||||
#define PLT_SHRT_MAX 32767
|
|
||||||
/* State transition table definition */
|
/* State transition table definition */
|
||||||
|
|
||||||
#define TABLE_COLUMNS 7
|
#define TABLE_COLUMNS 7
|
||||||
/*transition table - type of states defined in separate table */
|
/*transition table - type of states defined in separate table */
|
||||||
int st_table[][TABLE_COLUMNS] = {
|
int st_table[][TABLE_COLUMNS] = {
|
||||||
/* INPUT COLUMNS:
|
/* INPUT COLUMNS:
|
||||||
COLUMN # | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
|
COLUMN # | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
|
||||||
|[a-zA-Z]| 0 |[1-7]|[8-9]| . | # | other |
|
|[a-zA-Z]| 0 |[1-7]|[8-9]| . | # | other |
|
||||||
*/
|
*/
|
||||||
/* State 0 */ {1, 6 , 4 , 4 , IS , IS , IS},
|
/* State 0 */ {1, 6 , 4 , 4 , ES , ES , ES},
|
||||||
/* State 1 */ {1, 1 , 1 , 1 , 2 , 3 , 2 },
|
/* State 1 */ {1, 1 , 1 , 1 , 2 , 3 , 2 },
|
||||||
/* State 2 */ {IS, IS , IS, IS, IS , IS , IS},
|
/* State 2 */ {IS, IS , IS, IS, IS , IS , IS},
|
||||||
/* State 3 */ {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 4 */ {ES, 4 , 4 , 4 , 7 , 5 , 5 },
|
||||||
/* State 5 */ {IS, IS , IS, IS, IS , IS , IS},
|
/* State 5 */ {IS, IS , IS, IS, IS , IS , IS},
|
||||||
/* State 6 */ {ES, 9 , 9 , ES, 7 , ES , 5 },
|
/* State 6 */ {ES, 9 , 9 , ES, 7 , ES , 5 },
|
||||||
/* State 7 */ {8 , 7 , 7 , 7, 8 , 8 , 8 },
|
/* State 7 */ {8 , 7 , 7 , 7, 8 , 8 , 8 },
|
||||||
/* State 8 */ {IS, IS , IS, IS, IS , IS , IS},
|
/* State 8 */ {IS, IS , IS, IS, IS , IS , IS},
|
||||||
/* State 9 */ {ES, 9 , 11, ES, ES , ES , 10},
|
/* State 9 */ {ES, ES , 11, ES, ES , ES , 10},
|
||||||
/* State 10 */ {IS, IS , IS, IS, IS , IS , IS},
|
/* State 10 */ {IS, IS , IS, IS, IS , IS , IS},
|
||||||
/* State 11 */ {ES, 11 , 11, ES, ES , ES , 10},
|
/* State 11 */ {ES, 11 , 11, ES, ES , ES , 10},
|
||||||
/* State 12 */ {IS, IS , IS, IS, IS , IS , IS},
|
/* State 12 */ {IS, IS , IS, IS, IS , IS , IS},
|
||||||
/* State 13 */ {IS, IS , IS, IS, IS , IS , IS}
|
/* State 13 */ {IS, IS , IS, IS, IS , IS , IS}
|
||||||
|
|
||||||
};
|
};
|
||||||
/* Accepting state table definition */
|
/* Accepting state table definition */
|
||||||
|
@ -72,20 +70,20 @@ int st_table[][TABLE_COLUMNS] = {
|
||||||
|
|
||||||
int as_table[] = {
|
int as_table[] = {
|
||||||
|
|
||||||
/* State 0 */ NOAS,
|
/* State 0 */ NOAS,
|
||||||
/* State 1 */ NOAS,
|
/* State 1 */ NOAS,
|
||||||
/* State 2 */ ASWR,
|
/* State 2 */ ASWR,
|
||||||
/* State 3 */ ASNR,
|
/* State 3 */ ASNR,
|
||||||
/* State 4 */ NOAS,
|
/* State 4 */ NOAS,
|
||||||
/* State 5 */ ASWR,
|
/* State 5 */ ASWR,
|
||||||
/* State 6 */ NOAS,
|
/* State 6 */ NOAS,
|
||||||
/* State 7 */ NOAS,
|
/* State 7 */ NOAS,
|
||||||
/* State 8 */ ASWR,
|
/* State 8 */ ASWR,
|
||||||
/* State 9 */ NOAS,
|
/* State 9 */ NOAS,
|
||||||
/* State 10 */ ASWR,
|
/* State 10 */ ASWR,
|
||||||
/* State 11 */ NOAS,
|
/* State 11 */ NOAS,
|
||||||
/* State 12 */ ASNR,
|
/* State 12 */ ASNR,
|
||||||
/* State 13 */ ASWR
|
/* State 13 */ ASWR
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -113,21 +111,21 @@ typedef Token(*PTR_AAF)(char *lexeme);
|
||||||
|
|
||||||
PTR_AAF aa_table[] = {
|
PTR_AAF aa_table[] = {
|
||||||
|
|
||||||
/* State 0 */ NULL,
|
/* State 0 */ NULL,
|
||||||
/* State 1 */ NULL,
|
/* State 1 */ NULL,
|
||||||
/* State 2 */ aa_func02,
|
/* State 2 */ aa_func02,
|
||||||
/* State 3 */ aa_func03,
|
/* State 3 */ aa_func03,
|
||||||
/* State 4 */ NULL,
|
/* State 4 */ NULL,
|
||||||
/* State 5 */ aa_func05,
|
/* State 5 */ aa_func05,
|
||||||
/* State 6 */ NULL,
|
/* State 6 */ NULL,
|
||||||
/* State 7 */ NULL,
|
/* State 7 */ NULL,
|
||||||
/* State 8 */ aa_func08,
|
/* State 8 */ aa_func08,
|
||||||
/* State 9 */ NULL,
|
/* State 9 */ NULL,
|
||||||
/* State 10 */ aa_func10,
|
/* State 10 */ aa_func10,
|
||||||
/* State 11 */ NULL,
|
/* State 11 */ NULL,
|
||||||
/* State 12 */ aa_func12,
|
/* State 12 */ aa_func12,
|
||||||
/* State 13 */ aa_func13
|
/* State 13 */ aa_func13
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Keyword lookup table (.AND. and .OR. are not keywords) */
|
/* Keyword lookup table (.AND. and .OR. are not keywords) */
|
||||||
|
@ -135,14 +133,14 @@ PTR_AAF aa_table[] = {
|
||||||
#define KWT_SIZE 8
|
#define KWT_SIZE 8
|
||||||
|
|
||||||
char * kw_table[] = {
|
char * kw_table[] = {
|
||||||
"ELSE",
|
"ELSE",
|
||||||
"IF",
|
"IF",
|
||||||
"INPUT",
|
"INPUT",
|
||||||
"OUTPUT",
|
"OUTPUT",
|
||||||
"PLATYPUS",
|
"PLATYPUS",
|
||||||
"REPEAT",
|
"REPEAT",
|
||||||
"THEN",
|
"THEN",
|
||||||
"USING"
|
"USING"
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
### FUNCTION DEFINITIONS ###
|
### FUNCTION DEFINITIONS ###
|
||||||
/*
|
/* Purpose:
|
||||||
* Author: Victor Fernandes, 040772243
|
* Author: Victor Fernandes, 040772243
|
||||||
* Version: 0.0.1
|
* Version: 0.0.1
|
||||||
* Called functions:
|
* Called functions:
|
||||||
|
|
4
token.h
4
token.h
|
@ -4,7 +4,7 @@
|
||||||
* Author: Victor Fernandes, 040772243
|
* Author: Victor Fernandes, 040772243
|
||||||
* Version: 1.17.1
|
* Version: 1.17.1
|
||||||
* Date: 30 January 2017
|
* Date: 30 January 2017
|
||||||
* Provided by: S^R
|
* Provided by: Svillen Ranev
|
||||||
* The file is complete and MUST NOT be modified.
|
* The file is complete and MUST NOT be modified.
|
||||||
*/
|
*/
|
||||||
#ifndef TOKEN_H_
|
#ifndef TOKEN_H_
|
||||||
|
@ -62,7 +62,7 @@ typedef union TokenAttribute{
|
||||||
short str_offset; /* sring literal offset from the beginning of */
|
short str_offset; /* sring literal offset from the beginning of */
|
||||||
/* the string literal buffer (str_LTBL->cb_head) */
|
/* the string literal buffer (str_LTBL->cb_head) */
|
||||||
float flt_value; /* floating-point literal attribute (value) */
|
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 */
|
char err_lex[ERR_LEN+1]; /* error token attribite */
|
||||||
} TA;
|
} TA;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue