Advertisement
Guest User

Untitled

a guest
Mar 25th, 2019
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.60 KB | None | 0 0
  1. %{
  2. void yyerror (char const *s);
  3. // int alpha_yylex (void* ylval);
  4. int yylex(void);
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8.  
  9. #include "header.h"
  10.  
  11. unsigned short int scope = 0;
  12.  
  13. extern FILE* yyin;
  14. extern char yytext[];
  15. extern int yylineno;
  16.  
  17. bool is_func_rule = false; //an o kanonas poy ekteleitai einai funcution definition
  18. unsigned int anon_func = 0; //metraei poses anonimes synarthseis yparxoyn
  19.  
  20. vector <bool> isBlock;
  21. %}
  22.  
  23. %union{
  24. int intVal;
  25. char *strVal;
  26. double realVal;
  27. int lineNum;
  28. struct node *exprNode;
  29. }
  30.  
  31. %start program
  32.  
  33. /*KEYWORDS*/
  34. %token IF ELSE WHILE FOR FUNCTION RETURN BREAK CONTINUE
  35. %token AND NOT OR
  36. %token LOCAL TRUE FALSE NIL
  37.  
  38. %type <strVal> term expr assignexpr IF ELSE WHILE FOR FUNCTION RETURN BREAK CONTINUE AND NOT OR LOCAL TRUE FALSE NIL
  39. %type <strVal> '=' '+' '-' '*' '/' '%' EQ NE LT GT GE LE PLUSPLUS MINUSMINUS '{' '}' '[' ']' '(' ')' ';' ',' ':' '.'
  40. %type <strVal> COLONCOLON DOTDOT SINGLE_LINE_COMMENT NESTED_COMMENT lvalue member primary call objectdef const
  41.  
  42. %token '=' '+' '-' '*' '/' '%'
  43.  
  44. %token EQ NE LT GT GE LE PLUSPLUS MINUSMINUS
  45.  
  46. %token '{' '}' '[' ']' '(' ')' ';' ',' ':' '.'
  47.  
  48. %token COLONCOLON DOTDOT
  49.  
  50. %token SINGLE_LINE_COMMENT NESTED_COMMENT
  51.  
  52. %token <strVal> ID
  53. %token <strVal> INTEGER
  54. %token <strVal> REAL
  55. %token <strVal> STRING
  56.  
  57. %token number
  58.  
  59. %right '='
  60. %left OR
  61. %left AND
  62. %nonassoc EQ NE
  63. %nonassoc GT GE LT LE
  64. %left '+' '-'
  65. %left '*' '/' '%'
  66. %right NOT PLUSPLUS MINUSMINUS UMINUS
  67. %left '.' DOTDOT
  68. %left '[' ']'
  69. %left '(' ')'
  70.  
  71.  
  72. %%
  73. program: stmts
  74. ;
  75.  
  76. stmts: stmts stmt
  77. | /*empty*/
  78. ;
  79.  
  80.  
  81. stmt: expr ';'
  82. | ifstmt
  83. | whilestmt
  84. | forstmt
  85. | returnstmt
  86. | BREAK ';'
  87. | CONTINUE';'
  88. | block
  89. | funcdef
  90. | ';'
  91. ;
  92.  
  93. expr: assignexpr
  94. | expr '+' expr
  95. | expr '-' expr
  96. | expr '*' expr
  97. | expr '/' expr
  98. | expr '%' expr
  99. | expr GT expr
  100. | expr GE expr
  101. | expr LT expr
  102. | expr LE expr
  103. | expr EQ expr
  104. | expr NE expr
  105. | expr OR expr
  106. | expr AND expr
  107. | term
  108. ;
  109.  
  110. // op: '+' | '-' | '*' | '/' | '%' | GT | GE | LT | LE | EQ | NE | AND | OR
  111. // ;
  112.  
  113.  
  114. term: '(' expr ')'
  115. | '-'expr %prec UMINUS
  116. | NOT expr
  117. | PLUSPLUS lvalue {
  118. node_t *symbol = look_up( create_key( $2) );
  119. if( symbol != NULL && ( (symbol->type == USER_FUNC) || (symbol->type == LIB_FUNC) ) ){
  120. cout << "Error: Function operation: \"++" << $2 << "\" prohibited." << " scope[" << scope << "]." << "in line[" << yylineno << "]." << endl;
  121. }
  122. }
  123. | lvalue PLUSPLUS {
  124. node_t *symbol = look_up( create_key( $2) );
  125. if( symbol != NULL && ( (symbol->type == USER_FUNC) || (symbol->type == LIB_FUNC) ) ){
  126. cout << "Error: Function operation: \"" << $2 << "++\" prohibited." << " scope[" << scope << "]." << "in line[" << yylineno << "]." << endl;
  127. }
  128. }
  129. | MINUSMINUS lvalue{ node_t *symbol = look_up( create_key( $2) );
  130. if( symbol != NULL && ( (symbol->type == USER_FUNC) || (symbol->type == LIB_FUNC) ) ){
  131. cout << "Error: Function operation: \"--" << $2 << "\" prohibited." << " scope[" << scope << "]." << "in line[" << yylineno << "]." << endl;
  132. }
  133. }
  134. | lvalue MINUSMINUS{ node_t *symbol = look_up( create_key( $2) );
  135. if( symbol != NULL && ( (symbol->type == USER_FUNC) || (symbol->type == LIB_FUNC) ) ){
  136. cout << "Error: Function operation: \"" << $2 << "--\" prohibited." << " scope[" << scope << "]." << "in line[" << yylineno << "]." << endl;
  137. }
  138. }
  139. | primary
  140. ;
  141.  
  142. assignexpr: lvalue '=' expr{
  143.  
  144. if($1!=NULL){
  145. node_t *symbol = look_up( create_key( $1 ) );
  146. if( symbol != NULL && ( (symbol->type == USER_FUNC) || (symbol->type == LIB_FUNC) ) ){
  147. cout << "Error: Function assignment operation: \"" << $1 << "\" prohibited." << " scope[" << scope << "]." << "in line[" << yylineno << "]." << endl;
  148. }
  149. }else{}//TODO:An gurnaei to lvalue apo COLONCOLON ID tote to $1 einai NULL kai gamietai
  150. }
  151. ;
  152.  
  153.  
  154. primary: lvalue
  155. | call
  156. | objectdef
  157. | '(' funcdef ')'
  158. | const
  159. ;
  160.  
  161. lvalue: ID {
  162. node_t *symbol;
  163. node_t *lastsymbol=NULL;
  164. int i,j;
  165. bool error=false;
  166. string errorMsg="";
  167. bool errorFlag=false;
  168. for ( i = scope; i >= 0; i-- ){
  169. if ( (symbol=LookUp_Scope( $1 , i )) != NULL ){//to brika
  170. if( scope > symbol->scope && symbol->type!=FUNC_ARG && symbol->scope!=0 && symbol->type!=USER_FUNC){
  171. for(j=symbol->scope;j<scope;j++){
  172. // cout<<"isBlock="<<isBlock[j]<<endl;
  173. if(!isBlock[j]){
  174. error=true;
  175. break;
  176. }
  177. }
  178.  
  179. if(error && !errorFlag){
  180. errorMsg+= "Error: Cannot access : \"";
  181. errorMsg+= $1;
  182. errorMsg+= "\".";
  183. errorMsg+= " scope[";
  184. errorMsg+= to_string(scope);
  185. errorMsg+= "].";
  186. errorMsg+= "in line[";
  187. errorMsg+= to_string(yylineno);
  188. errorMsg+= "].\n";
  189.  
  190. error=false;
  191. errorFlag=true;
  192. }
  193. lastsymbol=symbol;
  194. if(error){
  195. break;
  196. }
  197. }
  198. }
  199. }
  200. if(lastsymbol){
  201. if(lastsymbol->scope == 0 || lastsymbol->scope == scope /*|| lastsymbol->type==USER_FUNC || lastsymbol->type==FUNC_ARG*/){
  202. cout<<"do nothing "<<$1<<endl;
  203. cout<<"\tlastsymbol->scope "<<lastsymbol->scope<<endl;
  204. cout<<"\tscope "<<scope<<endl;
  205. cout<<"\tlastsymbol->type "<<lastsymbol->type <<endl;
  206.  
  207. // cout<<errorMsg<<endl;
  208. }
  209. else{
  210. cout<<errorMsg;
  211. }
  212. }else{
  213. // cout<<"insert "<<$1<<endl;
  214. insert(create_key($1 ) , true, $1, (scope > 0 ? LOCAL_VAR : GLOBAL_VAR) , scope , yylineno , NULL );
  215. }
  216.  
  217.  
  218.  
  219. }
  220.  
  221. | LOCAL ID {
  222.  
  223. node_t *symbol=LookUp_Scope( $2 , scope );
  224.  
  225. if ( (symbol == NULL )&& (is_lib_func($2)==false)){//den to brika kai den einai libfunc
  226. insert(create_key($2 ) , true, $2, (scope > 0 ? LOCAL_VAR : GLOBAL_VAR) , scope , yylineno , NULL );
  227. $<exprNode>$ = symbol;
  228. }
  229. else{
  230.  
  231. $<exprNode>$ = symbol;//TODO
  232. }
  233. }
  234. | COLONCOLON ID {
  235. node_t *symbol;
  236. if ( (symbol=LookUp_Scope( $2 , 0 )) == NULL ){//den to brika
  237. $<exprNode>$ = symbol;
  238. cout << "Error: Not found: \"" << $2 << "\" in global scope." << " scope[" << scope << "]." << "in line[" << yylineno << "]." << endl;
  239. }
  240. else{
  241. $<exprNode>$ = symbol;//TODO
  242. }
  243. }
  244. | member
  245. ;
  246.  
  247. member: lvalue'.'ID
  248. | lvalue '[' expr ']'
  249. | call'.'ID
  250. | call '[' expr ']'
  251. ;
  252.  
  253. call: call '(' elist ')' {/*printf("Call elist\n");*/}
  254. | lvalue callsuffix {/*printf("Lvalue Callsuffix\n");*/}
  255. | '(' funcdef ')' '(' elist ')' {/*printf("Funcdef elist\n");*/}
  256. ;
  257.  
  258. callsuffix: normcall {/*printf("normcall\n");*/}
  259. | methodcall {/*printf("methodcall\n");*/}
  260. ;
  261.  
  262. normcall: '(' elist ')' {/*printf("( elist )\n");*/}
  263. ;
  264.  
  265. methodcall: DOTDOT ID '(' elist ')' /*equivalent to lvalue.id(lvalue, elist)*/
  266. ;
  267.  
  268. elist: expr {/*printf("What\n");*/}
  269. | elist ',' expr {/*printf("Recursive call elist , expr \n");*/}
  270. |
  271. ;
  272.  
  273. objectdef: '[' elist ']' {/*printf("elist\n");*/}
  274. | '[' indexed ']' {/*printf("indexed\n");*/}
  275. ;
  276.  
  277. indexed: indexedelem
  278. | indexed ',' indexedelem
  279. ;
  280.  
  281. indexedelem: '{' expr ':' expr '}'
  282. ;
  283.  
  284. block: '{'{
  285. scope++;
  286. if( is_func_rule == true ){
  287. isBlock.push_back(false);
  288. }else{
  289. isBlock.push_back(true);
  290. }
  291.  
  292. }
  293. stmts
  294. '}'{
  295. if( is_func_rule == true ){
  296. is_func_rule = false;
  297. active_func_name.pop_back();
  298. }
  299.  
  300.  
  301. set_is_active(scope , false );
  302. isBlock.pop_back();
  303. scope--;
  304. }
  305. ;
  306.  
  307. funcdef: FUNCTION { is_func_rule = true; } ID_OR_NOT '(' {scope++; } idlist')'{scope--;} block {/*printf("Funcdef\n");*/}
  308. ;
  309.  
  310. ID_OR_NOT: ID {
  311. active_func_name.push_back($1);
  312. node_t *symbol = LookUp_Scope($1 , scope);
  313. if( symbol != NULL ){//brhka func h var me to idio ID(onoma)
  314. cout << "Error: Function name: \"" << $1 << "\" exists!" << " scope[" << scope << "]." << "in line[" << yylineno << "]." << endl;
  315. goto END;
  316. }
  317.  
  318. if ( is_lib_func( $1 ) == false ){
  319. insert(create_key("") , true, $1, USER_FUNC , scope , yylineno , NULL );
  320. }
  321.  
  322. END: ;
  323. }
  324. | { anon_func++;
  325. active_func_name.push_back("$" + to_string(anon_func));
  326. insert(create_key("") , true, "$" + to_string(anon_func), USER_FUNC , scope , yylineno , NULL );
  327. }
  328. ;
  329.  
  330. const: INTEGER | STRING | NIL | TRUE | FALSE | REAL
  331. ;
  332.  
  333. idlist: ID {
  334. node_t *symbol = LookUp_Scope($1 , scope);
  335. if( symbol != NULL ){//brhka func h var me to idio ID(onoma)
  336. cout << "Error: Argument name: \"" << $1 << "\" exists!" << " scope[" << scope << "]." << "in line[" << symbol->line_num << "]." << endl;
  337. goto END1;
  338. }
  339.  
  340. if ( is_lib_func( $1 ) == false ){
  341. insert(create_key($1 ) , true, $1, FUNC_ARG , scope , yylineno , NULL );
  342. }
  343.  
  344. END1: ;
  345.  
  346. }
  347. | idlist ',' ID {
  348. node_t *symbol = LookUp_Scope($3 , scope);
  349. if( symbol != NULL ){//brhka func h var me to idio ID(onoma)
  350.  
  351. cout << "Error: Argument name: \"" << $3 << "\" exists!" << " scope[" << scope << "]." << "in line[" << symbol->line_num << "]." << endl;
  352. goto END2;
  353.  
  354. }
  355.  
  356. if ( is_lib_func( $3 ) == false ){
  357. insert(create_key($3 ) , true, $3, FUNC_ARG , scope , yylineno , NULL );
  358. }
  359.  
  360. END2: ;
  361. }
  362. |
  363. ;
  364.  
  365. ifstmt: IF '(' expr ')' stmt else
  366. ;
  367.  
  368. else: ELSE stmt
  369. |
  370. ;
  371.  
  372. whilestmt: WHILE '(' expr ')' stmt {/*printf("whilestmt\n");*/}
  373. ;
  374.  
  375. forstmt: FOR '(' elist ';' expr ';' elist ')' stmt {/*printf("for statement\n");*/}
  376. ;
  377.  
  378. returnstmt: RETURN expr ';'
  379. | RETURN ';'
  380. ;
  381.  
  382.  
  383. %%
  384.  
  385. void yyerror(char const *s)
  386. {
  387. fflush(stdout);
  388. fprintf(stderr , "yyerror! line:[%d] [%s]\n" ,yylineno, s );
  389. }
  390.  
  391.  
  392. int main(int argc, char *argv[])
  393. {
  394.  
  395. // #ifdef YYDEBUG
  396. // yydebug = 1;
  397. // #endif
  398.  
  399. // FILE* yyout;
  400. if(argc>1){
  401. if(!(yyin=fopen(argv[1],"r"))){
  402. fprintf(stderr, "Cannot read file : %s\n",argv[1]);
  403. return 1;
  404. }
  405. }
  406. else
  407. yyin = stdin;
  408. // yyout = (argc>2) ? fopen("argv[2]","w") : 0;
  409. init_SymTable();
  410. yyparse();
  411. print_SymTable();
  412. return 0;
  413. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement