PageRenderTime 52ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/Lexical Analyzer/Lexical_Ana_C/prog1.c

https://github.com/rjsikarwar/compiler
C | 991 lines | 920 code | 47 blank | 24 comment | 36 complexity | 6cf8ae1b78774a06394fed0172f09075 MD5 | raw file
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <malloc.h>
  4. #define push(s) *stackp++ = s
  5. #define pop() *--stackp
  6. int tot_size=0,cnt,key_cnt=0,par_cnt=0,del_cnt=0,relop_cnt=0,punc_cnt=0,op_cnt=0,id_cnt=0,l_cnt=0,d_cnt=0;
  7. char keywords[20][20],par[20],delimiter[20],relop[3][20],punctuation[20],operators[20],identifiers[100],numbers[100],config[1000],program[1000];
  8. char L[100],D[100];
  9. //STORING THE LIST OF POSITIONS FOR EACH OF THE TOKENS (SINCE ONE TOKEN CAN OCCUR IN VARIOUS LOCATIONS, THUS LINKED LIST)
  10. typedef struct loc loc;
  11. struct loc
  12. {
  13. int row,col;
  14. loc *next2;
  15. };
  16. //STRUCTURE FOR THE SYMBOL TABLE WHICH IS STORED AS A SINGLY LINKED LIST
  17. typedef struct sym_tab sym_tab;
  18. struct sym_tab
  19. {
  20. char token[100];
  21. int type; //1-keyword,2-parenthesis,3-relational operator,4-operator,5-identifier,6-number,7-literal
  22. loc *list;
  23. sym_tab *next1;
  24. };
  25. sym_tab *table;
  26. //CONVERT INFIX EXPRESSION IN INPUT FILE TO POSTFIX EXPRESSION
  27. void infix_postfix(char *inf,char *final)
  28. {
  29. int length=strlen(inf);
  30. int i,j=0,k=0,cnt=0,cur=0;
  31. char st_sym[100];
  32. for(i=0;i<length;i++)
  33. {
  34. if(inf[i]=='(')
  35. {
  36. cnt++;
  37. }
  38. else if(inf[i]==')')
  39. {
  40. final[cur]=st_sym[k-1];
  41. k--;
  42. cur++;
  43. }
  44. else if(inf[i]=='.' || inf[i]=='*' || inf[i]=='?' || inf[i]=='|' || inf[i]=='+')
  45. {
  46. st_sym[k]=inf[i];
  47. k++;
  48. }
  49. else
  50. {
  51. final[cur]=inf[i];
  52. cur++;
  53. }
  54. }
  55. final[cur]='\0';
  56. }
  57. //IF MATCH, THEN FINAL STATE, ELSE IF SPLIT THEN TWO EDGES OUT OF THIS STATE, ELSE ON 'c' THERE IS A TRANSITION
  58. enum
  59. {
  60. Match = 256,
  61. Split = 257
  62. };
  63. //STRUCTURE FOR EACH STATE
  64. typedef struct State State;
  65. struct State
  66. {
  67. int c; //IF THERE IS A TRANSITION, THEN IT IS ON THIS CHARACTER
  68. State *out; //TRANSITION INTO STATE 1
  69. State *out1; //TRANSITION INTO STATE 2
  70. int lastlist;
  71. };
  72. //FINAL MATCHING STATE
  73. State matchstate = { Match };
  74. int nstate; //NUMBER OF STATES
  75. //INITIALIZE STATE
  76. State*
  77. state(int c, State *out, State *out1)
  78. {
  79. State *s;
  80. nstate++; //INCREASE TOTAL COUNT OF STATES
  81. s = malloc(sizeof *s);
  82. s->lastlist = 0;
  83. s->c = c;
  84. s->out = out;
  85. s->out1 = out1;
  86. return s; //RETURN NEWLY ALLOTED STATE
  87. }
  88. //FRAG MAINTAINS THE NFA AS IT IS BUILDING UP(i.e. WITHOUT THE FINAL STATE)
  89. typedef struct Frag Frag;
  90. typedef union Ptrlist Ptrlist;
  91. struct Frag
  92. {
  93. State *start; //START STATE
  94. Ptrlist *out; //LIST OF TRANSITIONS OUT OF THIS STATE
  95. };
  96. //INITIALIZE THE FRAG STRUCTURE
  97. Frag
  98. frag(State *start, Ptrlist *out)
  99. {
  100. Frag n = { start, out };
  101. return n;
  102. }
  103. //STORING THE LISTS
  104. union Ptrlist
  105. {
  106. Ptrlist *next;
  107. State *s;
  108. };
  109. //CREATE A SINGLE LIST
  110. Ptrlist*
  111. list1(State **outp)
  112. {
  113. Ptrlist *l;
  114. l = (Ptrlist*)outp;
  115. l->next = NULL;
  116. return l;
  117. }
  118. //MODIFY OUT POINTERS FROM STATE TO POINT TO START
  119. void
  120. patch(Ptrlist *l, State *s)
  121. {
  122. Ptrlist *next;
  123. for(; l; l=next){
  124. next = l->next;
  125. l->s = s;
  126. }
  127. }
  128. //JOIN TWO LISTS
  129. Ptrlist*
  130. append(Ptrlist *l1, Ptrlist *l2)
  131. {
  132. Ptrlist *oldl1;
  133. oldl1 = l1;
  134. while(l1->next)
  135. l1 = l1->next;
  136. l1->next = l2;
  137. return oldl1;
  138. }
  139. //CONVERT POSTFIX EXPRESSION TO NFA
  140. State*
  141. post2nfa(char *postfix)
  142. {
  143. char *p;
  144. Frag stack[1000], *stackp, e1, e2, e;
  145. State *s;
  146. if(postfix == NULL)
  147. return NULL;
  148. stackp = stack;
  149. for(p=postfix; *p; p++){
  150. switch(*p){
  151. default:
  152. s = state(*p, NULL, NULL);
  153. push(frag(s, list1(&s->out)));
  154. break;
  155. case '.': //CONCATE
  156. e2 = pop();
  157. e1 = pop();
  158. patch(e1.out, e2.start);
  159. push(frag(e1.start, e2.out));
  160. break;
  161. case '|': //UNION
  162. e2 = pop();
  163. e1 = pop();
  164. s = state(Split, e1.start, e2.start);
  165. push(frag(s, append(e1.out, e2.out)));
  166. break;
  167. case '?': //0 OR 1
  168. e = pop();
  169. s = state(Split, e.start, NULL);
  170. push(frag(s, append(e.out, list1(&s->out1))));
  171. break;
  172. case '*': //0 OR MORE
  173. e = pop();
  174. s = state(Split, e.start, NULL);
  175. patch(e.out, s);
  176. push(frag(s, list1(&s->out1)));
  177. break;
  178. case '+': //1 OR MORE
  179. e = pop();
  180. s = state(Split, e.start, NULL);
  181. patch(e.out, s);
  182. push(frag(e.start, list1(&s->out1)));
  183. break;
  184. }
  185. }
  186. e = pop();
  187. if(stackp != stack)
  188. return NULL;
  189. patch(e.out, &matchstate);
  190. return e.start;
  191. }
  192. //STRUCTURE TO MAINTAIN LIST OF STATES
  193. typedef struct List List;
  194. struct List
  195. {
  196. State **s;
  197. int n;
  198. };
  199. List l1, l2, l3, l4; //2 FOR IDENTIFIERS, 2 FOR NUMBERS
  200. static int listid;
  201. void addstate(List*, State*);
  202. void step(List*, int, List*);
  203. //ADDS LIST L TO STATE
  204. List*
  205. startlist(State *start, List *l)
  206. {
  207. l->n = 0;
  208. listid++;
  209. addstate(l, start);
  210. return l;
  211. }
  212. //CHECKS IF STATE LIST CONTAINS A FINAL STATE
  213. int
  214. ismatch(List *l)
  215. {
  216. int i;
  217. for(i=0; i<l->n; i++)
  218. if(l->s[i] == &matchstate)
  219. return 1;
  220. return 0;
  221. }
  222. //ADDS STATE TO LIST
  223. void
  224. addstate(List *l, State *s)
  225. {
  226. if(s == NULL || s->lastlist == listid)
  227. return;
  228. s->lastlist = listid;
  229. if(s->c == Split){
  230. /* follow unlabeled arrows */
  231. addstate(l, s->out);
  232. addstate(l, s->out1);
  233. return;
  234. }
  235. l->s[l->n++] = s;
  236. }
  237. //FROM clist ON CHARACTER 'c' GET NEW LISTS nlist
  238. void
  239. step(List *clist, int c, List *nlist)
  240. {
  241. int i;
  242. State *s;
  243. listid++;
  244. nlist->n = 0;
  245. for(i=0; i<clist->n; i++){
  246. s = clist->s[i];
  247. if(s->c == c)
  248. addstate(nlist, s->out);
  249. }
  250. }
  251. //CHECK WHETHER STRING 's' CAN BE SIMULATED USING THE NFA
  252. int
  253. match(State *start, char *s,int op)
  254. {
  255. int i, c;
  256. List *clist, *nlist, *t;
  257. if(op==1)
  258. {
  259. clist = startlist(start, &l1);
  260. nlist = &l2;
  261. }
  262. else
  263. {
  264. clist = startlist(start, &l3);
  265. nlist = &l4;
  266. }
  267. for(; *s; s++){
  268. c = *s & 0xFF;
  269. step(clist, c, nlist);
  270. t = clist; clist = nlist; nlist = t; //SWAPS THE LIST
  271. }
  272. return ismatch(clist);
  273. }
  274. //CHECKS FOR DELIMITERS DEFINED IN config.txt
  275. int check_delimiter(char t)
  276. {
  277. int flag=-1,i;
  278. for(i=0;i<del_cnt;i++)
  279. {
  280. if(t==delimiter[i])
  281. flag=i;
  282. }
  283. return flag;
  284. }
  285. //CHECKS FOR PARENTHESIS DEFINED IN config.txt
  286. int check_parenthesis(char t)
  287. {
  288. int flag=-1,i;
  289. for(i=0;i<par_cnt;i++)
  290. {
  291. if(t==par[i])
  292. flag=i;
  293. }
  294. return flag;
  295. }
  296. //CHECKS FOR QUOTES DEFINED IN config.txt
  297. int check_quotes(char t)
  298. {
  299. int flag=-1,i;
  300. if(t=='\'' || t=='"')
  301. flag=1;
  302. return flag;
  303. }
  304. //CHECKS FOR KEYWORDS DEFINED IN config.txt
  305. int keyword_search(char *token)
  306. {
  307. int i,j,flag=-1,mat=0,len=strlen(token);
  308. for(i=0;i<key_cnt;i++)
  309. {
  310. mat=0;
  311. for(j=0;j<strlen(keywords[i]);j++)
  312. {
  313. if(j<=len && keywords[i][j]==token[j])
  314. mat++;
  315. }
  316. if(mat==strlen(keywords[i]))
  317. {
  318. flag=i;
  319. i=key_cnt;
  320. }
  321. }
  322. return flag;
  323. }
  324. //CHECKS FOR RELATIONAL OPERATORS DEFINED IN config.txt
  325. int relop_search(char *token)
  326. {
  327. int i,j,flag=-1,mat=0,len=strlen(token);
  328. for(i=0;i<relop_cnt;i++)
  329. {
  330. mat=0;
  331. for(j=0;j<strlen(relop[i]);j++)
  332. {
  333. if(j<=len && relop[i][j]==token[j])
  334. mat++;
  335. }
  336. if(mat==strlen(relop[i]))
  337. {
  338. flag=i;
  339. i=key_cnt;
  340. }
  341. }
  342. return flag;
  343. }
  344. //CHECKS FOR OPERATORS DEFINED IN config.txt
  345. int op_search(char *token)
  346. {
  347. int i,j,flag=-1,mat=0,len=strlen(token);
  348. for(i=0;i<op_cnt;i++)
  349. {
  350. mat=0;
  351. if(j<=len && operators[i]==token[0])
  352. mat++;
  353. if(strlen(token)==1 && mat==1)
  354. {
  355. flag=i;
  356. i=key_cnt;
  357. }
  358. }
  359. return flag;
  360. }
  361. //THIS FUNCTION SAVES THE TOKEN (ITS TYPE, ETC.) INTO THE LINKED LIST
  362. void save_list(char *temp,int type,int row,int col)
  363. {
  364. if(table==NULL)
  365. {
  366. table=(sym_tab *)malloc(sizeof(sym_tab));
  367. table->next1=NULL;
  368. strcpy(table->token,temp);
  369. table->type=type;
  370. loc *t12;
  371. t12=(loc *)malloc(sizeof(loc));
  372. t12->row=row;
  373. t12->col=col;
  374. t12->next2=NULL;
  375. table->list=t12;
  376. }
  377. else
  378. {
  379. sym_tab *t123,*last;
  380. t123=table;
  381. int fl=0;
  382. while(t123!=NULL)
  383. {
  384. if(t123->type==type)
  385. {
  386. if(strcmp(t123->token,temp)==0)
  387. break;
  388. }
  389. last=t123;
  390. t123=t123->next1;
  391. }
  392. if(t123!=NULL)
  393. {
  394. loc *t12;
  395. t12=(loc *)malloc(sizeof(loc));
  396. t12->row=row;
  397. t12->col=col;
  398. t12->next2=NULL;
  399. loc *l123;
  400. l123=t123->list;
  401. while(l123->next2!=NULL)
  402. {
  403. l123=l123->next2;
  404. }
  405. l123->next2=t12;
  406. }
  407. else
  408. {
  409. sym_tab *table1;
  410. table1=(sym_tab *)malloc(sizeof(sym_tab));
  411. table1->next1=NULL;
  412. strcpy(table1->token,temp);
  413. table1->type=type;
  414. loc *t12;
  415. t12=(loc *)malloc(sizeof(loc));
  416. t12->row=row;
  417. t12->col=col;
  418. t12->next2=NULL;
  419. table1->list=t12;
  420. last->next1=table1;
  421. }
  422. }
  423. }
  424. int main()
  425. {
  426. char regex[100],final[100],input[10][10],post_num[100],post_id[100];
  427. int i,flag_rd=0,flag_cur=0,flag_box=0;
  428. State *start_id,*start_num;
  429. table=NULL;
  430. char temp[20],c;
  431. char token[1000];
  432. int j,k,l,m,n;
  433. FILE *fp,*pro,*output,*error_file;
  434. //READ FROM config.txt
  435. fp = fopen("config.txt","r");
  436. c = getc(fp) ;
  437. while (c!= EOF)
  438. {
  439. config[tot_size]=c;
  440. tot_size++;
  441. c = getc(fp);
  442. }
  443. fclose(fp);
  444. i=0;
  445. //SKIP ALL THE COMMENTS
  446. while(!(config[i]=='-' && config[i+1]=='>'))
  447. {
  448. i++;
  449. }
  450. //ARRAY 'L'
  451. while(!(config[i]=='L' && config[i+1]==':'))
  452. i++;
  453. i=i+3;
  454. cnt=0;
  455. while(config[i]!='\n')
  456. {
  457. if(config[i]==',')
  458. {
  459. temp[cnt]='\0';
  460. L[l_cnt]=temp[0];
  461. l_cnt++;
  462. cnt=0;
  463. }
  464. else
  465. {
  466. temp[cnt]=config[i];
  467. cnt++;
  468. }
  469. i++;
  470. }
  471. //ARRAY 'D'
  472. while(!(config[i]=='D' && config[i+1]==':'))
  473. i++;
  474. i=i+3;
  475. cnt=0;
  476. while(config[i]!='\n')
  477. {
  478. if(config[i]==',')
  479. {
  480. temp[cnt]='\0';
  481. D[d_cnt]=temp[0];
  482. d_cnt++;
  483. cnt=0;
  484. }
  485. else
  486. {
  487. temp[cnt]=config[i];
  488. cnt++;
  489. }
  490. i++;
  491. }
  492. //KEYWORDS
  493. while(!(config[i]=='k' && config[i+1]=='e' && config[i+2]=='y'))
  494. {
  495. i++;
  496. }
  497. i+=10;
  498. cnt=0;
  499. while(config[i]!='\n')
  500. {
  501. if(config[i]==',')
  502. {
  503. temp[cnt]='\0';
  504. strcpy(keywords[key_cnt],temp);
  505. key_cnt++;
  506. cnt=0;
  507. }
  508. else
  509. {
  510. temp[cnt]=config[i];
  511. cnt++;
  512. }
  513. i++;
  514. }
  515. //PARENTHESIS
  516. while(!(config[i]=='p' && config[i+1]=='a' && config[i+2]=='r'))
  517. i++;
  518. i=i+13;
  519. cnt=0;
  520. while(config[i]!='\n')
  521. {
  522. if(config[i]==',')
  523. {
  524. temp[cnt]='\0';
  525. par[par_cnt]=temp[0];
  526. par_cnt++;
  527. cnt=0;
  528. }
  529. else
  530. {
  531. temp[cnt]=config[i];
  532. cnt++;
  533. }
  534. i++;
  535. }
  536. //DELIMITER
  537. while(!(config[i]=='d' && config[i+1]=='e' && config[i+2]=='l'))
  538. i++;
  539. i=i+11;
  540. cnt=0;
  541. while(config[i]!='\n')
  542. {
  543. if(config[i]==',')
  544. {
  545. temp[cnt]='\0';
  546. delimiter[del_cnt]=temp[0];
  547. del_cnt++;
  548. cnt=0;
  549. }
  550. else
  551. {
  552. temp[cnt]=config[i];
  553. cnt++;
  554. }
  555. i++;
  556. }
  557. delimiter[del_cnt]='\n';
  558. delimiter[del_cnt+1]=',';
  559. del_cnt+=2;
  560. //RELATIONAL-OPERATOR
  561. while(!(config[i]=='r' && config[i+1]=='e' && config[i+2]=='l'))
  562. i++;
  563. i=i+7;
  564. cnt=0;
  565. while(config[i]!='\n')
  566. {
  567. if(config[i]==',')
  568. {
  569. temp[cnt]='\0';
  570. strcpy(relop[relop_cnt],temp);
  571. relop_cnt++;
  572. cnt=0;
  573. }
  574. else
  575. {
  576. temp[cnt]=config[i];
  577. cnt++;
  578. }
  579. i++;
  580. }
  581. //OPERATOR
  582. while(!(config[i]=='o' && config[i+1]=='p' && config[i+2]=='e'))
  583. i++;
  584. i=i+10;
  585. cnt=0;
  586. while(config[i]!='\n')
  587. {
  588. if(config[i]==',')
  589. {
  590. temp[cnt]='\0';
  591. operators[op_cnt]=temp[0];
  592. op_cnt++;
  593. cnt=0;
  594. }
  595. else
  596. {
  597. temp[cnt]=config[i];
  598. cnt++;
  599. }
  600. i++;
  601. }
  602. //IDENTIFIERS
  603. while(!(config[i]=='i' && config[i+1]=='d' && config[i+2]=='e'))
  604. {
  605. i++;
  606. }
  607. i=i+13;
  608. cnt=0;
  609. while(config[i]!='\n')
  610. {
  611. temp[cnt]=config[i];
  612. cnt++;
  613. i++;
  614. }
  615. temp[cnt]='\0';
  616. strcpy(identifiers,temp);
  617. //NUMBERS
  618. while(!(config[i]=='n' && config[i+1]=='u' && config[i+2]=='m'))
  619. {
  620. i++;
  621. }
  622. i=i+9;
  623. cnt=0;
  624. while(config[i]!='\n')
  625. {
  626. temp[cnt]=config[i];
  627. cnt++;
  628. i++;
  629. }
  630. temp[cnt]='\0';
  631. strcpy(numbers,temp);
  632. infix_postfix(identifiers,post_id); //CONVERTS INFIX EXPRESSION OF IDENTIFIER INTO POSTFIX
  633. start_id = post2nfa(post_id); //CONVERTS POSTFIX EXPRESSION OF IDENTIFIER INTO NFA
  634. infix_postfix(numbers,post_num); //CONVERTS INFIX EXPRESSION OF NUMBERS INTO POSTFIX
  635. start_num = post2nfa(post_num); //CONVERTS POSTFIX EXPRESSION OF NUMBERS INTO NFA
  636. l1.s = malloc(nstate*sizeof l1.s[0]);
  637. l2.s = malloc(nstate*sizeof l2.s[0]);
  638. l3.s = malloc(nstate*sizeof l3.s[0]);
  639. l4.s = malloc(nstate*sizeof l4.s[0]);
  640. //READ THE PROGRAM
  641. pro = fopen("sample.txt","r");
  642. output = fopen("symbol_table.txt","w"); //OUPUT THE SYMBOL TABLE
  643. error_file = fopen("error_file.txt","w"); //OUPUT THE SYMBOL TABLE
  644. c = getc(pro) ;
  645. tot_size=0;
  646. while (c!= EOF)
  647. {
  648. program[tot_size]=c;
  649. tot_size++;
  650. c = getc(pro);
  651. }
  652. fclose(pro);
  653. fprintf(output,"%20s %20s %30s\n","TOKEN","TYPE","LINE NUMBER (row,col)");
  654. int row=1,col=0;
  655. cnt=0;
  656. for(i=0;i<tot_size;i++)
  657. {
  658. //CHECKS IF THERE ARE ANY COMMENTS
  659. if(i!=tot_size-1)
  660. {
  661. if(program[i]=='/' && program[i+1]=='/')
  662. {
  663. while((program[i]!='\n') && i<tot_size)
  664. i++;
  665. row++;
  666. }
  667. }
  668. //AT ANY POINT, IF THERE ARE MROE NUMBER OF CLOSING PARENTHESIS THAN OPEN, THEN ERROR (BALANCED PARENTHESIS)
  669. if(flag_rd<0)
  670. fprintf(error_file,"\nError on line %d column %d.\n \t Extra parenthesis ')'.",row,col);
  671. if(flag_cur<0)
  672. fprintf(error_file,"\nError on line %d column %d.\n \t Extra parenthesis '}'.",row,col);
  673. if(flag_box<0)
  674. fprintf(error_file,"\nError on line %d column %d.\n \t Extra parenthesis ']'.",row,col);
  675. //IF THERE ARE QUOTES, WE NEED TO INCLUDE 'ALL' CHARACTERS BETWEEN THEM AS LITERALS
  676. if(check_quotes(program[i])!=-1)
  677. {
  678. char abc=program[i];
  679. j=1;
  680. temp[0]=program[i];
  681. int prev_row=row;
  682. int prev_col=col;
  683. while(((i+j)<tot_size)&&(program[i+j]!=abc))
  684. {
  685. temp[j]=program[i+j];
  686. j++;
  687. if(program[i+j]=='\n')
  688. {
  689. row++;
  690. col=0;
  691. }
  692. else
  693. col++;
  694. }
  695. if(i+j==tot_size)
  696. {
  697. fprintf(error_file,"\nError on line %d column %d.\n \t Quotes does not have matching pair.",prev_row,prev_col);
  698. break;
  699. }
  700. temp[j]=abc;
  701. temp[j+1]='\0';
  702. //fprintf(output,"%20s %20s %10s (%d,%d)\n",temp,"literal","",row,col);
  703. save_list(temp,7,row,col);
  704. i=i+j;
  705. }
  706. //CHECK FOR THE PRESENCE OF DELIMITER
  707. else if(check_delimiter(program[i])!=-1)
  708. {
  709. token[cnt]='\0';
  710. if(cnt!=0)
  711. {
  712. j=0;
  713. while(j<strlen(token))
  714. {
  715. int my_fl=0;
  716. for(m=0;m<l_cnt;m++)
  717. {
  718. if(L[m]==token[j])
  719. {
  720. temp[j]='L';
  721. my_fl=1;
  722. }
  723. }
  724. for(m=0;m<d_cnt;m++)
  725. {
  726. if(D[m]==token[j])
  727. {
  728. temp[j]='D';
  729. my_fl=1;
  730. }
  731. }
  732. if(token[j]=='.')
  733. temp[j]='W';
  734. else if(my_fl==0)
  735. temp[j]=token[j];
  736. j++;
  737. }
  738. temp[j]='\0';
  739. //CHECK IF TOKEN IS A KEYWORD
  740. if(keyword_search(token)!=-1)
  741. {
  742. //fprintf(output,"%20s %20s %10s (%d,%d)\n",token,"keyword","",row,(col-strlen(token)-1));
  743. save_list(token,1,row,(col-strlen(token)-1));
  744. }
  745. //CHECK IF TOKEN IS A RELATIONAL OPERATOR
  746. else if(relop_search(token)!=-1)
  747. {
  748. //fprintf(output,"%20s %20s %10s (%d,%d)\n",token,"relop","",row,(col-strlen(token)));
  749. save_list(token,3,row,(col-strlen(token)));
  750. }
  751. //CHECK IF TOKEN IS A OPERATOR
  752. else if(op_search(token)!=-1)
  753. {
  754. //fprintf(output,"%20s %20s %10s (%d,%d)\n",token,"op","",row,col-1);
  755. save_list(token,4,row,(col-1));
  756. }
  757. //CHECK IF TOKEN IS A IDENTIFIER
  758. else if(match(start_id, temp, 1))
  759. {
  760. //fprintf(output,"%20s %20s %10s (%d,%d)\n",token,"identifier","",row,(col-strlen(token)));
  761. save_list(token,5,row,(col-strlen(token)));
  762. }
  763. //CHECK IF TOKEN IS A NUMBER
  764. else if(match(start_num, temp, 2))
  765. {
  766. //fprintf(output,"%20s %20s %10s (%d,%d)\n",token,"number","",row,(col-strlen(token)));
  767. save_list(token,6,row,(col-strlen(token)));
  768. }
  769. //IF IT DOES NOT MATCH ANY OF THESE, THEN IT IS AN ERROR
  770. else
  771. {
  772. fprintf(error_file,"\nError on line %d column %d.\n \t %s does not match any known type of token.",row,(col-strlen(token)),token);
  773. }
  774. }
  775. //CHECK IF PRESENCE OF PARENTHESIS (CHECK SEPARATELY BECAUSE IT IS ALSO PART OF DELIMITER)
  776. if(check_parenthesis(program[i])!=-1)
  777. {
  778. //fprintf(output,"%20c %20s %10s (%d,%d)\n",program[i],"parenthesis","",row,col-1);
  779. if(program[i]=='(')
  780. flag_rd++;
  781. else if(program[i]==')')
  782. flag_rd--;
  783. if(program[i]=='{')
  784. flag_cur++;
  785. else if(program[i]=='}')
  786. flag_cur--;
  787. if(program[i]=='[')
  788. flag_box++;
  789. else if(program[i]==']')
  790. flag_box--;
  791. char temp12[1000];
  792. strcpy(temp12,token);
  793. token[0]=program[i];
  794. token[1]='\0';
  795. save_list(token,2,row,(col-1));
  796. }
  797. if(program[i]=='\n')
  798. {
  799. row++;
  800. col=0;
  801. }
  802. cnt=0;
  803. }
  804. else
  805. {
  806. token[cnt]=program[i];
  807. cnt++;
  808. }
  809. col++;
  810. }
  811. sym_tab *temp12;
  812. temp12=table;
  813. //PRINT THE SYMBOL TABLE ONTO FILE
  814. while(temp12!=NULL)
  815. {
  816. if(temp12->type==1)
  817. fprintf(output,"%20s %20s %5s",temp12->token,"keyword","");
  818. else if(temp12->type==2)
  819. fprintf(output,"%20s %20s %5s",temp12->token,"parenthesis","");
  820. else if(temp12->type==3)
  821. fprintf(output,"%20s %20s %5s",temp12->token,"rel. operator","");
  822. else if(temp12->type==4)
  823. fprintf(output,"%20s %20s %5s",temp12->token,"operator","");
  824. else if(temp12->type==5)
  825. fprintf(output,"%20s %20s %5s",temp12->token,"identifier","");
  826. else if(temp12->type==6)
  827. fprintf(output,"%20s %20s %5s",temp12->token,"number","");
  828. else if(temp12->type==7)
  829. fprintf(output,"%20s %20s %5s",temp12->token,"literal","");
  830. loc *ter12=temp12->list;
  831. while(ter12!=NULL)
  832. {
  833. fprintf(output,"(%d,%d),",ter12->row,ter12->col);
  834. ter12=ter12->next2;
  835. }
  836. temp12=temp12->next1;
  837. fprintf(output,"\n");
  838. //int ag;
  839. //scanf("%d",&ag);
  840. }
  841. fclose(output);
  842. //AT THE END ALSO CHECK IF ALL THE PARENTHESIS HAVE BEEN CLOSED
  843. if(flag_rd!=0)
  844. fprintf(error_file,"\nError on line %d column %d.\n \t '(' not closed.",row,col);
  845. if(flag_cur!=0)
  846. fprintf(error_file,"\nError on line %d column %d.\n \t '{' not closed.",row,col);
  847. if(flag_box!=0)
  848. fprintf(error_file,"\nError on line %d column %d.\n \t '[' not closed.",row,col);
  849. printf("\n");
  850. return 0;
  851. }