AAAAAAAAAAAAAAA
This commit is contained in:
parent
5bd748b2e6
commit
d22d2718a0
|
@ -0,0 +1,868 @@
|
||||||
|
/* File Name: parser.c
|
||||||
|
* The PLATYPUS parsing program for the final assignment of
|
||||||
|
How To Train Your Dragon (AKA Compilers)
|
||||||
|
* 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;
|
||||||
|
extern int synerrno; /* Error counter */
|
||||||
|
extern char* kw_table[]; /* Keyword table with matching enum */
|
||||||
|
extern STD sym_table; /* The symbol table */
|
||||||
|
extern Buffer* sc_buf; /* Scanner buffer */
|
||||||
|
extern Buffer* str_LTBL; /* String literal table */
|
||||||
|
extern int line /* Line position of the Scanner */
|
||||||
|
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
{
|
||||||
|
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 &&
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
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 }
|
||||||
|
*/
|
||||||
|
voic 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.codem, 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();
|
||||||
|
stirng_expression_prime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* <unary_arithmetic_expression> ->
|
||||||
|
- <primary_arithmetic_expression>
|
||||||
|
| + <primary_arithmetic_expression>
|
||||||
|
FIRST Set = {-, +}
|
||||||
|
*/
|
||||||
|
void unary_arithmetic_expression()
|
||||||
|
{
|
||||||
|
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,71 @@
|
||||||
|
/* 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: Svillen Ravev
|
||||||
|
* 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 unary_arithmetic_expression(void);
|
||||||
|
void variable_identifier(void);
|
||||||
|
void variable_list(void);
|
||||||
|
void variable_list_prime(void);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue