Compare commits
30 Commits
Author | SHA1 | Date |
---|---|---|
|
933fbf61c9 | |
|
bcfe12a442 | |
|
d54a25668f | |
|
00504483c5 | |
|
8a8188e07d | |
|
57a7fa3e43 | |
|
06c9650d6f | |
|
0fd419102e | |
|
259d654eaf | |
|
d22d2718a0 | |
|
5bd748b2e6 | |
|
bb898ea44e | |
|
3d646261b5 | |
|
990900ae9a | |
|
992897c4ff | |
|
05b430c346 | |
|
fcb082a9de | |
|
94d90611e1 | |
|
89f718ce34 | |
|
c6f27e1e69 | |
|
5f717f4427 | |
|
69157aec8c | |
|
53fd5518dc | |
|
feb505e932 | |
|
182d4bbb90 | |
|
bc5b48ec82 | |
|
1bfef0f5fc | |
|
a213c022ef | |
|
158a461ebf | |
|
1efdeaf3e7 |
Binary file not shown.
Binary file not shown.
|
@ -1,12 +0,0 @@
|
||||||
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
|
|
|
@ -0,0 +1,328 @@
|
||||||
|
# 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
|
||||||
*Buffer Descriptor for the PLATYPUS language specification*
|
*Frontend compiler 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]`
|
||||||
- Default is to build both versions (this is an aftermath of testing behaviour from different compilers)
|
- No argument will build both versions (this is an aftermath of having to check behaviour in the binary from multiple compilers)
|
||||||
- It is safe to modify the default to either gcc or clang if you don't have one of them
|
- It is safe to modify the default to either gcc or clang if you wish.
|
||||||
- **NOTE: I haven't tested or created make targets for the scanner yet.**
|
- **NOTE: I haven't tested or created make targets for the final implementation yet. This is somewhat buried deep into the backburner**
|
||||||
### Windows
|
### Windows
|
||||||
#### Requires
|
#### Requires
|
||||||
- `msvc` (tested under Visual Studio 2015 with Update 3, however VS2013 shouldn't behave abnormally either, nor should 2017)
|
- `msvc` (tested under Visual Studio 2015 with Update 3, however VS 2012 and 2013 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, it is missing a scanner implementation, parser, symbol table, etc.
|
**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.
|
||||||
|
|
||||||
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)
|
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)
|
||||||
- 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 due to my environment's install locations for the C include libraries:
|
- This is an issue caused by my environment's install locations for the C include libraries:
|
||||||
- **Inside `buffer.h`, there is a `#DEFINE` line for `MACOS_DEP`. If you are using a Linux system or Windows and your malloc.h is actually named malloc.h, you can leave `#undef MACOS_DEP` alone, otherwise comment it out.**
|
- **`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.**
|
||||||
|
|
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: Svillen Ranev
|
* Professor: S^R
|
||||||
* 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,11 +22,12 @@
|
||||||
/* standard header files */
|
/* standard header files */
|
||||||
#include <stdio.h> /* standard input/output */
|
#include <stdio.h> /* standard input/output */
|
||||||
|
|
||||||
#ifdef MACOS_DEP
|
#ifndef WIN32
|
||||||
#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,6 +7,8 @@ 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
|
||||||
|
@ -41,6 +43,18 @@ 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
|
||||||
|
|
|
@ -0,0 +1,874 @@
|
||||||
|
/* 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();
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
/* 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
|
|
@ -0,0 +1,266 @@
|
||||||
|
/* 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: Svillen Ranev
|
* Author: S^R
|
||||||
* 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: Svillen Ranev
|
* Author: S^R
|
||||||
* 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%s\n",t.attribute.vid_lex);
|
printf("AVID_T\t\t%d\n",t.attribute.vid_offset);
|
||||||
break;
|
break;
|
||||||
case SVID_T:
|
case SVID_T:
|
||||||
printf("SVID_T\t\t%s\n",t.attribute.vid_lex);
|
printf("SVID_T\t\t%d\n",t.attribute.vid_offset);
|
||||||
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);
|
||||||
|
|
|
@ -0,0 +1,275 @@
|
||||||
|
/* 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: Svillen Ranev
|
* Provided by: S^R
|
||||||
* 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,6 +32,7 @@
|
||||||
/* 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 */
|
||||||
|
@ -44,8 +45,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 scerrnum; /* defined in platy_st.c - run-time error number */
|
extern int synerrno; /* 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*/
|
||||||
|
|
||||||
|
@ -73,7 +74,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*/
|
||||||
/* scerrnum = 0; *//*no need - global ANSI C */
|
/* synerrno = 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
|
||||||
|
@ -106,7 +107,8 @@ Token malar_next_token(Buffer * sc_buf)
|
||||||
pBuffer err_lex_buf;
|
pBuffer err_lex_buf;
|
||||||
|
|
||||||
if (sc_buf == NULL) {
|
if (sc_buf == NULL) {
|
||||||
scerrnum = 1;
|
synerrno
|
||||||
|
= 1;
|
||||||
return aa_table[ES]("RUN TIME ERROR: "); /* WHOOPS */
|
return aa_table[ES]("RUN TIME ERROR: "); /* WHOOPS */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,7 +176,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 */
|
||||||
|
@ -186,6 +188,7 @@ 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 '=':
|
||||||
|
@ -265,7 +268,7 @@ Token malar_next_token(Buffer * sc_buf)
|
||||||
|
|
||||||
b_retract_to_mark(sc_buf);
|
b_retract_to_mark(sc_buf);
|
||||||
|
|
||||||
lex_buf = b_create(1, 1, 'a');
|
lex_buf = b_create(20, 8, 'a');
|
||||||
|
|
||||||
/* Copy the scanned lexeme into lexical buffer */
|
/* Copy the scanned lexeme into lexical buffer */
|
||||||
for (; lexstart < lexend; ++lexstart) {
|
for (; lexstart < lexend; ++lexstart) {
|
||||||
|
@ -277,7 +280,8 @@ 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 {
|
||||||
scerrnum = 1;
|
synerrno
|
||||||
|
= 1;
|
||||||
t = aa_table[ES]("RUN TIME ERROR: ");
|
t = aa_table[ES]("RUN TIME ERROR: ");
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
@ -370,9 +374,10 @@ int char_class(char c)
|
||||||
Return values: Token
|
Return values: Token
|
||||||
*/
|
*/
|
||||||
Token aa_func02(char lexeme[]) {
|
Token aa_func02(char lexeme[]) {
|
||||||
unsigned int i, kw_idx; /* Variable to contain keyword table index */
|
unsigned kw_idx, offset; /* Variable to contain keyword table index */
|
||||||
Token t;
|
Token t;
|
||||||
char* temp_str;
|
char v_type;
|
||||||
|
/*char* temp_str;*/
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("Lexeme: '%s'\n", lexeme);
|
printf("Lexeme: '%s'\n", lexeme);
|
||||||
|
@ -387,17 +392,11 @@ 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: ");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < (VID_LEN) && i < strlen(lexeme); i++) {
|
strncpy(temp_str, lexeme, VID_LEN);*/
|
||||||
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':
|
||||||
|
@ -405,11 +404,21 @@ 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;
|
||||||
}
|
}
|
||||||
|
@ -424,24 +433,25 @@ Token aa_func02(char lexeme[]) {
|
||||||
*/
|
*/
|
||||||
Token aa_func03(char lexeme[]) {
|
Token aa_func03(char lexeme[]) {
|
||||||
Token t;
|
Token t;
|
||||||
unsigned int i;
|
unsigned offset;/*
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
t.code = SVID_T;
|
||||||
|
t.attribute.vid_offset = offset;
|
||||||
|
/*free(temp_str);*/
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -510,7 +520,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 > 32767) {
|
if (new_olval < 0 || new_olval > PLT_SHRT_MAX) {
|
||||||
t = aa_table[ES](lexeme);
|
t = aa_table[ES](lexeme);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
@ -549,11 +559,12 @@ Token aa_func12(char lexeme[]) {
|
||||||
*/
|
*/
|
||||||
Token aa_func13(char lexeme[]) {
|
Token aa_func13(char lexeme[]) {
|
||||||
Token t;
|
Token t;
|
||||||
unsigned int i;
|
unsigned int i = strlen(lexeme);
|
||||||
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] = '.';
|
||||||
|
|
|
@ -0,0 +1,382 @@
|
||||||
|
/* 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! */
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
/* 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: Svillen Ranev
|
* Provided by: S^R
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TABLE_H_
|
#ifndef TABLE_H_
|
||||||
|
@ -38,29 +38,31 @@
|
||||||
#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 , ES , ES , ES},
|
/* State 0 */ {1, 6 , 4 , 4 , IS , IS , IS},
|
||||||
/* 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, ES , 11, ES, ES , ES , 10},
|
/* State 9 */ {ES, 9 , 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 */
|
||||||
|
@ -70,20 +72,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
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -111,21 +113,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) */
|
||||||
|
@ -133,14 +135,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: Svillen Ranev
|
* Provided by: S^R
|
||||||
* 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) */
|
||||||
char vid_lex[VID_LEN+1]; /* variable identifier token attribute */
|
int vid_offset; /* the vid_offset member replaces vid_lex */
|
||||||
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