Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- %{
- void yyerror (char const *s);
- // int alpha_yylex (void* ylval);
- int yylex(void);
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "header.h"
- unsigned short int scope = 0;
- extern FILE* yyin;
- extern char yytext[];
- extern int yylineno;
- bool is_func_rule = false; //an o kanonas poy ekteleitai einai funcution definition
- unsigned int anon_func = 0; //metraei poses anonimes synarthseis yparxoyn
- vector <bool> isBlock;
- %}
- %union{
- int intVal;
- char *strVal;
- double realVal;
- int lineNum;
- struct node *exprNode;
- }
- %start program
- /*KEYWORDS*/
- %token IF ELSE WHILE FOR FUNCTION RETURN BREAK CONTINUE
- %token AND NOT OR
- %token LOCAL TRUE FALSE NIL
- %type <strVal> term expr assignexpr IF ELSE WHILE FOR FUNCTION RETURN BREAK CONTINUE AND NOT OR LOCAL TRUE FALSE NIL
- %type <strVal> '=' '+' '-' '*' '/' '%' EQ NE LT GT GE LE PLUSPLUS MINUSMINUS '{' '}' '[' ']' '(' ')' ';' ',' ':' '.'
- %type <strVal> COLONCOLON DOTDOT SINGLE_LINE_COMMENT NESTED_COMMENT lvalue member primary call objectdef const
- %token '=' '+' '-' '*' '/' '%'
- %token EQ NE LT GT GE LE PLUSPLUS MINUSMINUS
- %token '{' '}' '[' ']' '(' ')' ';' ',' ':' '.'
- %token COLONCOLON DOTDOT
- %token SINGLE_LINE_COMMENT NESTED_COMMENT
- %token <strVal> ID
- %token <strVal> INTEGER
- %token <strVal> REAL
- %token <strVal> STRING
- %token number
- %right '='
- %left OR
- %left AND
- %nonassoc EQ NE
- %nonassoc GT GE LT LE
- %left '+' '-'
- %left '*' '/' '%'
- %right NOT PLUSPLUS MINUSMINUS UMINUS
- %left '.' DOTDOT
- %left '[' ']'
- %left '(' ')'
- %%
- program: stmts
- ;
- stmts: stmts stmt
- | /*empty*/
- ;
- stmt: expr ';'
- | ifstmt
- | whilestmt
- | forstmt
- | returnstmt
- | BREAK ';'
- | CONTINUE';'
- | block
- | funcdef
- | ';'
- ;
- expr: assignexpr
- | expr '+' expr
- | expr '-' expr
- | expr '*' expr
- | expr '/' expr
- | expr '%' expr
- | expr GT expr
- | expr GE expr
- | expr LT expr
- | expr LE expr
- | expr EQ expr
- | expr NE expr
- | expr OR expr
- | expr AND expr
- | term
- ;
- // op: '+' | '-' | '*' | '/' | '%' | GT | GE | LT | LE | EQ | NE | AND | OR
- // ;
- term: '(' expr ')'
- | '-'expr %prec UMINUS
- | NOT expr
- | PLUSPLUS lvalue {
- node_t *symbol = look_up( create_key( $2) );
- if( symbol != NULL && ( (symbol->type == USER_FUNC) || (symbol->type == LIB_FUNC) ) ){
- cout << "Error: Function operation: \"++" << $2 << "\" prohibited." << " scope[" << scope << "]." << "in line[" << yylineno << "]." << endl;
- }
- }
- | lvalue PLUSPLUS {
- node_t *symbol = look_up( create_key( $2) );
- if( symbol != NULL && ( (symbol->type == USER_FUNC) || (symbol->type == LIB_FUNC) ) ){
- cout << "Error: Function operation: \"" << $2 << "++\" prohibited." << " scope[" << scope << "]." << "in line[" << yylineno << "]." << endl;
- }
- }
- | MINUSMINUS lvalue{ node_t *symbol = look_up( create_key( $2) );
- if( symbol != NULL && ( (symbol->type == USER_FUNC) || (symbol->type == LIB_FUNC) ) ){
- cout << "Error: Function operation: \"--" << $2 << "\" prohibited." << " scope[" << scope << "]." << "in line[" << yylineno << "]." << endl;
- }
- }
- | lvalue MINUSMINUS{ node_t *symbol = look_up( create_key( $2) );
- if( symbol != NULL && ( (symbol->type == USER_FUNC) || (symbol->type == LIB_FUNC) ) ){
- cout << "Error: Function operation: \"" << $2 << "--\" prohibited." << " scope[" << scope << "]." << "in line[" << yylineno << "]." << endl;
- }
- }
- | primary
- ;
- assignexpr: lvalue '=' expr{
- if($1!=NULL){
- node_t *symbol = look_up( create_key( $1 ) );
- if( symbol != NULL && ( (symbol->type == USER_FUNC) || (symbol->type == LIB_FUNC) ) ){
- cout << "Error: Function assignment operation: \"" << $1 << "\" prohibited." << " scope[" << scope << "]." << "in line[" << yylineno << "]." << endl;
- }
- }else{}//TODO:An gurnaei to lvalue apo COLONCOLON ID tote to $1 einai NULL kai gamietai
- }
- ;
- primary: lvalue
- | call
- | objectdef
- | '(' funcdef ')'
- | const
- ;
- lvalue: ID {
- node_t *symbol;
- node_t *lastsymbol=NULL;
- int i,j;
- bool error=false;
- string errorMsg="";
- bool errorFlag=false;
- for ( i = scope; i >= 0; i-- ){
- if ( (symbol=LookUp_Scope( $1 , i )) != NULL ){//to brika
- if( scope > symbol->scope && symbol->type!=FUNC_ARG && symbol->scope!=0 && symbol->type!=USER_FUNC){
- for(j=symbol->scope;j<scope;j++){
- // cout<<"isBlock="<<isBlock[j]<<endl;
- if(!isBlock[j]){
- error=true;
- break;
- }
- }
- if(error && !errorFlag){
- errorMsg+= "Error: Cannot access : \"";
- errorMsg+= $1;
- errorMsg+= "\".";
- errorMsg+= " scope[";
- errorMsg+= to_string(scope);
- errorMsg+= "].";
- errorMsg+= "in line[";
- errorMsg+= to_string(yylineno);
- errorMsg+= "].\n";
- error=false;
- errorFlag=true;
- }
- lastsymbol=symbol;
- if(error){
- break;
- }
- }
- }
- }
- if(lastsymbol){
- if(lastsymbol->scope == 0 || lastsymbol->scope == scope /*|| lastsymbol->type==USER_FUNC || lastsymbol->type==FUNC_ARG*/){
- cout<<"do nothing "<<$1<<endl;
- cout<<"\tlastsymbol->scope "<<lastsymbol->scope<<endl;
- cout<<"\tscope "<<scope<<endl;
- cout<<"\tlastsymbol->type "<<lastsymbol->type <<endl;
- // cout<<errorMsg<<endl;
- }
- else{
- cout<<errorMsg;
- }
- }else{
- // cout<<"insert "<<$1<<endl;
- insert(create_key($1 ) , true, $1, (scope > 0 ? LOCAL_VAR : GLOBAL_VAR) , scope , yylineno , NULL );
- }
- }
- | LOCAL ID {
- node_t *symbol=LookUp_Scope( $2 , scope );
- if ( (symbol == NULL )&& (is_lib_func($2)==false)){//den to brika kai den einai libfunc
- insert(create_key($2 ) , true, $2, (scope > 0 ? LOCAL_VAR : GLOBAL_VAR) , scope , yylineno , NULL );
- $<exprNode>$ = symbol;
- }
- else{
- $<exprNode>$ = symbol;//TODO
- }
- }
- | COLONCOLON ID {
- node_t *symbol;
- if ( (symbol=LookUp_Scope( $2 , 0 )) == NULL ){//den to brika
- $<exprNode>$ = symbol;
- cout << "Error: Not found: \"" << $2 << "\" in global scope." << " scope[" << scope << "]." << "in line[" << yylineno << "]." << endl;
- }
- else{
- $<exprNode>$ = symbol;//TODO
- }
- }
- | member
- ;
- member: lvalue'.'ID
- | lvalue '[' expr ']'
- | call'.'ID
- | call '[' expr ']'
- ;
- call: call '(' elist ')' {/*printf("Call elist\n");*/}
- | lvalue callsuffix {/*printf("Lvalue Callsuffix\n");*/}
- | '(' funcdef ')' '(' elist ')' {/*printf("Funcdef elist\n");*/}
- ;
- callsuffix: normcall {/*printf("normcall\n");*/}
- | methodcall {/*printf("methodcall\n");*/}
- ;
- normcall: '(' elist ')' {/*printf("( elist )\n");*/}
- ;
- methodcall: DOTDOT ID '(' elist ')' /*equivalent to lvalue.id(lvalue, elist)*/
- ;
- elist: expr {/*printf("What\n");*/}
- | elist ',' expr {/*printf("Recursive call elist , expr \n");*/}
- |
- ;
- objectdef: '[' elist ']' {/*printf("elist\n");*/}
- | '[' indexed ']' {/*printf("indexed\n");*/}
- ;
- indexed: indexedelem
- | indexed ',' indexedelem
- ;
- indexedelem: '{' expr ':' expr '}'
- ;
- block: '{'{
- scope++;
- if( is_func_rule == true ){
- isBlock.push_back(false);
- }else{
- isBlock.push_back(true);
- }
- }
- stmts
- '}'{
- if( is_func_rule == true ){
- is_func_rule = false;
- active_func_name.pop_back();
- }
- set_is_active(scope , false );
- isBlock.pop_back();
- scope--;
- }
- ;
- funcdef: FUNCTION { is_func_rule = true; } ID_OR_NOT '(' {scope++; } idlist')'{scope--;} block {/*printf("Funcdef\n");*/}
- ;
- ID_OR_NOT: ID {
- active_func_name.push_back($1);
- node_t *symbol = LookUp_Scope($1 , scope);
- if( symbol != NULL ){//brhka func h var me to idio ID(onoma)
- cout << "Error: Function name: \"" << $1 << "\" exists!" << " scope[" << scope << "]." << "in line[" << yylineno << "]." << endl;
- goto END;
- }
- if ( is_lib_func( $1 ) == false ){
- insert(create_key("") , true, $1, USER_FUNC , scope , yylineno , NULL );
- }
- END: ;
- }
- | { anon_func++;
- active_func_name.push_back("$" + to_string(anon_func));
- insert(create_key("") , true, "$" + to_string(anon_func), USER_FUNC , scope , yylineno , NULL );
- }
- ;
- const: INTEGER | STRING | NIL | TRUE | FALSE | REAL
- ;
- idlist: ID {
- node_t *symbol = LookUp_Scope($1 , scope);
- if( symbol != NULL ){//brhka func h var me to idio ID(onoma)
- cout << "Error: Argument name: \"" << $1 << "\" exists!" << " scope[" << scope << "]." << "in line[" << symbol->line_num << "]." << endl;
- goto END1;
- }
- if ( is_lib_func( $1 ) == false ){
- insert(create_key($1 ) , true, $1, FUNC_ARG , scope , yylineno , NULL );
- }
- END1: ;
- }
- | idlist ',' ID {
- node_t *symbol = LookUp_Scope($3 , scope);
- if( symbol != NULL ){//brhka func h var me to idio ID(onoma)
- cout << "Error: Argument name: \"" << $3 << "\" exists!" << " scope[" << scope << "]." << "in line[" << symbol->line_num << "]." << endl;
- goto END2;
- }
- if ( is_lib_func( $3 ) == false ){
- insert(create_key($3 ) , true, $3, FUNC_ARG , scope , yylineno , NULL );
- }
- END2: ;
- }
- |
- ;
- ifstmt: IF '(' expr ')' stmt else
- ;
- else: ELSE stmt
- |
- ;
- whilestmt: WHILE '(' expr ')' stmt {/*printf("whilestmt\n");*/}
- ;
- forstmt: FOR '(' elist ';' expr ';' elist ')' stmt {/*printf("for statement\n");*/}
- ;
- returnstmt: RETURN expr ';'
- | RETURN ';'
- ;
- %%
- void yyerror(char const *s)
- {
- fflush(stdout);
- fprintf(stderr , "yyerror! line:[%d] [%s]\n" ,yylineno, s );
- }
- int main(int argc, char *argv[])
- {
- // #ifdef YYDEBUG
- // yydebug = 1;
- // #endif
- // FILE* yyout;
- if(argc>1){
- if(!(yyin=fopen(argv[1],"r"))){
- fprintf(stderr, "Cannot read file : %s\n",argv[1]);
- return 1;
- }
- }
- else
- yyin = stdin;
- // yyout = (argc>2) ? fopen("argv[2]","w") : 0;
- init_SymTable();
- yyparse();
- print_SymTable();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement