153 lines
3.7 KiB
Plaintext
153 lines
3.7 KiB
Plaintext
%{
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stack>
|
|
#include <string>
|
|
#define INFILE_ERROR 1
|
|
#define OUTFILE_ERROR 2
|
|
|
|
extern int yylineno;
|
|
extern FILE *yyin;
|
|
int yylex();
|
|
|
|
void yyerror(const char *msg, ...);
|
|
|
|
struct StackElement {
|
|
std::string value;
|
|
enum { INT, VAR } type;
|
|
};
|
|
|
|
std::stack<StackElement> expressionsStack;
|
|
FILE *tripletFile;
|
|
int tempVarCounter = 0;
|
|
|
|
std::string generateTempVar() {
|
|
return "result" + std::to_string(tempVarCounter++);
|
|
}
|
|
|
|
void writeTriplet(const std::string& result, const std::string& arg1, const std::string& arg2, const std::string& op) {
|
|
fprintf(tripletFile, "%s= %s %s %s \n", result.c_str(), arg1.c_str(), arg2.c_str(), op.c_str());
|
|
|
|
}
|
|
|
|
%}
|
|
|
|
%union {
|
|
char *text;
|
|
int ival;
|
|
}
|
|
|
|
%token <text> ID
|
|
%token <ival> INT_LIT
|
|
%token LET
|
|
%token INT_TYPE
|
|
%token SEMICOLON COLON
|
|
|
|
%left '+' '-'
|
|
%left '*' '/'
|
|
|
|
%start program
|
|
|
|
%%
|
|
|
|
program
|
|
: statement_list { printf("koniec\n"); }
|
|
;
|
|
|
|
statement_list
|
|
: statement
|
|
| statement_list statement
|
|
;
|
|
|
|
statement
|
|
: variable_declaration { printf("Deklaracja zmiennej\n"); }
|
|
| expression SEMICOLON {
|
|
printf("instrukcja\n");
|
|
if (!expressionsStack.empty()) {
|
|
expressionsStack.pop();
|
|
}
|
|
}
|
|
;
|
|
|
|
variable_declaration
|
|
: LET ID COLON INT_TYPE '=' expression SEMICOLON
|
|
{
|
|
printf("Deklaracja zmiennej: %s\n", $2);
|
|
if (!expressionsStack.empty()) {
|
|
StackElement expression = expressionsStack.top();
|
|
expressionsStack.pop();
|
|
writeTriplet(std::string($2), expression.value, "", "=");
|
|
}
|
|
}
|
|
;
|
|
|
|
expression
|
|
: expression '+' expression {
|
|
printf("Wyrazenie z +\n");
|
|
StackElement rhs = expressionsStack.top();
|
|
expressionsStack.pop();
|
|
StackElement lhs = expressionsStack.top();
|
|
expressionsStack.pop();
|
|
std::string temp = generateTempVar();
|
|
writeTriplet(temp, lhs.value, rhs.value, "+");
|
|
}
|
|
| expression '-' expression {
|
|
printf("Wyrazenie z -\n");
|
|
StackElement rhs = expressionsStack.top();
|
|
expressionsStack.pop();
|
|
StackElement lhs = expressionsStack.top();
|
|
expressionsStack.pop();
|
|
std::string temp = generateTempVar();
|
|
writeTriplet(temp, lhs.value, rhs.value, "-");
|
|
}
|
|
| expression '*' expression {
|
|
printf("Wyrazenie z *\n");
|
|
StackElement rhs = expressionsStack.top();
|
|
expressionsStack.pop();
|
|
StackElement lhs = expressionsStack.top();
|
|
expressionsStack.pop();
|
|
std::string temp = generateTempVar();
|
|
writeTriplet(temp, lhs.value, rhs.value, "*");
|
|
}
|
|
| expression '/' expression {
|
|
printf("Wyrazenie z /\n");
|
|
StackElement rhs = expressionsStack.top();
|
|
expressionsStack.pop();
|
|
StackElement lhs = expressionsStack.top();
|
|
expressionsStack.pop();
|
|
std::string temp = generateTempVar();
|
|
writeTriplet(temp, lhs.value, rhs.value, "/");
|
|
}
|
|
| '(' expression ')' { printf("Wyrazenie w nawiasach\n"); }
|
|
| INT_LIT {
|
|
printf("Literal calkowity: %d\n", $1);
|
|
StackElement element;
|
|
element.value = std::to_string($1);
|
|
element.type = StackElement::INT;
|
|
expressionsStack.push(element);
|
|
}
|
|
| ID {
|
|
printf("Identyfikator: %s\n", $1);
|
|
char buffer[128];
|
|
snprintf(buffer, sizeof(buffer), "%s", $1);
|
|
StackElement element;
|
|
element.value = std::string(buffer);
|
|
element.type = StackElement::VAR;
|
|
expressionsStack.push(element);
|
|
}
|
|
;
|
|
|
|
%%
|
|
|
|
int main(int argc, char *argv[]) {
|
|
tripletFile = fopen("triplets.txt", "w");
|
|
if (!tripletFile) {
|
|
fprintf(stderr, "Blad\n");
|
|
return OUTFILE_ERROR;
|
|
}
|
|
yyparse();
|
|
fclose(tripletFile);
|
|
return 0;
|
|
}
|