Skip to content

Instantly share code, notes, and snippets.

@samagragupta
Created May 5, 2020 14:29
Show Gist options
  • Select an option

  • Save samagragupta/06b97c2ec76bf9f7e3e6cbbf6a3b0050 to your computer and use it in GitHub Desktop.

Select an option

Save samagragupta/06b97c2ec76bf9f7e3e6cbbf6a3b0050 to your computer and use it in GitHub Desktop.
PikaC
%{
#include <cstdio>
#include "pikaC.tab.h" // to get the token types from Bison
#include <string.h>
#include <stdlib.h>
char* strdup (const char* s)
{
size_t slen = strlen(s);
char* result = (char*) malloc(slen + 1);
if(result == NULL)
{
return NULL;
}
memcpy(result, s, slen+1);
return result;
}
/* #include <iostream>
using namespace std;
extern int yylex(); */
int line_number = 1;
%}
%option noyywrap
%%
[ \t] ;
[\n] { line_number++; }
[0-9]+ { yylval.ival = atoi(yytext); return INT;}
[0-9]*\.[0-9]+ { yylval.fval = atof(yytext); return FLOAT;}
\'[a-zA-Z0-9]\' { return CHAR;}
true { yylval.bval = true; return BOOL;}
True { yylval.bval = true; return BOOL;}
false { yylval.bval = false; return BOOL;}
False { yylval.bval = false; return BOOL;}
int { yylval.dtype = strdup(yytext); return TYPE_INT;}
float { yylval.dtype = strdup(yytext); return TYPE_FLOAT;}
char { yylval.dtype = strdup(yytext); return TYPE_CHAR;}
bool { yylval.dtype = strdup(yytext); return TYPE_BOOL;}
File { yylval.dtype = strdup(yytext); return TYPE_FILE;}
void { return TYPE_VOID;}
= { return ASSIGNMENT; }
[!~+\-*/%&|^] { return yytext[0];}
"<<" { return LSHIFT;}
">>" { return RSHIFT;}
"<" { return LT;}
">" { return GT;}
"==" { return EQ;}
"!=" { return NE;}
"<=" { return LE;}
">=" { return GE;}
"&&" { return LOGAND;}
"||" { return LOGOR;}
; { return TERMINATOR; }
if { return IF; }
elif { return ELIF; }
else { return ELSE; }
for { return FOR; }
while { return WHILE; }
return { return RETURN; }
break { return BREAK; }
scan { return SCAN; }
print { return PRINT; }
read { return READ; }
write { return WRITE; }
[\(\)\{\}?:,\[\]] { return yytext[0]; }
[a-zA-Z]+[a-zA-Z0-9_]* { yylval.vval = strdup(yytext); return VARIABLE;}
. { yylval.inval = strdup(yytext); return INVALID; }
%%
// \"([a-zA-Z0-9]|[ ])+\" { yylval.sval = strdup(yytext); return STRING;} //-> for string
/*
To Run:
bison -dv pikaC.y & flex pikaC.l & g++ pikaC.tab.c lex.yy.c -lm -o pikaC & pikaC.exe
*/
%{
#include <cstdio>
#include <iostream>
using namespace std;
extern int yylex();
extern int yyparse();
extern FILE *yyin;
extern int line_number;
void yyerror(const char *s);
%}
%union {
int ival;
float fval;
char *sval;
char *vval;
char *inval;
char *dtype;
char cval;
bool bval;
}
/* Terminal Tokens */
%token TYPE_VOID
%token ASSIGNMENT
%token LSHIFT
%token RSHIFT
%token LT
%token GT
%token EQ
%token NE
%token LE
%token GE
%token LOGAND
%token LOGOR
%token TERMINATOR
%token IF
%token ELIF
%token ELSE
%token FOR
%token WHILE
%token RETURN
%token BREAK
%token SCAN
%token PRINT
%token READ
%token WRITE
/* Data Tokens */
%token <ival> INT
%token <fval> FLOAT
%token <cval> CHAR
%token <bval> BOOL
// %token <sval> STRING
%token <inval> INVALID
%token <vval> VARIABLE
%token <dtype> TYPE_INT
%token <dtype> TYPE_FLOAT
%token <dtype> TYPE_CHAR
%token <dtype> TYPE_BOOL
%token <dtype> TYPE_FILE
/* Operator Associativity */
%right ASSIGNMENT
%left LOGOR
%left LOGAND
%left '|'
%left '^'
%left '&'
%left EQ NE
%left GT GE LT LE
%left LSHIFT RSHIFT
%left '+' '-'
%left '*' '/' '%'
%left '['']'
%left '(' ')'
%start program
%error-verbose
%%
program: STMTS
| {cout << "Empty file" << endl;} ;
STMTS: STMT STMTS
| STMT ;
STMT: IO TERMINATOR
| EXP TERMINATOR
| DECL_STMT
| ASSIGN_STMT TERMINATOR
| CONTROL_STMT
| LOOP
| BREAK_STMT TERMINATOR
| FUNC_DECL
// | FUNC_CALL TERMINATOR -> its will be in exp part
| RETURN_STMT TERMINATOR ;
IO: SCAN '(' AllVar_list ')' {cout << line_number << ": Input Statement" << endl;}
| SCAN '(' VARIABLE '[' EXP ']' ')' {cout << line_number << ": Array Input Statement" << endl;}
| PRINT '(' EXP ')' {cout << line_number << ": Print Statement" << endl;} ;
// /* operator: ASSIGNMENT | LOGOR | LOGAND | '|' | '^' | '&' | EQ | NE | GT | GE | LT | LE | LSHIFT | RSHIFT | '+' | '-' | '*' | '/' | '%'; */
EXP: EXP ASSIGNMENT EXP
| EXP LOGOR EXP
| EXP LOGAND EXP
| EXP '|' EXP
| EXP '^' EXP
| EXP '&' EXP
| EXP EQ EXP
| EXP NE EXP
| EXP GT EXP
| EXP GE EXP
| EXP LT EXP
| EXP LE EXP
| EXP LSHIFT EXP
| EXP RSHIFT EXP
| EXP '+' EXP
| EXP '-' EXP
| EXP '*' EXP
| EXP '/' EXP
| EXP '%' EXP
| '(' EXP ')'
| '-' EXP
| All_var
| VALUE
| FUNC_CALL
DATA_TYPE: TYPE_INT
| TYPE_FLOAT
| TYPE_CHAR
| TYPE_BOOL
| TYPE_FILE ;
VALUE: INT
| FLOAT
| CHAR
| BOOL ;
variable_list: VARIABLE ',' variable_list {cout << line_number << ": Variable declaration without definition" << endl; free($1);}
| VARIABLE {cout << line_number << ": Variable declaration without definition" << endl; free($1);}
| VARIABLE ASSIGNMENT EXP ',' variable_list {cout << line_number << ": Variable declaration with definition" << endl; free($1);}
| VARIABLE ASSIGNMENT EXP {cout << line_number << ": Variable declaration with definition" << endl; free($1);}
| VARIABLE '[' EXP ']' ',' variable_list {cout << line_number << ": Array declaration without definition" << endl; free($1);}
| VARIABLE '[' EXP ']' {cout << line_number << ": Array declaration without definition" << endl; free($1);}
| VARIABLE '[' EXP ']' ASSIGNMENT '{' EXP '}' ',' variable_list {cout << line_number << ": Array declaration with definition" << endl; free($1);}
| VARIABLE '[' EXP ']' ASSIGNMENT '{' EXP '}' {cout << line_number << ": Array declaration with definition" << endl; free($1);}
All_var: VARIABLE {free($1);}
| VARIABLE '[' EXP ']' {free($1);} ;
AllVar_list: All_var ',' AllVar_list
| All_var ;
DECL_STMT: DATA_TYPE variable_list TERMINATOR;
ASSIGN_STMT: All_var '=' EXP {cout << line_number << ": Assignment statement" << endl;} ;
LOOP: FOR VARIABLE ASSIGNMENT EXP ',' EXP '{' STMTS '}' {cout << line_number << ": FOR(v,v) stmt" << endl; free($2);}
| FOR VARIABLE ASSIGNMENT EXP ',' EXP ',' EXP '{' STMTS '}' {cout << line_number << ": FOR(v,v,v) stmt" << endl; free($2);}
| WHILE '(' EXP ')' '{' STMTS '}' {cout << line_number << ": WHILE stmt" << endl;} ;
CONTROL_STMT: IF '(' EXP ')' '{' STMTS '}' {cout << line_number << ": IF stmt" << endl;}
| IF '(' EXP ')' '{' STMTS '}' ELSE '{' STMTS '}' {cout << line_number << ": IF ELSE stmt" << endl;}
| IF '(' EXP ')' '{' STMTS '}' ELIF '(' EXP ')' '{' STMTS '}' ELSE '{' STMTS '}' {cout << line_number << ": IF ELIF ELSE stmt" << endl;}
| '(' EXP ')' '?' STMT ':' STMT {cout << line_number << ": Conditional IF stmt" << endl;} ;
parameter_list: DATA_TYPE VARIABLE ',' parameter_list {free($2);}
| DATA_TYPE VARIABLE {free($2);}
| DATA_TYPE VARIABLE '[' ']' ',' parameter_list {free($2);}
| DATA_TYPE VARIABLE '[' ']' {free($2);}
| ;
FUNC_DECL: DATA_TYPE function_name '(' parameter_list ')' '{' STMTS '}' {cout << line_number << ": Function declaration with parameters" << endl;}
| DATA_TYPE '[' ']' function_name '(' parameter_list ')' '{' STMTS '}' {cout << line_number << ": Function declaration with parameters" << endl;}
| TYPE_VOID function_name '(' parameter_list ')' '{' STMTS '}' {cout << line_number << ": Function declaration with parameters" << endl;} ;
function_name: VARIABLE {cout << line_number << ": User-defined function" << endl; free($1);}
| DATA_TYPE {cout << line_number << ": Predefined function" << endl;} ;
FUNC_CALL: function_name '(' arguments ')' {cout << line_number << ": Function call with arguments" << endl;} ;
arguments: EXP ',' arguments
| EXP
| ;
BREAK_STMT: BREAK {cout << line_number << ": BREAK Statement" << endl;} ;
RETURN_STMT: RETURN EXP {cout << line_number << ": RETURN with EXP" << endl;}
| RETURN {cout << line_number << ": RETURN without EXP" << endl;} ;
%%
int main(int, char**) {
FILE *myfile = fopen("./Test_Programs/Program-5.txt", "r");
if (!myfile) {
cout << "Error Opening File!" << endl;
return -1;
}
cout<<"\n";
yyin = myfile;
yyparse();
cout<<"\nSUCCESS!\n";
return 0;
}
void yyerror(const char *s) {
cout << "PARSE ERROR on line number " << line_number << "! Message: " << s << endl;
exit(line_number);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment