├── Lab4-ParsingIntroductions ├── in2.txt ├── in1.txt ├── in3.txt ├── Images │ ├── Q1.PNG │ ├── Q2.PNG │ ├── Q1_desc.PNG │ ├── BFSvsDFS(Q3) │ │ ├── i.PNG │ │ ├── (i).PNG │ │ ├── fail.PNG │ │ ├── i+i+i.PNG │ │ ├── third.PNG │ │ └── better_message_fail.PNG │ └── Q2_Small_and_Capital.PNG ├── LabAssignment4_09.08.2019.pdf ├── README.md ├── Q2.java ├── Q1.java └── Q3.java ├── Lab2-SimpleLexicalAnalyzer ├── a.txt ├── README.md └── lex.java ├── Lab6-SLRParsing ├── GrammarQ6.txt ├── Grammar.txt ├── Images │ ├── map.PNG │ ├── stack.PNG │ ├── table.PNG │ └── FirstFollow.PNG ├── README.md └── PrettyPrinter.java ├── Lab7-YACC ├── a.exe ├── Runs.PNG ├── LabAssingment7.pdf ├── README.md ├── a.txt ├── sample inputs │ ├── input1.txt │ ├── input2.txt │ └── input3.txt ├── parse.l └── parse.y ├── Lab5-PredictiveParsing ├── grammarLL_1.txt ├── Images │ ├── Table1.PNG │ ├── Table2.PNG │ └── Table2_2.PNG ├── GrammarLL_2.txt ├── map.txt ├── map2.txt ├── output.txt ├── Q1_5.java ├── q3.l ├── input.txt ├── README.md ├── Q2_5.java └── PrettyPrinter.java ├── Parser_Library ├── LR0.txt ├── DemoClass.java ├── README.md ├── PrettyPrinter.java ├── LR0Parser.java ├── SLRParser.java ├── LALRParser.java ├── LR1Parser.java ├── Parser.java └── AugmentedFirstAndFollow.java ├── Lab1-REtoNFA ├── images │ ├── Reject.PNG │ ├── accept.PNG │ ├── reject2.PNG │ └── Instructions.PNG ├── print.sh ├── README.md └── wrapper.py ├── Lab8-AssemblyExploration ├── a.exe ├── add.c ├── lab8.c ├── add.s ├── ssort ├── README.md └── lab8.s ├── Lab10-BasicYaccCalculator ├── a.exe ├── parsing.PNG ├── LabAssignment10_04.10.2019.pdf ├── calculator.l ├── calculator.y ├── README.md └── calculator.tab.h ├── Lab3-LexIntroductions ├── token.exe ├── Images │ ├── 3.PNG │ ├── 1_1.PNG │ ├── 1_3.PNG │ └── 2_2.PNG ├── program.exe ├── Assignment3.pdf ├── integerEquiv.exe ├── evenBinaryRecog.exe ├── a.txt ├── evenBinaryRecog.l ├── README.md ├── token.l ├── integerEquiv.l └── program.l ├── Lab11-ExtendedYaccCalculator ├── a.exe ├── README.md ├── calculator.l ├── calculator.y └── calculator.tab.h ├── Lab12-AST ├── LabAssignment12_18.10.2019.pdf ├── 3address(old).l ├── ast.l ├── dag.l ├── 3address_1.y ├── 3address.l ├── 3address(old).y ├── transformInput.py ├── ast.y ├── dag.y ├── 3address.y └── README.md ├── Lab9-SelfCorrectingParser ├── Images │ ├── error.PNG │ ├── okay.PNG │ ├── errorV2.PNG │ ├── errorV2_2.PNG │ └── errorV2_3.PNG ├── LabAssignment9_20.09.2019.pdf ├── er1.txt ├── Q2_5_b.java ├── README.md └── PrettyPrinter.java ├── Lab13-Extended3AddressCode ├── LabAssignment13_25.10.2019.pdf ├── input.txt ├── 3address.l └── README.md └── README.md /Lab4-ParsingIntroductions/in2.txt: -------------------------------------------------------------------------------- 1 | A->aAB|aBc|aAc -------------------------------------------------------------------------------- /Lab2-SimpleLexicalAnalyzer/a.txt: -------------------------------------------------------------------------------- 1 | 1 2.3 4 2 | a.9 3.9 abc3 po 3 | 12a9 -------------------------------------------------------------------------------- /Lab4-ParsingIntroductions/in1.txt: -------------------------------------------------------------------------------- 1 | E->E+T|T 2 | T->T*F|F 3 | F->(E)|i -------------------------------------------------------------------------------- /Lab6-SLRParsing/GrammarQ6.txt: -------------------------------------------------------------------------------- 1 | S -> L = R | R 2 | L -> * R | id 3 | R -> L -------------------------------------------------------------------------------- /Lab4-ParsingIntroductions/in3.txt: -------------------------------------------------------------------------------- 1 | E->TA 2 | A->+TA|@ 3 | T->FC 4 | C->*FC|@ 5 | F->(E)|i -------------------------------------------------------------------------------- /Lab7-YACC/a.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab7-YACC/a.exe -------------------------------------------------------------------------------- /Lab5-PredictiveParsing/grammarLL_1.txt: -------------------------------------------------------------------------------- 1 | E->FMN 2 | T->FM 3 | F->(E)|i 4 | M->*FM|@ 5 | N->+TN|@ -------------------------------------------------------------------------------- /Lab6-SLRParsing/Grammar.txt: -------------------------------------------------------------------------------- 1 | E -> E + T | E - T | T 2 | T -> T * F | T / F | F 3 | F -> ( E ) | id -------------------------------------------------------------------------------- /Lab7-YACC/Runs.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab7-YACC/Runs.PNG -------------------------------------------------------------------------------- /Parser_Library/LR0.txt: -------------------------------------------------------------------------------- 1 | a b c d e 2 | S A B 3 | S -> a A d | b B d | a B e | b A e 4 | A -> c 5 | B -> c -------------------------------------------------------------------------------- /Lab1-REtoNFA/images/Reject.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab1-REtoNFA/images/Reject.PNG -------------------------------------------------------------------------------- /Lab1-REtoNFA/images/accept.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab1-REtoNFA/images/accept.PNG -------------------------------------------------------------------------------- /Lab6-SLRParsing/Images/map.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab6-SLRParsing/Images/map.PNG -------------------------------------------------------------------------------- /Lab7-YACC/LabAssingment7.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab7-YACC/LabAssingment7.pdf -------------------------------------------------------------------------------- /Lab8-AssemblyExploration/a.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab8-AssemblyExploration/a.exe -------------------------------------------------------------------------------- /Lab1-REtoNFA/images/reject2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab1-REtoNFA/images/reject2.PNG -------------------------------------------------------------------------------- /Lab10-BasicYaccCalculator/a.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab10-BasicYaccCalculator/a.exe -------------------------------------------------------------------------------- /Lab3-LexIntroductions/token.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab3-LexIntroductions/token.exe -------------------------------------------------------------------------------- /Lab6-SLRParsing/Images/stack.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab6-SLRParsing/Images/stack.PNG -------------------------------------------------------------------------------- /Lab6-SLRParsing/Images/table.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab6-SLRParsing/Images/table.PNG -------------------------------------------------------------------------------- /Lab11-ExtendedYaccCalculator/a.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab11-ExtendedYaccCalculator/a.exe -------------------------------------------------------------------------------- /Lab3-LexIntroductions/Images/3.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab3-LexIntroductions/Images/3.PNG -------------------------------------------------------------------------------- /Lab3-LexIntroductions/program.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab3-LexIntroductions/program.exe -------------------------------------------------------------------------------- /Lab8-AssemblyExploration/add.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() 3 | { 4 | int a=2,b=3; 5 | int c=a+b; 6 | printf("%d\n",c); 7 | } -------------------------------------------------------------------------------- /Lab1-REtoNFA/images/Instructions.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab1-REtoNFA/images/Instructions.PNG -------------------------------------------------------------------------------- /Lab10-BasicYaccCalculator/parsing.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab10-BasicYaccCalculator/parsing.PNG -------------------------------------------------------------------------------- /Lab3-LexIntroductions/Assignment3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab3-LexIntroductions/Assignment3.pdf -------------------------------------------------------------------------------- /Lab3-LexIntroductions/Images/1_1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab3-LexIntroductions/Images/1_1.PNG -------------------------------------------------------------------------------- /Lab3-LexIntroductions/Images/1_3.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab3-LexIntroductions/Images/1_3.PNG -------------------------------------------------------------------------------- /Lab3-LexIntroductions/Images/2_2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab3-LexIntroductions/Images/2_2.PNG -------------------------------------------------------------------------------- /Lab12-AST/LabAssignment12_18.10.2019.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab12-AST/LabAssignment12_18.10.2019.pdf -------------------------------------------------------------------------------- /Lab3-LexIntroductions/integerEquiv.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab3-LexIntroductions/integerEquiv.exe -------------------------------------------------------------------------------- /Lab4-ParsingIntroductions/Images/Q1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab4-ParsingIntroductions/Images/Q1.PNG -------------------------------------------------------------------------------- /Lab4-ParsingIntroductions/Images/Q2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab4-ParsingIntroductions/Images/Q2.PNG -------------------------------------------------------------------------------- /Lab5-PredictiveParsing/Images/Table1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab5-PredictiveParsing/Images/Table1.PNG -------------------------------------------------------------------------------- /Lab5-PredictiveParsing/Images/Table2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab5-PredictiveParsing/Images/Table2.PNG -------------------------------------------------------------------------------- /Lab6-SLRParsing/Images/FirstFollow.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab6-SLRParsing/Images/FirstFollow.PNG -------------------------------------------------------------------------------- /Lab3-LexIntroductions/evenBinaryRecog.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab3-LexIntroductions/evenBinaryRecog.exe -------------------------------------------------------------------------------- /Lab5-PredictiveParsing/Images/Table2_2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab5-PredictiveParsing/Images/Table2_2.PNG -------------------------------------------------------------------------------- /Lab9-SelfCorrectingParser/Images/error.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab9-SelfCorrectingParser/Images/error.PNG -------------------------------------------------------------------------------- /Lab9-SelfCorrectingParser/Images/okay.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab9-SelfCorrectingParser/Images/okay.PNG -------------------------------------------------------------------------------- /Lab4-ParsingIntroductions/Images/Q1_desc.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab4-ParsingIntroductions/Images/Q1_desc.PNG -------------------------------------------------------------------------------- /Lab9-SelfCorrectingParser/Images/errorV2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab9-SelfCorrectingParser/Images/errorV2.PNG -------------------------------------------------------------------------------- /Lab9-SelfCorrectingParser/Images/errorV2_2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab9-SelfCorrectingParser/Images/errorV2_2.PNG -------------------------------------------------------------------------------- /Lab9-SelfCorrectingParser/Images/errorV2_3.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab9-SelfCorrectingParser/Images/errorV2_3.PNG -------------------------------------------------------------------------------- /Lab4-ParsingIntroductions/Images/BFSvsDFS(Q3)/i.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab4-ParsingIntroductions/Images/BFSvsDFS(Q3)/i.PNG -------------------------------------------------------------------------------- /Lab4-ParsingIntroductions/Images/BFSvsDFS(Q3)/(i).PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab4-ParsingIntroductions/Images/BFSvsDFS(Q3)/(i).PNG -------------------------------------------------------------------------------- /Lab4-ParsingIntroductions/Images/BFSvsDFS(Q3)/fail.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab4-ParsingIntroductions/Images/BFSvsDFS(Q3)/fail.PNG -------------------------------------------------------------------------------- /Lab4-ParsingIntroductions/Images/BFSvsDFS(Q3)/i+i+i.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab4-ParsingIntroductions/Images/BFSvsDFS(Q3)/i+i+i.PNG -------------------------------------------------------------------------------- /Lab4-ParsingIntroductions/Images/BFSvsDFS(Q3)/third.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab4-ParsingIntroductions/Images/BFSvsDFS(Q3)/third.PNG -------------------------------------------------------------------------------- /Lab4-ParsingIntroductions/LabAssignment4_09.08.2019.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab4-ParsingIntroductions/LabAssignment4_09.08.2019.pdf -------------------------------------------------------------------------------- /Lab9-SelfCorrectingParser/LabAssignment9_20.09.2019.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab9-SelfCorrectingParser/LabAssignment9_20.09.2019.pdf -------------------------------------------------------------------------------- /Lab10-BasicYaccCalculator/LabAssignment10_04.10.2019.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab10-BasicYaccCalculator/LabAssignment10_04.10.2019.pdf -------------------------------------------------------------------------------- /Lab13-Extended3AddressCode/LabAssignment13_25.10.2019.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab13-Extended3AddressCode/LabAssignment13_25.10.2019.pdf -------------------------------------------------------------------------------- /Lab4-ParsingIntroductions/Images/Q2_Small_and_Capital.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab4-ParsingIntroductions/Images/Q2_Small_and_Capital.PNG -------------------------------------------------------------------------------- /Lab3-LexIntroductions/a.txt: -------------------------------------------------------------------------------- 1 | main() 2 | { 3 | INT i=0; 4 | INT sum=0; 5 | INT count; 6 | read(count); 7 | for(i=0;i<10;i++) 8 | { 9 | read(x); 10 | sum+=x;;y; 11 | } 12 | print(sum); 13 | } -------------------------------------------------------------------------------- /Lab4-ParsingIntroductions/Images/BFSvsDFS(Q3)/better_message_fail.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PalAditya/CompilerDesignLab/HEAD/Lab4-ParsingIntroductions/Images/BFSvsDFS(Q3)/better_message_fail.PNG -------------------------------------------------------------------------------- /Lab1-REtoNFA/print.sh: -------------------------------------------------------------------------------- 1 | javac REtoNFA.java 2 | java REtoNFA.java | tee output.txt 3 | python wrapper.py 0 > resultNFA.dot 4 | python wrapper.py 1 > resultDFA.dot 5 | dot -Tpng resultNFA.dot -o nfa.png 6 | dot -Tpng resultDFA.dot -o dfa.png 7 | imgcat nfa.png 8 | imgcat dfa.png -------------------------------------------------------------------------------- /Lab3-LexIntroductions/evenBinaryRecog.l: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | %} 4 | %% 5 | (1|(01*01*))* {printf("Okay");} 6 | .* {printf("Not okay");} 7 | %% 8 | int yywrap(){} 9 | int main(int argc, char*argv[]) 10 | { 11 | yylex(); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /Lab2-SimpleLexicalAnalyzer/README.md: -------------------------------------------------------------------------------- 1 | # Java Equivalent to Lex 2 | This code simply uses the in-built regex parser available in Java to parse the input String, which is read from the file a.txt [ *Change it to experiment* ] 3 | It is assumed that **tokens** are separated by spaces and newlines. -------------------------------------------------------------------------------- /Lab3-LexIntroductions/README.md: -------------------------------------------------------------------------------- 1 | # LEX 2 | 3 | **1_1** and **1_3**: Both simply use the regex to identify the pattern. The rule .* is used in case it matches a substring and not the whole expression. 4 | **2_2**: Simple tokenizer 5 | **3**: Enhancement of 2_2. The last rule ignores brackets, braces, semicolons and spaces. 6 | -------------------------------------------------------------------------------- /Lab12-AST/3address(old).l: -------------------------------------------------------------------------------- 1 | %{ 2 | #include "3address(old).tab.h" 3 | extern char yyval; 4 | %} 5 | 6 | %% 7 | 8 | [0-9]+ {yylval.symbol=(char)(yytext[0]);return NUMBER;} 9 | [a-z] {yylval.symbol= (char)(yytext[0]);return LETTER;} 10 | . {return yytext[0];} 11 | \n {return 0;} 12 | 13 | %% 14 | 15 | int yywrap() 16 | { 17 | return 1; 18 | } -------------------------------------------------------------------------------- /Lab13-Extended3AddressCode/input.txt: -------------------------------------------------------------------------------- 1 | x = y + 5; 2 | z = x*2; 3 | a = x + z; 4 | print ABC; 5 | read %f zxc; 6 | while (awe > qwe) 7 | { 8 | print qwe123 ; 9 | jkl = qwe + 1; 10 | qwe = qwe + 2; 11 | } 12 | if (awe != qwe || qwe + abc > 50 && abc == 10.234) 13 | { 14 | print POI123QWE; 15 | } 16 | else 17 | { 18 | print abc; 19 | print lkj; 20 | } -------------------------------------------------------------------------------- /Lab5-PredictiveParsing/GrammarLL_2.txt: -------------------------------------------------------------------------------- 1 | K->+DOp 2 | D->CD|@ 3 | C->QRm 4 | Q->t|w 5 | R->rT 6 | T->R|@ 7 | O->NO|@ 8 | P->FU 9 | U->cFU|dFU|@ 10 | F->r|q|v|hEi 11 | N->G|I|S|H 12 | G->rlEm 13 | I->sB/OV 14 | V->p|oOp 15 | S->%BuOp 16 | H->zL|-r 17 | L->E|* 18 | B->AW 19 | W->yAW|@ 20 | A->JX 21 | X->nJX|@ 22 | J->xJ|jBk|M 23 | M->EY 24 | Y->eE|fE|gE 25 | E->PZ 26 | Z->aPZ|bPZ|@ -------------------------------------------------------------------------------- /Lab10-BasicYaccCalculator/calculator.l: -------------------------------------------------------------------------------- 1 | %{ 2 | /* Definition section */ 3 | #include 4 | #include "calculator.tab.h" 5 | extern int yylval; 6 | %} 7 | 8 | /* Rule Section */ 9 | %% 10 | [0-9]+ { 11 | yylval=atoi(yytext); 12 | //printf("%d\n",yylval); 13 | return NUMBER; 14 | } 15 | [\t] ; 16 | [\n] return 0; 17 | . return yytext[0]; 18 | %% 19 | int yywrap() 20 | { 21 | return 1; 22 | } 23 | -------------------------------------------------------------------------------- /Lab12-AST/ast.l: -------------------------------------------------------------------------------- 1 | %{ 2 | /* Definition section */ 3 | #include 4 | %} 5 | 6 | /* Rule Section */ 7 | %% 8 | [0-9]+ { 9 | node *newnode=(node *)malloc(sizeof(node)); 10 | newnode->isOp=0; 11 | newnode->left=NULL; 12 | newnode->right=NULL; 13 | newnode->type=atoi(yytext); 14 | yylval=newnode; 15 | return NUMBER; 16 | } 17 | [\t] ; 18 | [\n] return 0; 19 | . return yytext[0]; 20 | %% 21 | int yywrap() 22 | { 23 | return 1; 24 | } 25 | -------------------------------------------------------------------------------- /Lab12-AST/dag.l: -------------------------------------------------------------------------------- 1 | %{ 2 | /* Definition section */ 3 | #include 4 | %} 5 | 6 | /* Rule Section */ 7 | %% 8 | [a-z] { 9 | node *newnode=(node *)malloc(sizeof(node)); 10 | newnode->isOp=0; 11 | newnode->left=NULL; 12 | newnode->right=NULL; 13 | newnode->type=yytext[0]; 14 | strcpy(expressions[index1],yytext); 15 | newnode->id=index1++; 16 | yylval=newnode; 17 | return ID; 18 | } 19 | [\t" "] ; 20 | [\n] return 0; 21 | . return yytext[0]; 22 | %% 23 | int yywrap() 24 | { 25 | return 1; 26 | } 27 | -------------------------------------------------------------------------------- /Lab5-PredictiveParsing/map.txt: -------------------------------------------------------------------------------- 1 | P -> prog DL SL end 2 | DL -> D DL | @ 3 | D -> TY VL ; 4 | TY -> int | float 5 | VL -> id U 6 | U -> VL | @ 7 | SL -> S SL | @ 8 | T -> F W 9 | W -> * F W | / F W | @ 10 | F -> id | ic | fc | ( E ) 11 | S -> ES | IS | WS | IOS 12 | ES -> id := E ; 13 | IS -> if BE then SL V 14 | V -> end | else SL end 15 | WS -> while BE do SL end 16 | IOS -> print PE | scan id 17 | PE -> E | str 18 | BE -> AE X 19 | X -> or AE X | @ 20 | AE -> NE Y 21 | Y -> and NE Y | @ 22 | NE -> not NE | { BE } | RE 23 | RE -> E [ 24 | [ -> = E | < E | > E 25 | E -> T Z 26 | Z -> + T Z | - T Z | @ -------------------------------------------------------------------------------- /Lab5-PredictiveParsing/map2.txt: -------------------------------------------------------------------------------- 1 | + 2 | t 3 | r 4 | m 5 | t 6 | r 7 | m 8 | t 9 | r 10 | m 11 | t 12 | r 13 | m 14 | r 15 | l 16 | r 17 | m 18 | r 19 | l 20 | r 21 | m 22 | - 23 | r 24 | z 25 | r 26 | s 27 | r 28 | e 29 | r 30 | / 31 | r 32 | l 33 | r 34 | m 35 | o 36 | s 37 | r 38 | f 39 | r 40 | / 41 | r 42 | l 43 | r 44 | m 45 | p 46 | % 47 | r 48 | g 49 | r 50 | u 51 | r 52 | l 53 | r 54 | b 55 | r 56 | m 57 | p 58 | p 59 | % 60 | r 61 | g 62 | r 63 | u 64 | r 65 | l 66 | r 67 | a 68 | r 69 | m 70 | r 71 | l 72 | r 73 | m 74 | s 75 | r 76 | e 77 | r 78 | / 79 | r 80 | l 81 | r 82 | m 83 | p 84 | p 85 | p -------------------------------------------------------------------------------- /Lab11-ExtendedYaccCalculator/README.md: -------------------------------------------------------------------------------- 1 | # Assignment 11 2 | 3 | The operations that are now supported are all the trigonometric functions, logarithm (to base 10) and square root. 4 | 5 | All extended operations should be wrapped in square brackets and for normal precedence, use standard round brackets. 6 | 7 | Compile with ```lex calculator.l & yacc -d calculator.y & gcc lex.yy.c calculator.tab.c``` (Use y.tab.c for *Linux/Mac* 8 | 9 | Example I/O: 10 | 1) 2 + 3 = 5.000000 11 | 2) 9 * sin [2] = 8.183677 12 | 3) 1 + 2 + 3 * tan [20] - (8 * 7) = -46.288517 13 | 14 | ![image](https://user-images.githubusercontent.com/25523604/66759874-a91da500-eebe-11e9-8307-cd0a22bd6c70.png) 15 | -------------------------------------------------------------------------------- /Lab8-AssemblyExploration/lab8.c: -------------------------------------------------------------------------------- 1 | //Program for selection sort 2 | #include 3 | #include 4 | int main() 5 | { 6 | int arr[]={1,-1,9,1,1,2,8,98,22}; 7 | int l=sizeof(arr)/sizeof(arr[0]); 8 | int i,index,j,max,temp,k; 9 | for(i=0;i=max) 16 | { 17 | max=arr[j]; 18 | index=j; 19 | } 20 | } 21 | if(index<0) 22 | continue; 23 | temp=arr[l-i-1]; 24 | arr[l-i-1]=arr[index]; 25 | arr[index]=temp; 26 | } 27 | printf("The sorted array is:\n"); 28 | for(i=0;i 49 | id 50 | do 51 | id 52 | := 53 | id 54 | - 55 | id 56 | ; 57 | end 58 | end 59 | while 60 | id 61 | > 62 | id 63 | do 64 | id 65 | := 66 | id 67 | + 68 | id 69 | ; 70 | id 71 | := 72 | id 73 | ; 74 | if 75 | id 76 | = 77 | id 78 | then 79 | id 80 | := 81 | id 82 | ; 83 | end 84 | end 85 | end -------------------------------------------------------------------------------- /Lab11-ExtendedYaccCalculator/calculator.l: -------------------------------------------------------------------------------- 1 | %{ 2 | /* Definition section */ 3 | #include 4 | #include "calculator.tab.h" 5 | extern double yylval; 6 | %} 7 | 8 | /* Rule Section */ 9 | %% 10 | [0-9]+ { 11 | yylval=atof(yytext); 12 | return NUMBER; 13 | } ; 14 | [0-9]+[.][0-9]+ { 15 | yylval=atof(yytext); 16 | return NUMBER_F; 17 | }; 18 | "**" return POWER; 19 | "sin"e? { 20 | return SINE; 21 | } 22 | "cos" return COSINE; 23 | "cosec" return COSECANT; 24 | "tan" return TANGENT; 25 | "sec" return SECANT; 26 | "cot" return COTANGENT; 27 | "log" return LOGARITHM; 28 | "root" return SQ_ROOT; 29 | 30 | [\t] {}; 31 | [\n] {return 0;}; 32 | . return yytext[0]; 33 | %% 34 | int yywrap() 35 | { 36 | return 1; 37 | } 38 | -------------------------------------------------------------------------------- /Lab9-SelfCorrectingParser/er1.txt: -------------------------------------------------------------------------------- 1 | + - * / = < > ( ) { } := ; and else end ic id if int do fc float not or print prog scan str then while 2 | P DL D TY VL U SL S ES IS V WS IOS PE BE X AE Y NE RE ZZ E Z T W F 3 | P -> prog DL SL end 4 | DL -> D DL | @ 5 | D -> TY VL ; 6 | TY -> int | float 7 | VL -> id U 8 | U -> VL | @ 9 | SL -> S SL | @ 10 | S -> ES | IS | WS | IOS 11 | ES -> id := E ; 12 | IS -> if BE then SL V 13 | V -> else SL end | end 14 | WS -> while BE do SL end 15 | IOS -> print PE | scan id 16 | PE -> E | str 17 | BE -> AE X 18 | X-> or AE X | @ 19 | AE -> NE Y 20 | Y -> and NE Y | @ 21 | NE -> { BE } | not NE | RE 22 | RE -> E ZZ 23 | ZZ -> = E | < E | > E 24 | E -> T Z 25 | Z -> + T Z | - T Z | @ 26 | T -> F W 27 | W -> * F W | / F W | @ 28 | F -> ( E ) | id | ic | fc -------------------------------------------------------------------------------- /Lab5-PredictiveParsing/Q1_5.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | class Q1_5 4 | { 5 | String fLine=""; 6 | ArrayList ntMap=new ArrayList<>(); 7 | ArrayList tMap=new ArrayList<>(); 8 | public static void main(String args[])throws IOException 9 | { 10 | FirstAndFollow obj=new FirstAndFollow(); 11 | ArrayList arr[][]=obj.module1("grammarLL_1.txt"); 12 | if(arr==null) 13 | { 14 | System.out.println("Exiting...:("); 15 | } 16 | System.out.print("i $ "); 17 | obj.module2(arr,"i $"); 18 | System.out.print("( i ) * ( i )* i $ "); 19 | obj.module2(arr,"( i ) * ( i ) * i $"); 20 | System.out.print("i i $ "); 21 | obj.module2(arr,"i i $ "); 22 | } 23 | } -------------------------------------------------------------------------------- /Lab7-YACC/README.md: -------------------------------------------------------------------------------- 1 | # YACC: Yet Another Compiler-Compiler 2 | The relevant files are *parse.l* and *parse.y* . *parse_test.l* is there for helping debug the tokenizing process of the input grammar. 3 | Both *parse_test.l* and *parse.y* expect to read input from a file called **a.txt**, placed in the same directory. So, either write your own programs there, or copy/paste the sample programs given in the *sample_inputs* directory to test (only input1.txt is valid) 4 | Compile in the following order: 5 | 1. yacc parse.y -d 6 | 2. lex parse.l 7 | 3. cc (or gcc) parse.tab.c 8 | 4. a.exe 9 | 10 | (Note: In Linux, the file would most likely be called y.tab.c, and in tha case, change the #include in parse.l to #include "y.tab.h") 11 | The screenshot for a run using the three sample input files, in-order, is attached. -------------------------------------------------------------------------------- /Lab8-AssemblyExploration/add.s: -------------------------------------------------------------------------------- 1 | .file "add.c" 2 | .def ___main; .scl 2; .type 32; .endef 3 | .section .rdata,"dr" 4 | LC0: 5 | .ascii "%d\12\0" 6 | .text 7 | .globl _main 8 | .def _main; .scl 2; .type 32; .endef 9 | _main: 10 | LFB10: 11 | .cfi_startproc 12 | pushl %ebp 13 | .cfi_def_cfa_offset 8 14 | .cfi_offset 5, -8 15 | movl %esp, %ebp 16 | .cfi_def_cfa_register 5 17 | andl $-16, %esp 18 | subl $32, %esp 19 | call ___main 20 | movl $2, 28(%esp) 21 | movl $3, 24(%esp) 22 | movl 24(%esp), %eax 23 | movl 28(%esp), %edx 24 | addl %edx, %eax 25 | movl %eax, 20(%esp) 26 | movl 20(%esp), %eax 27 | movl %eax, 4(%esp) 28 | movl $LC0, (%esp) 29 | call _printf 30 | leave 31 | .cfi_restore 5 32 | .cfi_def_cfa 4, 4 33 | ret 34 | .cfi_endproc 35 | LFE10: 36 | .ident "GCC: (GNU) 4.8.1" 37 | .def _printf; .scl 2; .type 32; .endef -------------------------------------------------------------------------------- /Lab10-BasicYaccCalculator/calculator.y: -------------------------------------------------------------------------------- 1 | %{ 2 | /* Definition section */ 3 | #include 4 | int flag=0; 5 | %} 6 | 7 | %token NUMBER 8 | 9 | %left '+' '-' 10 | 11 | %left '*' '/' '%' 12 | 13 | /* Rule Section */ 14 | %% 15 | 16 | ArithmeticExpression: 17 | E{ 18 | printf("\nResult=%d\n", $$); 19 | return 0; 20 | }; 21 | E:E'+'E {$$=$1+$3;} 22 | 23 | |E'-'E {$$=$1-$3;} 24 | 25 | |E'*'E {$$=$1*$3;} 26 | 27 | |E'/'E {$$=$1/$3;} 28 | 29 | | NUMBER {$$=$1;} 30 | 31 | ; 32 | 33 | %% 34 | 35 | //driver code 36 | void main() 37 | { 38 | printf("Enter Any Arithmetic Expression with +,-,* and / only\n"); 39 | yyparse(); 40 | if(flag==0) 41 | printf("Entered arithmetic expression is Valid\n"); 42 | } 43 | 44 | void yyerror() 45 | { 46 | printf("Entered arithmetic expression is Invalid\n"); 47 | flag=1; 48 | } -------------------------------------------------------------------------------- /Lab3-LexIntroductions/token.l: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | #include 4 | void check(char *str); 5 | %} 6 | %% 7 | [0-9] {printf("Digit: %s\n",yytext);} 8 | [0-9]+ {printf("Digits: %s\n",yytext);} 9 | [0-9]+([.][0-9]+)?([E][+-]?[0-9]+)? {printf("Numbers: %s\n",yytext);} 10 | [a-zA-z] {printf("Letter: %s\n",yytext);} 11 | [a-zA-z]([a-zA-z]|[0-9])* {check(yytext);} 12 | ([<]|[>]|[<][=]|[>][=]|[<][>]|[=]) {printf("Relop: %s\n",yytext);} 13 | ["\n"" "] {} 14 | %% 15 | int yywrap(){} 16 | int main(int argc, char*argv[]) 17 | { 18 | yylex(); 19 | return 0; 20 | } 21 | void check(char *str) 22 | { 23 | if(strcmp(str,"if")==0) 24 | { 25 | printf("If\n"); 26 | } 27 | else if(strcmp(str,"else")==0) 28 | { 29 | printf("Else\n"); 30 | } 31 | else if(strcmp(str,"if")==0) 32 | { 33 | printf("Then\n"); 34 | } 35 | else 36 | { 37 | printf("Id: %s\n",yytext); 38 | } 39 | } -------------------------------------------------------------------------------- /Lab5-PredictiveParsing/q3.l: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | #include 4 | 5 | void check(char *str); 6 | %} 7 | 8 | %% 9 | 10 | "+"|"-"|"*"|"/"|";" {fprintf(yyout,"%s\n",yytext);} 11 | "<"|">"|"<="|">="|":="|"=" {fprintf(yyout,"%s\n",yytext);} 12 | ["\t""\n"" "] {} 13 | [0-9]*[.][0-9]+ {fprintf(yyout,"id\n");} 14 | [0-9]+ {fprintf(yyout,"id\n");} 15 | "if"|"else"|"then" {fprintf(yyout,"%s\n",yytext);} 16 | "while"|"do"|"end" {fprintf(yyout,"%s\n",yytext);} 17 | "prog"|"scan"|"print" {fprintf(yyout,"%s\n",yytext);} 18 | "int"|"float" {fprintf(yyout,"%s\n",yytext);} 19 | [a-zA-Z][a-zA-Z0-9]* {fprintf(yyout,"id\n");} 20 | 21 | %% 22 | 23 | int yywrap() {} 24 | 25 | int main(int argc, char*argv[]) 26 | { 27 | extern FILE *yyin, *yyout; 28 | 29 | yyin = fopen("input.txt", "r"); 30 | yyout = fopen("output.txt", "w"); 31 | 32 | yylex(); 33 | return 0; 34 | } -------------------------------------------------------------------------------- /Lab12-AST/3address_1.y: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | void yyerror(char *s); 4 | int index1=0; 5 | char temp = 'A'-1; 6 | #define YYSTYPE char 7 | %} 8 | 9 | 10 | %left '+' '-' 11 | %left '/' '*' 12 | 13 | %token LETTER NUMBER 14 | %% 15 | 16 | statement: LETTER '=' exp {printf("%c = %c\n", (char)$1,(char)$3);}; 17 | exp: exp '+' exp {printf("%c = %c + %c\n", ++temp,(char)$1,(char)$3);$$ = temp;} 18 | |exp '-' exp {printf("%c = %c - %c\n", ++temp,(char)$1,(char)$3);$$ = temp;} 19 | |exp '/' exp {printf("%c = %c / %c\n", ++temp,(char)$1,(char)$3);$$ = temp;} 20 | |exp '*' exp {printf("%c = %c * %c\n", ++temp,(char)$1,(char)$3);$$ = temp;} 21 | |'(' exp ')' {$$= (char)$2;} 22 | |NUMBER {$$ = (char)$1;} 23 | |LETTER {(char)$1;}; 24 | 25 | %% 26 | 27 | void yyerror(char *s){ 28 | printf("Error %s",s); 29 | } 30 | 31 | 32 | int main(){ 33 | printf("Enter the expression: "); 34 | yyparse(); 35 | return 0; 36 | } -------------------------------------------------------------------------------- /Lab5-PredictiveParsing/input.txt: -------------------------------------------------------------------------------- 1 | prog 2 | int i; 3 | int j; 4 | int sum; 5 | int count; 6 | 7 | sum:=0; 8 | count:=5; 9 | 10 | scan count 11 | print sum 12 | 13 | if count=3 14 | then sum:=2; 15 | else 16 | if count < 4 17 | then sum:=2.3; 18 | end 19 | 20 | while count>2.3 21 | do sum:=sum-1; 22 | end 23 | end 24 | 25 | while sum > 0 26 | do 27 | count:=count+1; 28 | i := 1.2345; 29 | 30 | if count=3 31 | then sum:=2; 32 | end 33 | end 34 | 35 | end -------------------------------------------------------------------------------- /Lab8-AssemblyExploration/ssort: -------------------------------------------------------------------------------- 1 | ; 2 | jmp start 3 | ;data 4 | arr: db 9,2,3,17,1,6,12,8 5 | ;code 6 | start: nop 7 | lda 4000;assuming array length is in 4000 8 | mov b,a 9 | mov c,a; 10 | sta 4001;store this as we need to decrement it 11 | outer_loop: mvi h,0;max 12 | lxi d,arr;de can point to arr[0] now 13 | inner_loop: ldax d;store arr[j] in accumulator 14 | cmp h;compare with max 15 | jc deincrement 16 | mov h,a;max=arr[j] if needed 17 | xchg;swap de with hl 18 | shld 4002;//save the index 19 | xchg;reswap 20 | deincrement: inr e;point to next element 21 | dcr c 22 | jnz inner_loop 23 | lda 4001 24 | dcr a 25 | mov c,a 26 | sta 4001;inner loop decremented 27 | dcr e;pointing to last element to access 28 | xchg;swap, d again has max value 29 | mov a,m;got value of last element 30 | mov e,a;e is temp 31 | mov a,d;a has max value 32 | mov m,a;overwrote last element 33 | lhld 4002;get back index 34 | mov a,e 35 | mov m,a;swapping done 36 | dcr b; 37 | jnz outer_loop 38 | hlt -------------------------------------------------------------------------------- /Lab3-LexIntroductions/integerEquiv.l: -------------------------------------------------------------------------------- 1 | /*%{ 2 | #include 3 | #include 4 | void onemove(); 5 | void zeromove(); 6 | void check(); 7 | int state=0; 8 | %} 9 | %% 10 | [0] {zeromove();} 11 | [1] {onemove();} 12 | ["\n"] {check();} 13 | %% 14 | int yywrap(){} 15 | void onemove() 16 | { 17 | if(state==0) 18 | state=1; 19 | else if(state==1) 20 | state=0; 21 | else if(state==2) 22 | state=2; 23 | } 24 | void zeromove() 25 | { 26 | if(state==0) 27 | state=0; 28 | else if(state==1) 29 | state=2; 30 | else if(state==2) 31 | state=1; 32 | } 33 | int main(int argc, char*argv[]) 34 | { 35 | yylex(); 36 | return 0; 37 | } 38 | void check() 39 | { 40 | if(state==0) 41 | { 42 | printf("Divisible by 3\n"); 43 | } 44 | else 45 | { 46 | printf("Not divisible by 3\n"); 47 | } 48 | state=0; 49 | //exit(0); 50 | }*/ 51 | %{ 52 | #include 53 | %} 54 | %% 55 | (0*|0*110*|0*101*010*)* {printf("Okay");} 56 | .* {printf("Not okay");} 57 | %% 58 | int yywrap(){} 59 | int main(int argc, char*argv[]) 60 | { 61 | yylex(); 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /Lab9-SelfCorrectingParser/Q2_5_b.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | class Q2_5_b 4 | { 5 | String fLine=""; 6 | ArrayList ntMap=new ArrayList<>(); 7 | ArrayList tMap=new ArrayList<>(); 8 | public static void main(String args[])throws IOException 9 | { 10 | AugmentedFirstAndFollow2 obj=new AugmentedFirstAndFollow2(); 11 | ArrayList arr[][]=obj.module1("er1.txt",false,true); 12 | if(arr==null) 13 | { 14 | System.out.println("Exiting...:("); 15 | } 16 | System.out.print("prog end $ "); 17 | obj.module2(arr,obj.errors,"prog end $"); 18 | /*String str="prog int id ; int id ; int id ; int id ; id := ic ; id := ic ; scan id print id if id = ic then id := ic ;" 19 | +" else if id < ic then id := fc ; end while id > fc do id := id - ic ; end end" 20 | +" while id > ic do id := id + ic ; id := fc ; if id = ic then id := ic ; end end end $";*/ 21 | String str="prog int id ; ; scan if id := ic then id := ( ic + ic } int id ; = prog $"; 22 | System.out.print(str+" \n"); 23 | obj.module2(arr,obj.errors,str); 24 | } 25 | } -------------------------------------------------------------------------------- /Lab7-YACC/a.txt: -------------------------------------------------------------------------------- 1 | global 2 | 3 | def 4 | // some type defs 5 | someId := product 6 | pr1op[3], pr2op : someType; 7 | otherProp123 : 8 | otherId := product 9 | extra, nul : null 10 | end 11 | end; 12 | 13 | var1, var2[5], var3 : float; 14 | var4[1], v5[3][4] : int 15 | end 16 | 17 | fun myFunc -> int 18 | print "# 123QWE" 19 | end 20 | 21 | fun myFunc2 22 | var1, var2[5], var3 : float; 23 | var4[1], v5[3][4] : int 24 | -> int 25 | print "# 123QWE" 26 | end 27 | 28 | // Some comments in between 29 | // int print scan 30 | 31 | while awe > qwe: 32 | print "# 123QWE"; 33 | awe := qwe + 1; 34 | qwe := qwe + 2 35 | end; 36 | 37 | if awe <> qwe or awe <> qwe or qwe + abc > 50 and not((abc = 10.234) or 10.234 <= qwe and not qwe > 50) or qwe <> abc: 38 | print "# 123QWE" 39 | else 40 | print "ABC"; 41 | print "ABC" 42 | end; 43 | 44 | from iteratorId := 5+abc to qwe-1.23 step abc+qwe : 45 | print "ABC"; 46 | print "Looping" 47 | end; 48 | 49 | exit; 50 | return someExp1 mod someExp2; 51 | 52 | super.current.sub := (id1 : 1+2, 3-4, 5*6, 7/8, 9 mod 10, +1.-2, 4.567, (3), id2) ; 53 | print "ABC"; 54 | read %f abc + 10.234 mod qwe / 50; 55 | 56 | read %s someID0 [id1 + id2][id3 - id4] 57 | 58 | end -------------------------------------------------------------------------------- /Lab4-ParsingIntroductions/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Parsing 3 | 4 | **Q1:** It involves the following algorithm: 5 | 1. Arrange the non-terminal symbols in order: A1, A2, A3, ..., An 6 | 2. For i=1 to n do: 7 |  For j=1 to i-1 do: 8 |   *I)* replace each production of the form Ai->AjY with the productions: Ai->Z1Y|Z2Y|...|ZkY where Aj->Z1|Z2|...|Zk are all the current productions of Aj. 9 |   *II)* Eliminate the immediate left recursion among the Ai 10 | 11 | 12 | **Q2:** It involves the following algorithm: 13 |  1. For each non-terminal A, find the longest prefix, say a, common to two or more of its alternatives 14 |  2. if (a!=epsilon) then replace all the A productions, A->ab1|ab2|ab3|...|abn|Z, where Z is anything that does not begin with a, with A->aY|Z and Y->b1|b2|b3|...|bn 15 |  Repeat the above until no common prefixes remain. 16 | 17 | **Q3**: It involves the basic DFS, where we expand each production and try to find a match. BFS has also been implemented. 18 | -------------------------------------------------------------------------------- /Lab7-YACC/sample inputs/input1.txt: -------------------------------------------------------------------------------- 1 | global 2 | 3 | def 4 | // some type defs 5 | someId := product 6 | pr1op[3], pr2op : someType; 7 | otherProp123 : 8 | otherId := product 9 | extra, nul : null 10 | end 11 | end; 12 | 13 | var1, var2[5], var3 : float; 14 | var4[1], v5[3][4] : int 15 | end 16 | 17 | fun myFunc -> int 18 | print "# 123QWE" 19 | end 20 | 21 | fun myFunc2 22 | var1, var2[5], var3 : float; 23 | var4[1], v5[3][4] : int 24 | -> int 25 | print "# 123QWE" 26 | end 27 | 28 | // Some comments in between 29 | // int print scan 30 | 31 | while awe > qwe: 32 | print "# 123QWE"; 33 | awe := qwe + 1; 34 | qwe := qwe + 2 35 | end; 36 | 37 | if awe <> qwe or awe <> qwe or qwe + abc > 50 and not((abc = 10.234) or 10.234 <= qwe and not qwe > 50) or qwe <> abc: 38 | print "# 123QWE" 39 | else 40 | print "ABC"; 41 | print "ABC" 42 | end; 43 | 44 | from iteratorId := 5+abc to qwe-1.23 step abc+qwe : 45 | print "ABC"; 46 | print "Looping" 47 | end; 48 | 49 | exit; 50 | return someExp1 mod someExp2; 51 | 52 | super.current.sub := (id1 : 1+2, 3-4, 5*6, 7/8, 9 mod 10, +1.-2, 4.567, (3), id2) ; 53 | print "ABC"; 54 | read %f abc + 10.234 mod qwe / 50; 55 | 56 | read %s someID0 [id1 + id2][id3 - id4] 57 | 58 | end 59 | -------------------------------------------------------------------------------- /Lab7-YACC/sample inputs/input2.txt: -------------------------------------------------------------------------------- 1 | global 2 | 3 | def 4 | // some type defs 5 | someId := product 6 | pr1op[3], pr2op : someType; 7 | otherProp123 : 8 | otherId := product 9 | extra, nul : null 10 | end 11 | end 12 | 13 | var1, var2[5], var3 : float; 14 | var4[1], v5[3][4] : int 15 | end 16 | 17 | fun myFunc -> int 18 | print "# 123QWE" 19 | end 20 | 21 | fun myFunc2 22 | var1, var2[5], var3 : float; 23 | var4[1], v5[3][4] : int 24 | -> int 25 | print "# 123QWE" 26 | end 27 | 28 | // Some comments in between 29 | // int print scan 30 | 31 | while awe > qwe: 32 | print "# 123QWE"; 33 | awe := qwe + 1; 34 | qwe := qwe + 2 35 | end; 36 | 37 | if awe <> qwe or awe <> qwe or qwe + abc > 50 and not((abc = 10.234) or 10.234 <= qwe and not qwe > 50) or qwe <> abc: 38 | print "# 123QWE" 39 | else 40 | print "ABC"; 41 | print "ABC" 42 | end 43 | 44 | from iteratorId := 5+abc to qwe-1.23 step abc+qwe : 45 | print "ABC"; 46 | print "Looping" 47 | end; 48 | 49 | exit; 50 | return someExp1 mod someExp2; 51 | 52 | super.current.sub := (id1 : 1+2, 3-4, 5*6, 7/8, 9 mod 10, +1.-2, 4.567, (3), id2) ; 53 | print "ABC"; 54 | read %f abc + 10.234 mod qwe / 50; 55 | 56 | read %s someID0 [id1 + id2][id3 - id4] 57 | 58 | end 59 | -------------------------------------------------------------------------------- /Lab7-YACC/sample inputs/input3.txt: -------------------------------------------------------------------------------- 1 | global 2 | 3 | def 4 | // some type defs 5 | someId := product 6 | pr1op[3], pr2op : someType; 7 | otherProp123 : 8 | otherId := product 9 | extra, nul : null 10 | end 11 | end; 12 | 13 | var1, var2[5], var3 : float; 14 | var4[1], v5[3][4] : int 15 | end 16 | 17 | fun myFunc -> int 18 | print "# 123QWE" 19 | end 20 | 21 | fun myFunc2 22 | var1, var2[5], var3 : float; 23 | var4[1], v5[3][4] : int 24 | -> int 25 | print "# 123QWE" 26 | end 27 | 28 | // Some comments in between 29 | // int print scan 30 | 31 | while awe > qwe: 32 | print "# 123QWE"; 33 | awe := qwe + 1; 34 | qwe = qwe + 2 35 | end; 36 | 37 | if awe <> qwe or awe <> qwe or qwe + abc > 50 and not((abc = 10.234) or 10.234 <= qwe and not qwe > 50) or qwe <> abc: 38 | print "# 123QWE" 39 | else 40 | print "ABC"; 41 | print "ABC" 42 | end; 43 | 44 | from iteratorId := 5+abc to qwe-1.23 step abc+qwe : 45 | print "ABC"; 46 | print "Looping" 47 | end; 48 | 49 | exit; 50 | return someExp1 mod someExp2; 51 | 52 | super.current.sub := (id1 : 1+2, 3-4, 5*6, 7/8, 9 mod 10, +1.-2, 4.567, (3), id2) ; 53 | print "ABC"; 54 | read %f abc + 10.234 mod qwe / 50; 55 | 56 | read %s someID0 [id1 + id2][id3 - id4] 57 | 58 | end 59 | -------------------------------------------------------------------------------- /Lab1-REtoNFA/README.md: -------------------------------------------------------------------------------- 1 | This uses the **Thomposon's construction** method to build the NFA. 2 | First, we define an NFA as a three tuple: *start_vertex*, *end_vertex* and *transition_symbol* and a list of all such transitions. 3 | Then we build three functions: The *concat*, *kleene star* and *or*, all of which acceprt two NFAs and return a new NFA. 4 | To build *concat*, we accept two NFAs, create a new NFA, copy all the existing transitions of NFA 1 into the temp and copy the transitions of NFA 2 by appending it to last node of NFA 1. We then mark start node of NFA 1 as start node of temp and end end node of NFA 2 as end node of temp and return. 5 | Similar things are one for other two too. 6 | We finally use a stack to evaluate the regex. 7 | We then reduce the NFA to a DFA and use DFS to evaluate any given expression. 8 | **Input:** Use brackets and dots explicitly to indicate groups and concatenation, like **(a.b.(c|a))** and not **ab(c|a)**. Also, brackets can change the meaning significantly, like ((a.b*)|(c.a)) means a followed by any number of b's or simply ca, whereas (a.b*|(c.a)) can be interpreted as the previous one or maybe a followed by any number of b's or the fragment ca (I'll let you figure out which one :P), so ue explicit brackets too remove such ambiguity. 9 | Sample images are in the images directory. 10 | -------------------------------------------------------------------------------- /Lab2-SimpleLexicalAnalyzer/lex.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.util.regex.*; 3 | import java.io.*; 4 | class LexicalAnalyzer 5 | { 6 | public static void main(String args[])throws IOException 7 | { 8 | LexicalAnalyzer obj=new LexicalAnalyzer(); 9 | obj.go(); 10 | } 11 | void analyze(String str[]) 12 | { 13 | int i,l=str.length; 14 | for(i=0;i|<=|>=|=|<>",str[i])) 33 | System.out.println("Relop: "+str[i]); 34 | else 35 | System.out.println("Unknown token "+str[i]+" :( "); 36 | } 37 | } 38 | public void go()throws IOException 39 | { 40 | String str=""; 41 | BufferedReader br=new BufferedReader(new FileReader("a.txt")); 42 | while((str=br.readLine())!=null) 43 | { 44 | analyze(str.split(" ")); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Lab12-AST/3address.l: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | #include 4 | char symtab[100][100]; 5 | char* pop(); 6 | void push(char *s); 7 | int top=-1; 8 | %} 9 | %% 10 | 11 | [0-9]+ { 12 | node *newnode=(node *)malloc(sizeof(node)); 13 | strcpy(newnode->addr,yytext); 14 | int i; 15 | for(i=0;i<100;i++) 16 | newnode->code[i]='\0'; 17 | //printf("Address and code are: %s,%s\n",newnode->addr,newnode->code); 18 | yylval=newnode; 19 | push(yytext); 20 | return NUMBER; 21 | } 22 | [a-z]+ { 23 | node *newnode=(node *)malloc(sizeof(node)); 24 | strcpy(newnode->addr,yytext); 25 | int i; 26 | for(i=0;i<100;i++) 27 | newnode->code[i]='\0'; 28 | //printf("Address and code are: %s,%s\n",newnode->addr,newnode->code); 29 | yylval=newnode; 30 | push(yytext); 31 | return ID; 32 | } 33 | [" "\t] {} 34 | . {return yytext[0];} 35 | \n {return 0;} 36 | 37 | %% 38 | 39 | int yywrap() 40 | { 41 | return 1; 42 | } 43 | /* 44 | //---RELOP--- 45 | [<>]|<=|>= { 46 | node *newnode=(node *)malloc(sizeof(node)); 47 | strcpy(newnode->addr,yytext); 48 | int i; 49 | for(i=0;i<100;i++) 50 | newnode->code[i]='\0'; 51 | //printf("Address and code are: %s,%s\n",newnode->addr,newnode->code); 52 | yylval=newnode; 53 | push(yytext); 54 | return RELOP; 55 | } 56 | */ 57 | 58 | void push(char *s) 59 | { 60 | //printf("Pushed %s\n",s); 61 | strcpy(symtab[++top],s); 62 | } 63 | char *pop() 64 | { 65 | //printf("Popped %s\n",symtab[top]); 66 | return symtab[top--]; 67 | } 68 | -------------------------------------------------------------------------------- /Lab7-YACC/parse.l: -------------------------------------------------------------------------------- 1 | %{ 2 | /* Definition section */ 3 | #include 4 | #include "parse.tab.h" 5 | extern int yylval; 6 | %} 7 | %option yylineno 8 | /* Rule Section */ 9 | %% 10 | [/][/].*["\n"] {} 11 | and { return AND; } 12 | := { return ASSIGN;} 13 | : {return COLON;} 14 | , {return COMMA;} 15 | def {return DEF;} 16 | \/ {return DIV;} 17 | [.] {return DOT;} 18 | [e][l][s][e] {return ELSE;} 19 | end {return END;} 20 | = {return EQ;} 21 | exit {return EXITLOOP;} 22 | float {return FLOAT;} 23 | [0-9]+[.][0-9]+ {return FLOAT_CONST;} 24 | %[fsd] {return FORMAT;} 25 | from {return FROM;} 26 | fun {return FUN;} 27 | >= {return GE;} 28 | global {return GLOBAL;} 29 | > {return GT;} 30 | if {return IF;} 31 | int {return INT;} 32 | [0-9]+ {return INT_CONST;} 33 | [(] {return LEFT_PAREN;} 34 | \[ {return LEFT_SQ_BKT;} 35 | [<][=] {return LE;} 36 | [<] {return LT;} 37 | \- {return MINUS;} 38 | mod {return MOD; } 39 | \* {return MULT; } 40 | [<][>] {return NE; } 41 | not {return NOT;} 42 | null {return NUL;} 43 | or {return OR;} 44 | \+ {return PLUS;} 45 | print {return PRINT;} 46 | product {return PRODUCT;} 47 | read {return READ;} 48 | return {return RETURN;} 49 | \-> {return RETURNS;} 50 | [)] {return RIGHT_PAREN;} 51 | \] {return RIGHT_SQ_BKT;} 52 | ; {return SEMICOLON;} 53 | skip {return SKIP;} 54 | step {return STEP;} 55 | to {return TO;} 56 | while {return WHILE;} 57 | [a-zA-Z][a-zA-Z0-9]+ {return ID;} 58 | \".*\" {return STRING;} 59 | [\t\n" "] {}; 60 | 61 | %% 62 | 63 | int yywrap() 64 | { 65 | return 1; 66 | } -------------------------------------------------------------------------------- /Lab10-BasicYaccCalculator/README.md: -------------------------------------------------------------------------------- 1 | # Assignment 10 2 | 3 | ## The CFG would be: 4 | 5 | ``` 6 | S -> S + T | S - T | T 7 | T -> T * number | T / number | number 8 | ``` 9 | 10 | Where number is [0-9] + 11 | 12 | Proof this is LR (1): The LR (1) parsing table (generated by the LR1Parser in folder ```Parser Library```) is as below with no SR or RR conflict. 13 | 14 | ![image](https://user-images.githubusercontent.com/25523604/66759066-2a743800-eebd-11e9-9fc5-ec5359e4f1bc.png) 15 | 16 | A parsing of ```number * number + number - number / number``` is: 17 | 18 | ![image](https://user-images.githubusercontent.com/25523604/66759485-f51c1a00-eebd-11e9-8035-3a7b15d5257e.png) 19 | 20 | 21 | ## The attribute grammar will be: 22 | 23 | ``` 24 | E’ -> E {E’.res = E.res} 25 | E -> E + T {E.res =E.res + T.res} 26 | E -> E - T {E.res = E.res - E’.res} 27 | E -> T {E.res = T.res} 28 | T -> T / number {T.res = T.res - number} 29 | T -> T * number {T.res = T.res - number} 30 | T -> number {T.res = number} 31 | ``` 32 | 33 | _Example:_ 3 + 9 – 2 (We'll do a left recursive derivation) 34 | 35 | ```E’ -> E -> E - T -> E + T – T -> T + T – T -> number + T – T -> number – number – T -> number +number -number``` 36 | 37 | Now, if we walk the attribute grammar backwards, we get that all the **T + T – T** get **T.res = number** (last rule), which then propagates to **E + T – T** {E.res = T.res (3)}, the **E – T** {E.res = E.res + T.res (12)}, then **E** {E.res = E.res -T.res (10)} and finally, E' {E'.res = E.res (10)}, so we get 10 38 | 39 | **Note:** For YACC implementation, I have used simply ```S -> S + S | S – S | S * S | S / S | number```, as associativity/precedence can be handled by YACC. 40 | -------------------------------------------------------------------------------- /Lab3-LexIntroductions/program.l: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | #include 4 | void check(char *str); 5 | %} 6 | %% 7 | [0-9] {printf("Digit: %s\n",yytext);} 8 | [0-9]+ {printf("Digits: %s\n",yytext);} 9 | [0-9]+([.][0-9]+)?([E][+-]?[0-9]+)? {printf("Numbers: %s\n",yytext);} 10 | [a-zA-z] {printf("Letter: %s\n",yytext);} 11 | [a-zA-z]([a-zA-z]|[0-9])* {check(yytext);} 12 | [=] {printf("Assignment\n");} 13 | [++|+=|\-=|\-\-] {printf("Shorthands\n");} 14 | [<|>|<=|>=|<>|==] {printf("Relop: %s\n",yytext);} 15 | ([+][-][*][/]) {printf("Arithmetic operator: %s\n",yytext);} 16 | ["\n"" "\(\)\{\};] {} 17 | %% 18 | int yywrap(){} 19 | int main(int argc, char*argv[]) 20 | { 21 | extern FILE *yyin; 22 | yyin = fopen("a.txt","r"); 23 | yylex(); 24 | fclose(yyin); 25 | return 0; 26 | } 27 | void check(char *str) 28 | { 29 | if(strcmp(str,"main")==0) 30 | { 31 | printf("Main function\n"); 32 | } 33 | else if(strcmp(str,"if")==0) 34 | { 35 | printf("If\n"); 36 | } 37 | else if(strcmp(str,"else")==0) 38 | { 39 | printf("Else\n"); 40 | } 41 | else if(strcmp(str,"if")==0) 42 | { 43 | printf("Then\n"); 44 | } 45 | else if(strcmp(str,"for")==0) 46 | { 47 | printf("For loop\n"); 48 | } 49 | else if(strcmp(str,"while")==0) 50 | { 51 | printf("While loop\n"); 52 | } 53 | else if(strcmp(str,"read")==0) 54 | { 55 | printf("Input: Read\n"); 56 | } 57 | else if(strcmp(str,"print")==0) 58 | { 59 | printf("Output: print\n"); 60 | } 61 | else if(strcmp(str,"INT")==0||strcmp(str,"int")==0) 62 | { 63 | printf("Data type: Integer\n"); 64 | } 65 | else if(strcmp(str,"FLOAT")==0||strcmp(str,"float")==0) 66 | { 67 | printf("Data type: Real\n"); 68 | } 69 | else 70 | { 71 | printf("Id: %s\n",yytext); 72 | } 73 | } -------------------------------------------------------------------------------- /Lab11-ExtendedYaccCalculator/calculator.y: -------------------------------------------------------------------------------- 1 | %code requires 2 | { 3 | #define YYSTYPE double 4 | } 5 | %{ 6 | /* Definition section */ 7 | #include 8 | #include 9 | int flag=0; 10 | void yyerror(char *s); 11 | %} 12 | 13 | %token NUMBER POWER SINE NUMBER_F COSINE TANGENT LOGARITHM SQ_ROOT COTANGENT SECANT COSECANT 14 | 15 | %nonassoc SINE COSINE TANGENT LOGARITHM SQ_ROOT COTANGENT SECANT COSECANT 16 | 17 | %left '+' '-' 18 | 19 | %left '*' '/' '%' 20 | 21 | %nonassoc POWER 22 | 23 | %left '(' ')' '[' ']' 24 | 25 | /* Rule Section */ 26 | %% 27 | 28 | ArithmeticExpression: 29 | E{ 30 | printf("\nResult=%lf\n",$$); 31 | return 0; 32 | }; 33 | E:E'+'E {$$=$1+$3;} 34 | 35 | |E'-'E {$$=$1-$3;} 36 | 37 | |E'*'E {$$=$1*$3;} 38 | 39 | |E'/'E {$$=$1/$3;} 40 | 41 | |E'%'E {$$=(int)$1%(int)$3;} 42 | 43 | | E POWER E {$$=pow($1,$3);} 44 | 45 | |'('E')' {$$=$2;} 46 | 47 | | SINE'['E']' {$$=sin($3);} 48 | 49 | | COSECANT'['E']' {$$=(1.0/sin($3));} 50 | 51 | | COSINE'['E']' {$$=cos($3);} 52 | 53 | | TANGENT'['E']' {$$=tan($3);} 54 | 55 | | COTANGENT'['E']' {$$=1.0/tan($3);} 56 | 57 | | SECANT'['E']' {$$=1.0/cos($3);} 58 | 59 | | LOGARITHM'['E']' {$$=log10($3);} 60 | 61 | | SQ_ROOT'['E']' {$$=sqrt($3);} 62 | 63 | | NUMBER {$$=$1;} 64 | 65 | | NUMBER_F {$$=$1;} 66 | ; 67 | 68 | %% 69 | 70 | //driver code 71 | void main() 72 | { 73 | printf("Enter Any Arithmetic Expression. Supported operations are in README.docx\n"); 74 | yyparse(); 75 | if(flag==0) 76 | printf("Entered arithmetic expression is Valid\n"); 77 | } 78 | 79 | void yyerror(char *s) 80 | { 81 | printf("Entered arithmetic expression is Invalid\n"); 82 | flag=1; 83 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CompilerDesignLab 2 | Code for Compiler Design Lab, Semester 7 3 | Will contain **images** and **README** files for each assignment if possible. 4 | 5 | The work is now available in the form of a library :smile: 6 | 7 | A basic usage of the library is as easy as follows: 8 | 9 | ```java 10 | LR1Parser obj=new LR1Parser();//Create an instance of the desired parser-In this case LR1 type parser 11 | obj.read_grammar("D://Documents/Lab4/LR0.txt");//Read the grammar file 12 | obj.buildDFA();//Build a dfa from the file 13 | System.out.println(obj.states);//Prints the transitions in all states 14 | obj.print_transitions();//Print all the transitions 15 | obj.getParsingTable(true);//Use false to avoid printing the table after creation 16 | obj.parse("a c e",true);//Parse the string; use false to prevent the stack actions from displaying on screen 17 | ``` 18 | Please move to [docs](Parser_Library/README.md) for a full understanding of the library. 19 | 20 | For **release** build: 21 | 22 | ```java 23 | 24 | io.github.PalAditya 25 | parser-library 26 | 0.1.1 27 | 28 | ``` 29 | 30 | For **snapshot** build: 31 | 32 | ```java 33 | 34 | io.github.PalAditya 35 | parser-library 36 | 0.1-SNAPSHOT 37 | 38 | ``` 39 | 40 | In case you want the pre-release (latest) versions, you can download it manually from [here](https://oss.sonatype.org/content/repositories/central_bundles-18962/io/github/PalAditya/parser-library/0.1.1/) 41 | 42 | **Note**: This is not being maintained anymore. Please see [here](https://github.com/PalAditya/JParser) to get the latest version of the code. 43 | -------------------------------------------------------------------------------- /Lab12-AST/3address(old).y: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | char addtotable(char,char,char); 4 | void yyerror(char *s); 5 | int index1=0; 6 | char temp = 'A'-1; 7 | struct expr{ 8 | char operand1; 9 | char operand2; 10 | char operator; 11 | char result; 12 | }; 13 | %} 14 | 15 | %union{ 16 | char symbol; 17 | } 18 | 19 | %left '+' '-' 20 | %left '/' '*' 21 | 22 | %token LETTER NUMBER 23 | %type exp 24 | %% 25 | 26 | statement: LETTER '=' exp ';' {addtotable((char)$1,(char)$3,'=');}; 27 | exp: exp '+' exp {$$ = addtotable((char)$1,(char)$3,'+');} 28 | |exp '-' exp {$$ = addtotable((char)$1,(char)$3,'-');} 29 | |exp '/' exp {$$ = addtotable((char)$1,(char)$3,'/');} 30 | |exp '*' exp {$$ = addtotable((char)$1,(char)$3,'*');} 31 | |'(' exp ')' {$$= (char)$2;} 32 | |NUMBER {$$ = (char)$1;} 33 | |LETTER {(char)$1;}; 34 | 35 | %% 36 | 37 | struct expr arr[20]; 38 | 39 | void yyerror(char *s){ 40 | //printf("Error %s",s); 41 | } 42 | 43 | char addtotable(char a, char b, char o){ 44 | temp++; 45 | arr[index1].operand1 =a; 46 | arr[index1].operand2 = b; 47 | arr[index1].operator = o; 48 | arr[index1].result=temp; 49 | index1++; 50 | return temp; 51 | } 52 | 53 | void threeAddressCode(){ 54 | int i=0; 55 | char temp='A'; 56 | while(imax. The jl (jump on less) command allows it to not enter the if section,as it then goes to L8 or else it goes to L9 24 | L8| It sets index to -1 and max to arr[l-i-1] {first two lines of loop} before jumping to L3 (j loop) 25 | L3|Lines 58 to 62 perform the check if arr[j]>=max (by the subtract long, or subl command) and does a jump in that case to L5. Line 64-65 checks if index is -1, in which case L6 is called {L6's function described below}. Finally, L7 adds one to loop index (j++) 26 | L5|Does the two operations: {max=arr[j];index=j;} 27 | L9| Handles the end of program. It calls L10 repeatedly (boundary check done by jl command) to print the array and then returns 28 | L4| Handles increment for i (outer) loop 29 | L6| It handles the swap part {temp=arr[l-i-1];arr[l-i-1]=arr[index];arr[index]=temp;} 30 | 31 | **Note2**: add.s is much easier to understand. In lines 20-24, we first assign 2 and 3 to memory locations and then load them to registers (*eax* and *edx*). Addition is done with addl command, printf call is then made to output the value and then program exits. 32 | -------------------------------------------------------------------------------- /Lab13-Extended3AddressCode/3address.l: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | #include 4 | 5 | char c; 6 | 7 | %} 8 | 9 | DIGIT [0-9]+ 10 | ID [a-zA-Z_][0-9a-zA-Z_]* 11 | FLOAT [0-9]+[.][0-9]* 12 | 13 | ARITHMETIC_OPERATORS ['+' '\-' '*' '/' '^' '%'] 14 | OTHER_CHARACTERS ['=' ';' '(' ')' '{' '}'] 15 | TYPES ["int" "float" "long" "char" "double"] 16 | FORMAT ["%d" "%f" "%s"] 17 | 18 | %% 19 | [ \t] ; 20 | [\n] ; 21 | 22 | 23 | "if" { return (IF); } 24 | "else" { return (ELSE); } 25 | "while" { return (WHILE); } 26 | 27 | "int" { return (TYPES); } 28 | "float" { return (TYPES); } 29 | "long" { return (TYPES); } 30 | "char" { return (TYPES); } 31 | "double" { return (TYPES); } 32 | 33 | "read" {return (READ);} 34 | "print" {return (PRINT);} 35 | 36 | %[fsd] {yylval.sval = strdup(yytext); 37 | return (FORMAT);} 38 | 39 | ">" {yylval.sval = strdup(yytext); 40 | return (REL_OPT);} 41 | "<" {yylval.sval = strdup(yytext); 42 | return (REL_OPT);} 43 | ">=" {yylval.sval = strdup(yytext); 44 | return (REL_OPT);} 45 | "<=" {yylval.sval = strdup(yytext); 46 | return (REL_OPT);} 47 | "!=" {yylval.sval = strdup(yytext); 48 | return (REL_OPT);} 49 | "==" {yylval.sval = strdup(yytext); 50 | return (REL_OPT);} 51 | 52 | "||" {yylval.sval = strdup(yytext); 53 | return (OR);} 54 | "&&" {yylval.sval = strdup(yytext); 55 | return (AND);} 56 | "!" {yylval.sval = strdup(yytext); 57 | return (NOT);} 58 | "true" {yylval.sval = strdup(yytext); 59 | return (TRUE);} 60 | "false" {yylval.sval = strdup(yytext); 61 | return (FALSE);} 62 | 63 | {DIGIT} { yylval.ival = atoi(yytext); 64 | return DIGIT; } 65 | 66 | {FLOAT} { yylval.fval = atof(yytext); 67 | return FLOAT; } 68 | 69 | {ID} { 70 | yylval.sval = strdup(yytext); 71 | return ID; 72 | } 73 | {ARITHMETIC_OPERATORS} { 74 | c = yytext[0]; 75 | return(c); 76 | } 77 | 78 | {OTHER_CHARACTERS} { 79 | c = yytext[0]; 80 | return(c); 81 | } 82 | 83 | %% 84 | 85 | int yywrap() 86 | { 87 | return 1; 88 | } 89 | -------------------------------------------------------------------------------- /Lab5-PredictiveParsing/README.md: -------------------------------------------------------------------------------- 1 | # Predictive parsing (Top-down) 2 | 3 | *Compilation order* : PrettyPrinter.java followed by FirstAndFollow.java (or *AugmentedFirstAndFollow.java*), the other two in any order 4 | 5 | **Working of FirstAndFollow.java**: We take the productions one by one and put them in a map. 6 | First set is calculated as follows: 7 | For each production **A->x**, if there is a terminal at the start of **x**, add the terminal to the first set of **A**. 8 | Else, recursively calculate the first set of the non-terminal and add it to first set of **A**. 9 | Follow set is calculated as: 10 | For each production **A->xSb**, if there is a terminal (b) following the non-terminal **(S)**, add the terminal to follow set of non-terminal. 11 | Else, if non-terminal follows a non-terminal, add it's first to the follow set of the non-terminal. Keep doing this until the fisrt set of non-terminal has no epsilon 12 | Add **'$'** to the follow set of start symbol 13 | If the non-terminal in question is last symbol of a production and the generating non-terminal is not the same as it, add follow of generating non-terminal to it. 14 | 15 | Q1) It does nothing. Simply creates an object of FirstAndFollow.java and calls the modules to test a few Strings. 16 | Q2) My implementation had a limitation that only characters can be terminals/non-terminals. Hence, I first used the *fill()* function in Q5_2.java to create a mapping for all the tokens to a single character. So, the transformations are: 17 | *map.txt (actual input)* -> *Grammar_LL2.txt(parsable grammar)* 18 | Then, a Lex program (*q3.l*) converts the given input file (*input.txt*) to tokens (*output.txt*); 19 | Then, I use the map to transform it again: *output.txt->map2.txt* 20 | Fianlly, the object is called and it proceeds as question 1. 21 | 22 | **PrettyPrinter.java** simply formats the table. 23 | 24 | You can use the rMap maps in the Q2_5.java to reverse the symbols back. 25 | 26 | **AugmentedFirstAndFollow.java** removes the limitations of 'character-only' tokens of **FirstAndFollow.java** and can handle left-recursive grammars too. Also, it's more object-oriented. -------------------------------------------------------------------------------- /Lab12-AST/transformInput.py: -------------------------------------------------------------------------------- 1 | from pprint import pprint 2 | 3 | def isStart(i, trim_map): 4 | for key, value in trim_map.items(): 5 | for val in value: 6 | if val[0]==i: 7 | return True 8 | return False 9 | 10 | def isEnd(i, trim_map): 11 | for key, value in trim_map.items(): 12 | for val in value: 13 | if val[1]==i: 14 | return True 15 | return False 16 | 17 | def subString(Str,n): 18 | 19 | #range_list=[] 20 | substring_map={} 21 | # Pick starting point 22 | for Len in range(1,n + 1): 23 | 24 | # Pick ending point 25 | for i in range(n - Len + 1): 26 | 27 | # Print characters from current 28 | # starting point to current ending 29 | # point. 30 | j = i + Len - 1 31 | 32 | newString = "" 33 | for k in range(i,j + 1): 34 | newString += Str[k] 35 | 36 | """if newString in substring_set: 37 | flag=True 38 | for index in range(0,len(range_list)): 39 | if range_list[index][0]j: #Completely consumed 40 | flag=False 41 | break; 42 | if flag: 43 | range_list.append((i,j));""" 44 | 45 | if newString in substring_map: 46 | substring_map[newString].append((i,j)) 47 | else: 48 | substring_map[newString]=[(i,j)] 49 | #print() 50 | 51 | trim_map={} 52 | trim_copy={} 53 | for key, value in substring_map.items(): 54 | if len(value)>1 and len(key)>2 and key[0] not in ("+","-","*","/"): 55 | trim_map[key]=value 56 | trim_copy[key]=value 57 | 58 | 59 | keyList=list(trim_map.keys()) 60 | keyList = [str(i) for i in keyList] 61 | 62 | for key, value in trim_copy.items(): 63 | for i in range(0,len(keyList)): 64 | if key!=keyList[i] and key in keyList[i]: 65 | trim_map.pop(key,'None') 66 | 67 | #pprint(trim_map) 68 | 69 | """for i in substring_set: 70 | if substring_set 71 | print(range_list)""" 72 | 73 | modified_string = "" 74 | for i in range (0,len(Str)): 75 | if isStart(i,trim_map): 76 | if ord(Str[i])>=97 and ord(Str[i])<=122: 77 | modified_string+="("+Str[i] 78 | else: 79 | modified_string+=Str[i]+"(" 80 | elif isEnd(i,trim_map): 81 | if ord(Str[i])>=97 and ord(Str[i])<=122: 82 | modified_string+=Str[i]+")" 83 | else: 84 | modified_string+=")"+Str[i] 85 | else: 86 | modified_string+=Str[i] 87 | 88 | return modified_string 89 | 90 | s="a+b+c+e*d*x+z+a+b+c+k*x+z" 91 | s=input() 92 | t=len(s) 93 | print(subString(s,t)) -------------------------------------------------------------------------------- /Lab12-AST/ast.y: -------------------------------------------------------------------------------- 1 | %{ 2 | /* Definition section */ 3 | #include 4 | #include 5 | typedef struct node{ 6 | int isOp; 7 | int type; 8 | struct node *left; 9 | struct node *right; 10 | }node; 11 | #define YYSTYPE node* 12 | void yyerror(char *s); 13 | void preorder(node *x); 14 | #include "ast.tab.h" 15 | #include "lex.yy.c" 16 | int flag=0; 17 | %} 18 | 19 | %token NUMBER 20 | 21 | %left '+' '-' 22 | 23 | %left '*' '/' '%' 24 | 25 | /* Rule Section */ 26 | %% 27 | 28 | ArithmeticExpression: 29 | E{ 30 | printf("\nResult\n"); 31 | preorder($1); 32 | return 0; 33 | }; 34 | E:E'+'T 35 | { 36 | node *newnode=(node *)malloc(sizeof(node)); 37 | newnode->isOp=1; 38 | newnode->type=0; 39 | newnode->left=$1; 40 | newnode->right=$3; 41 | $$=newnode; 42 | } 43 | |E'-'T 44 | { 45 | node *newnode=(node *)malloc(sizeof(node)); 46 | newnode->isOp=1; 47 | newnode->type=1; 48 | newnode->left=$1; 49 | newnode->right=$3; 50 | $$=newnode; 51 | } 52 | |T 53 | { 54 | $$=$1; 55 | }; 56 | T: T'*'F 57 | { 58 | node *newnode=(node *)malloc(sizeof(node)); 59 | newnode->isOp=1; 60 | newnode->type=2; 61 | newnode->left=$1; 62 | newnode->right=$3; 63 | $$=newnode; 64 | } 65 | 66 | |T'/'F 67 | { 68 | node *newnode=(node *)malloc(sizeof(node)); 69 | newnode->isOp=1; 70 | newnode->type=3; 71 | newnode->left=$1; 72 | newnode->right=$3; 73 | $$=newnode; 74 | } 75 | 76 | | F {$$=$1;} 77 | 78 | ; 79 | 80 | F: NUMBER 81 | { 82 | 83 | $$=$1; 84 | } 85 | | '('NUMBER')' 86 | { 87 | $$=$2; 88 | }; 89 | 90 | %% 91 | void main() 92 | { 93 | printf("Enter Any Arithmetic Expression with +,-,* and / only\n"); 94 | yyparse(); 95 | } 96 | void preorder(node *x) 97 | { 98 | if (x==NULL) 99 | return; 100 | if(x->isOp) 101 | { 102 | switch(x->type) 103 | { 104 | case 0: 105 | printf("+ "); 106 | break; 107 | case 1: 108 | printf("- "); 109 | break; 110 | case 2: 111 | printf("* "); 112 | break; 113 | case 3: 114 | printf("/ "); 115 | break; 116 | default: 117 | yyerror("Unknown symbol"); 118 | break; 119 | } 120 | } 121 | else 122 | { 123 | printf("%d ",x->type); 124 | } 125 | preorder(x->left); 126 | preorder(x->right); 127 | } 128 | void yyerror(char *s) 129 | { 130 | printf("Entered arithmetic expression is Invalid\n"); 131 | flag=1; 132 | } -------------------------------------------------------------------------------- /Lab6-SLRParsing/README.md: -------------------------------------------------------------------------------- 1 | # LR (0) Parsing: SLR method 2 | 3 | *Compilation order* : *PrettyPrinter.java* followed by *AugmentedFirstAndFollow.java* followed by *LR_parser.java* . 4 | 5 | **Working of AugmentedFirstAndFollow.java**: We take the productions one by one and put them in a map. 6 | First set is calculated as follows: 7 | For each production **A->x**, if there is a terminal at the start of **x**, add the terminal to the first set of **A**. 8 | Else, recursively calculate the first set of the non-terminal and add it to first set of **A**. 9 | Follow set is calculated as: 10 | For each production **A->xSb**, if there is a terminal (b) following the non-terminal **(S)**, add the terminal to follow set of non-terminal. 11 | Else, if non-terminal follows a non-terminal, add it's first to the follow set of the non-terminal. Keep doing this until the fisrt set of non-terminal has no epsilon 12 | Add **'$'** to the follow set of start symbol 13 | If the non-terminal in question is last symbol of a production and the generating non-terminal is not the same as it, add follow of generating non-terminal to it. 14 | 15 | **LR_parser.java** : It defines two primary functions- *closure* and *goto* 16 | *Closure (Set)* : Add the input set to final set. Then, for each rule in the input set, if the **dot** following it is a non-terminal, add the productions of that to the final set till no more elements can be added. 17 | *Goto (Set, Symbol)* : For all the pairs in the set which have the dot infront of the symbol passed alongside the set, add them to the final set by shifting the dot one position to right. Then, calculate closure for all those elements and add them to the set. 18 | The DFA and parsing table are built following the techniques described [here]([https://www.geeksforgeeks.org/parsing-set-3-slr-clr-and-lalr-parsers/](https://www.geeksforgeeks.org/parsing-set-3-slr-clr-and-lalr-parsers/)) 19 | 20 | **PrettyPrinter.java** simply formats the table. 21 | 22 | **Note**: The question is configured to directly run the grammar given in file Grammar.txt. If you want to change it to use GrammarQ6.txt (say), please navigate to the constructor of LR_parser.java and ensure that all commands like *terminals.add()...* and *nonTerminals.add()...* are removed and replaced by the following commands: 23 | terminals.add("="); 24 | terminals.add("id"); 25 | terminals.add("*"); 26 | nonTerminals.add("S"); 27 | nonTerminals.add("L"); 28 | nonTerminals.add("R"); 29 | 30 | Also, the input to be evaluated should be like this: id + ( id ) $ {Space separated with a $ at end}. Also, the input to both utils and obj should be same (Don't use Grammar.txt in one and GrammarQ6.txt in the other) -------------------------------------------------------------------------------- /Parser_Library/DemoClass.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | public class DemoClass 4 | { 5 | public static void main(String args[]) 6 | { 7 | /**First demonstarate LR0*/ 8 | /**Standard mode, to be used for quick checking*/ 9 | LR0Parser obj=new LR0Parser(); 10 | obj.read_grammar("LR0.txt"); 11 | obj.buildDFA(); 12 | System.out.println(obj.getParsingTable(false)?"Grammar is LR0 :)":"Grammar isn't LR0 :("); 13 | System.out.println(obj.parse("a c d",false)?"Successfully parsed":"Parse Failure"); 14 | System.out.println(obj.parse("a c d k",false)?"Successfully parsed":"Parse Failure") ; 15 | /**Debug mode*/ 16 | System.out.println(obj.states); 17 | obj.print_transitions(); 18 | obj.getParsingTable(true); 19 | obj.parse("a c d",true); 20 | /**Now SLR*/ 21 | SLRParser obj2=new SLRParser(); 22 | obj2.read_grammar("LR0.txt"); 23 | obj2.buildDFA(); 24 | System.out.println(obj2.getParsingTable(false)?"Grammar is SLR :)":"Grammar isn't SLR :("); 25 | System.out.println(obj2.parse("a c d",false)?"Successfully parsed":"Parse Failure"); 26 | System.out.println(obj2.parse("a c d k",false)?"Successfully parsed":"Parse Failure"); 27 | /**Debug mode*/ 28 | System.out.println(obj2.states); 29 | obj2.print_transitions(); 30 | obj2.getParsingTable(true); 31 | obj2.parse("a c d",true); 32 | /**Now LR1*/ 33 | LR1Parser obj3=new LR1Parser(); 34 | obj3.read_grammar("LR0.txt"); 35 | obj3.buildDFA(); 36 | System.out.println(obj3.getParsingTable(false)?"Grammar is LR1 :)":"Grammar isn't LR1 :("); 37 | System.out.println(obj3.parse("a c d",false)?"Successfully parsed":"Parse Failure"); 38 | System.out.println(obj3.parse("a c d k",false)?"Successfully parsed":"Parse Failure"); 39 | /**Debug mode*/ 40 | System.out.println(obj3.states); 41 | obj3.print_transitions(); 42 | obj3.getParsingTable(true); 43 | obj3.parse("a c d",true); 44 | LALRParser obj4=new LALRParser(); 45 | obj4.read_grammar("LR0.txt"); 46 | obj4.buildDFA(); 47 | System.out.println(obj4.getParsingTable(false)?"Grammar is LALR :)":"Grammar isn't LALR :("); 48 | System.out.println(obj4.parse("a c d",false)?"Successfully parsed":"Parse Failure"); 49 | System.out.println(obj4.parse("a c d k",false)?"Successfully parsed":"Parse Failure"); 50 | /**Debug mode*/ 51 | System.out.println(obj4.states); 52 | obj4.print_transitions(); 53 | obj4.getParsingTable(true); 54 | obj4.parse("a c d",true); 55 | } 56 | } -------------------------------------------------------------------------------- /Lab9-SelfCorrectingParser/README.md: -------------------------------------------------------------------------------- 1 | # Assignment 9 2 | 3 | **Solution for error recovery** 4 | 5 | The solution is not complete, as it cannot handle inserting missing tokens (only check for replacements and deletes tokens). Also, I have adopted a greedy strategy to quickly choose which token to replace the wrong token with, which is wrong in some cases (the correct way would be try all tokens and choose the one which has the longest match, but that creates an entirely too big recursion tree). 6 | 7 | The best way would probably be to use the initial specification of parser generated by code, then fill in the blank entries manually by logic and inspection 8 | 9 | My approach is a mixture of all. It tries to repair the input and parse, and if it can't, simply gives up and announces **error** else announces **Can be derived**. 10 | 11 | **Error correcting actions taken**: 12 | 13 | - Delete duplicated tokens (Except duplicate brackets) to handle "; ;", "+ +", errors 14 | 15 | - Replace tokens where we know for certain what the next token would be: Example: Only **id** can follow **scan** 16 | 17 | - Handled assignment and equality mismatch specifically (:= and =) as it's the most common, etc. 18 | 19 | - Try all tokens recursively in case of token mismatch 20 | 21 | Currently in the program Q2\_5.java, an erroneous version is given which will correct itself and parse the input (with information). Some other sample screenshots are also included in the ```Images``` directory. 22 | 23 | For the correct input (as given in Q5, part 2 initially), please uncomment the top String variable **str**. 24 | 25 | **Note:** For including deletion, the blank entries in table could simply be filled with {nonterminal} -\> {epsilon}, but that was failing much more often and was closer to _panic mode_ error recovery and not _phrase level_, so I discarded that. 26 | 27 | The grammar is given in **er1.txt**. The format is all terminals on line 1, then all non-terminals on line 2 followed by all productions. Epsilon is denoted by *@*. 28 | 29 | **A demo:** 30 | 31 | *prog int id ; ; scan if id := ic then id := ( ic + ic } int id ; = prog $* 32 | 33 | ```Error: Repeated token ; at position 5 34 | Error: Missing token id at position 6 35 | Corrected token set is: [prog, int, id, ;, scan, id, if, id, :=, ic, then, id, :=, (, ic, +, ic, }, int, id, ;, =, prog, $] 36 | Error: Should use equality rather than assignment at token 9 37 | Error correction was done: Replaced token 18 with ) 38 | Error correction was done: Replaced token 19 with ; 39 | Error correction was done: Replaced token 21 with := 40 | Error correction was done: Replaced token 22 with ; 41 | Error correction was done: Replaced token 23 with end 42 | ``` 43 | 44 | _Can be derived :)_ -------------------------------------------------------------------------------- /Lab8-AssemblyExploration/lab8.s: -------------------------------------------------------------------------------- 1 | .file "lab8.c" 2 | .def ___main; .scl 2; .type 32; .endef 3 | .section .rdata,"dr" 4 | LC0: 5 | .ascii "The sorted array is:\0" 6 | LC1: 7 | .ascii "%d \0" 8 | .text 9 | .globl _main 10 | .def _main; .scl 2; .type 32; .endef 11 | _main: 12 | LFB14: 13 | .cfi_startproc 14 | pushl %ebp 15 | .cfi_def_cfa_offset 8 16 | .cfi_offset 5, -8 17 | movl %esp, %ebp 18 | .cfi_def_cfa_register 5 19 | andl $-16, %esp 20 | subl $80, %esp 21 | call ___main 22 | movl $1, 20(%esp) 23 | movl $-1, 24(%esp) 24 | movl $9, 28(%esp) 25 | movl $1, 32(%esp) 26 | movl $1, 36(%esp) 27 | movl $2, 40(%esp) 28 | movl $8, 44(%esp) 29 | movl $98, 48(%esp) 30 | movl $22, 52(%esp) 31 | movl $9, 60(%esp) 32 | movl $0, 76(%esp) 33 | jmp L2 34 | L8: 35 | movl $-1, 72(%esp) 36 | movl 76(%esp), %eax 37 | movl 60(%esp), %edx 38 | subl %eax, %edx 39 | movl %edx, %eax 40 | subl $1, %eax 41 | movl 20(%esp,%eax,4), %eax 42 | movl %eax, 64(%esp) 43 | movl $0, 68(%esp) 44 | jmp L3 45 | L5: 46 | movl 68(%esp), %eax 47 | movl 20(%esp,%eax,4), %eax 48 | cmpl 64(%esp), %eax 49 | jl L4 50 | movl 68(%esp), %eax 51 | movl 20(%esp,%eax,4), %eax 52 | movl %eax, 64(%esp) 53 | movl 68(%esp), %eax 54 | movl %eax, 72(%esp) 55 | L4: 56 | addl $1, 68(%esp) 57 | L3: 58 | movl 76(%esp), %eax 59 | movl 60(%esp), %edx 60 | subl %eax, %edx 61 | movl %edx, %eax 62 | cmpl 68(%esp), %eax 63 | jg L5 64 | cmpl $0, 72(%esp) 65 | jns L6 66 | jmp L7 67 | L6: 68 | movl 76(%esp), %eax 69 | movl 60(%esp), %edx 70 | subl %eax, %edx 71 | movl %edx, %eax 72 | subl $1, %eax 73 | movl 20(%esp,%eax,4), %eax 74 | movl %eax, 56(%esp) 75 | movl 76(%esp), %eax 76 | movl 60(%esp), %edx 77 | subl %eax, %edx 78 | movl %edx, %eax 79 | leal -1(%eax), %edx 80 | movl 72(%esp), %eax 81 | movl 20(%esp,%eax,4), %eax 82 | movl %eax, 20(%esp,%edx,4) 83 | movl 72(%esp), %eax 84 | movl 56(%esp), %edx 85 | movl %edx, 20(%esp,%eax,4) 86 | L7: 87 | addl $1, 76(%esp) 88 | L2: 89 | movl 76(%esp), %eax 90 | cmpl 60(%esp), %eax 91 | jl L8 92 | movl $LC0, (%esp) 93 | call _puts 94 | movl $0, 76(%esp) 95 | jmp L9 96 | L10: 97 | movl 76(%esp), %eax 98 | movl 20(%esp,%eax,4), %eax 99 | movl %eax, 4(%esp) 100 | movl $LC1, (%esp) 101 | call _printf 102 | addl $1, 76(%esp) 103 | L9: 104 | movl 76(%esp), %eax 105 | cmpl 60(%esp), %eax 106 | jl L10 107 | movl $10, (%esp) 108 | call _putchar 109 | movl $0, %eax 110 | leave 111 | .cfi_restore 5 112 | .cfi_def_cfa 4, 4 113 | ret 114 | .cfi_endproc 115 | LFE14: 116 | .ident "GCC: (GNU) 4.8.1" 117 | .def _puts; .scl 2; .type 32; .endef 118 | .def _printf; .scl 2; .type 32; .endef 119 | .def _putchar; .scl 2; .type 32; .endef -------------------------------------------------------------------------------- /Lab10-BasicYaccCalculator/calculator.tab.h: -------------------------------------------------------------------------------- 1 | /* A Bison parser, made by GNU Bison 2.7. */ 2 | 3 | /* Bison interface for Yacc-like parsers in C 4 | 5 | Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . */ 19 | 20 | /* As a special exception, you may create a larger work that contains 21 | part or all of the Bison parser skeleton and distribute that work 22 | under terms of your choice, so long as that work isn't itself a 23 | parser generator using the skeleton or a modified version thereof 24 | as a parser skeleton. Alternatively, if you modify or redistribute 25 | the parser skeleton itself, you may (at your option) remove this 26 | special exception, which will cause the skeleton and the resulting 27 | Bison output files to be licensed under the GNU General Public 28 | License without this special exception. 29 | 30 | This special exception was added by the Free Software Foundation in 31 | version 2.2 of Bison. */ 32 | 33 | #ifndef YY_YY_CALCULATOR_TAB_H_INCLUDED 34 | # define YY_YY_CALCULATOR_TAB_H_INCLUDED 35 | /* Enabling traces. */ 36 | #ifndef YYDEBUG 37 | # define YYDEBUG 0 38 | #endif 39 | #if YYDEBUG 40 | extern int yydebug; 41 | #endif 42 | 43 | /* Tokens. */ 44 | #ifndef YYTOKENTYPE 45 | # define YYTOKENTYPE 46 | /* Put the tokens into the symbol table, so that GDB and other debuggers 47 | know about them. */ 48 | enum yytokentype { 49 | NUMBER = 258 50 | }; 51 | #endif 52 | 53 | 54 | #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED 55 | typedef int YYSTYPE; 56 | # define YYSTYPE_IS_TRIVIAL 1 57 | # define yystype YYSTYPE /* obsolescent; will be withdrawn */ 58 | # define YYSTYPE_IS_DECLARED 1 59 | #endif 60 | 61 | extern YYSTYPE yylval; 62 | 63 | #ifdef YYPARSE_PARAM 64 | #if defined __STDC__ || defined __cplusplus 65 | int yyparse (void *YYPARSE_PARAM); 66 | #else 67 | int yyparse (); 68 | #endif 69 | #else /* ! YYPARSE_PARAM */ 70 | #if defined __STDC__ || defined __cplusplus 71 | int yyparse (void); 72 | #else 73 | int yyparse (); 74 | #endif 75 | #endif /* ! YYPARSE_PARAM */ 76 | 77 | #endif /* !YY_YY_CALCULATOR_TAB_H_INCLUDED */ 78 | -------------------------------------------------------------------------------- /Parser_Library/README.md: -------------------------------------------------------------------------------- 1 | # Parser_Library: An easy-to-use library to quickly debug your work. 2 | 3 | Currently supported parsers: *LR0*, *SLR*, *LR1* and *LALR* parsers. 4 | A basic usage of the library is as easy as follows: 5 | 6 | ```java 7 | LR1Parser obj=new LR1Parser();//Create an instance of the desired parser-In this case LR1 type parser 8 | obj.read_grammar("D://Documents/Lab4/LR0.txt");//Read the grammar file 9 | obj.buildDFA();//Build a dfa from the file 10 | System.out.println(obj.states);//Prints the transitions in all states 11 | obj.print_transitions();//Print all the transitions 12 | obj.getParsingTable(true);//Use false to avoid printing the table after creation 13 | obj.parse("a c e",true);//Parse the string; use false to prevent the stack actions from displaying on screen 14 | ``` 15 | - The map of the states 16 | 17 | ![map](https://user-images.githubusercontent.com/25523604/64479680-d9936480-d1d7-11e9-9461-66f5ae88e970.PNG) 18 | 19 | - The parse table 20 | 21 | ![table](https://user-images.githubusercontent.com/25523604/64479682-d9936480-d1d7-11e9-95a1-c502f42eb3e1.PNG) 22 | 23 | - The actions taken by stack to parse the table 24 | 25 | ![Stack_actions](https://user-images.githubusercontent.com/25523604/64479679-d8face00-d1d7-11e9-826b-1674716a80aa.PNG) 26 | 27 |

Functions

28 | 29 | *Parser.java* is the base class which all the other classes inherit from. It exposes the following methods: 30 | 31 | |Function|Return Type|Action| 32 | |------|---------|---------| 33 | read_grammar|void|Reads the grammar, augments it and fills in the list of terminals and non-terminals 34 | join|String|Utility method to join convert ArrayList to String 35 | getClosure|void|Accepts a HashSet of type and computes it's closure 36 | getGoto|HashSetComputes Goto 37 | augment, unaugment| void,void| Augments and unaugments the grammar 38 | parse|void|Parses the string using the generated table 39 | getIndex|int|Returns the index of the state, or -1 if a new state 40 | pretty_it|void|Formatting 41 | print_transitions|void|Prints all transitions 42 | 43 | You can either clone the repository here for a minimal usage, or download it from maven, with full documentation and junit tests. 44 | 45 | For **release** build: 46 | 47 | ```java 48 | 49 | io.github.PalAditya 50 | parser-library 51 | 0.1.1 52 | 53 | ``` 54 | 55 | For **snapshot** build: 56 | 57 | ```java 58 | 59 | io.github.PalAditya 60 | parser-library 61 | 0.1-SNAPSHOT 62 | 63 | ``` 64 | 65 | In case you want the pre-release (latest) versions, you can download it manually from [here](https://oss.sonatype.org/content/repositories/central_bundles-18962/io/github/PalAditya/parser-library/0.1.1/) 66 | 67 | **Note**: This is not being maintained anymore. Please see [here](https://github.com/PalAditya/JParser) to get the latest version of the code. 68 | -------------------------------------------------------------------------------- /Lab1-REtoNFA/wrapper.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | script, mode = sys.argv 4 | 5 | def skipWhiteSpaces(): 6 | global line 7 | while line == '\n': 8 | line = file.readline() 9 | 10 | file = open('output.txt','r') 11 | 12 | line = file.readline() 13 | line = file.readline() 14 | 15 | skipWhiteSpaces() 16 | 17 | regex = line[:-1] 18 | 19 | line = file.readline() 20 | 21 | skipWhiteSpaces() 22 | 23 | line = file.readline() 24 | 25 | nfa = {} 26 | 27 | start_nfa = 0 28 | 29 | while line[0] == 'q': 30 | trans = line.split(' ') 31 | if trans[6] == '^\n': 32 | trans[6] = 'e\n' 33 | if (trans[0],trans[6][:-1]) not in nfa.keys(): 34 | nfa[(trans[0],trans[6][:-1])] = [] 35 | nfa[(trans[0],trans[6][:-1])].append(trans[2]) 36 | line = file.readline() 37 | 38 | trans = line.split(' ') 39 | end_nfa = trans[4][:-1] 40 | 41 | line = file.readline() 42 | skipWhiteSpaces() 43 | line = file.readline() 44 | skipWhiteSpaces() 45 | 46 | dfa = {} 47 | 48 | start_dfa = 0 49 | 50 | while line[0] == 'q': 51 | trans = line.split(' ') 52 | if (trans[0],trans[8][:-1]) not in dfa.keys(): 53 | dfa[(trans[0],trans[8][:-1])] = [] 54 | dfa[(trans[0],trans[8][:-1])].append(trans[3]) 55 | line = file.readline() 56 | 57 | trans = line.split(' ') 58 | end_dfa = trans[6][:-1].split(',') 59 | 60 | file.close() 61 | 62 | if mode == '0': 63 | 64 | print "digraph finite_state_machine {" 65 | print "\trankdir=LR;" 66 | print "\tsize=\"15,10\"" 67 | print "\tlabelloc=\"b\";" 68 | print "\tcolor=white;" 69 | print "\tfontcolor=white;" 70 | print "\tbgcolor=transparent;" 71 | print "\trankdir=LR;" 72 | print "\tlabel=\"Regex : {}\";".format(regex) 73 | print "\tnode [color=white fontcolor=white shape = doublecircle label=\"\"]; addr_{}".format(end_nfa[1:]) 74 | print "\tnode [color=white fontcolor=white shape = circle]" 75 | for lhs in nfa.keys(): 76 | rhs = nfa[lhs] 77 | for value in rhs: 78 | print "\taddr_{} -> addr_{} [color=white fontcolor=white label = \"{}\" ];".format(lhs[0][1:],value[1:],lhs[1]) 79 | 80 | print "\tnode [color=white fontcolor=white shape = none label=\"\"]; start" 81 | print "\tstart -> addr_{} [color=white fontcolor=white label = \"start\" ]".format(start_nfa) 82 | print "}" 83 | 84 | elif mode == '1': 85 | 86 | print "digraph finite_state_machine {" 87 | print "\trankdir=LR;" 88 | print "\tsize=\"15,10\"" 89 | print "\tlabelloc=\"b\";" 90 | print "\tcolor=white;" 91 | print "\tfontcolor=white;" 92 | print "\tbgcolor=transparent;" 93 | print "\trankdir=LR;" 94 | print "\tlabel=\"Regex : {}\";".format(regex) 95 | for end in end_dfa: 96 | print "\tnode [color=white fontcolor=white shape = doublecircle label=\"\"]; addr_{}".format(end) 97 | print "\tnode [color=white fontcolor=white shape = circle]" 98 | for lhs in dfa.keys(): 99 | rhs = dfa[lhs] 100 | for value in rhs: 101 | print "\taddr_{} -> addr_{} [color=white fontcolor=white label = \"{}\" ];".format(lhs[0][1:],value[1:],lhs[1]) 102 | 103 | print "\tnode [color=white fontcolor=white shape = none label=\"\"]; start" 104 | print "\tstart -> addr_{} [color=white fontcolor=white label = \"start\" ]".format(start_nfa) 105 | print "}" -------------------------------------------------------------------------------- /Lab11-ExtendedYaccCalculator/calculator.tab.h: -------------------------------------------------------------------------------- 1 | /* A Bison parser, made by GNU Bison 2.7. */ 2 | 3 | /* Bison interface for Yacc-like parsers in C 4 | 5 | Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . */ 19 | 20 | /* As a special exception, you may create a larger work that contains 21 | part or all of the Bison parser skeleton and distribute that work 22 | under terms of your choice, so long as that work isn't itself a 23 | parser generator using the skeleton or a modified version thereof 24 | as a parser skeleton. Alternatively, if you modify or redistribute 25 | the parser skeleton itself, you may (at your option) remove this 26 | special exception, which will cause the skeleton and the resulting 27 | Bison output files to be licensed under the GNU General Public 28 | License without this special exception. 29 | 30 | This special exception was added by the Free Software Foundation in 31 | version 2.2 of Bison. */ 32 | 33 | #ifndef YY_YY_CALCULATOR_TAB_H_INCLUDED 34 | # define YY_YY_CALCULATOR_TAB_H_INCLUDED 35 | /* Enabling traces. */ 36 | #ifndef YYDEBUG 37 | # define YYDEBUG 0 38 | #endif 39 | #if YYDEBUG 40 | extern int yydebug; 41 | #endif 42 | /* "%code requires" blocks. */ 43 | /* Line 2058 of yacc.c */ 44 | #line 2 "calculator.y" 45 | 46 | #define YYSTYPE double 47 | 48 | 49 | /* Line 2058 of yacc.c */ 50 | #line 51 "calculator.tab.h" 51 | 52 | /* Tokens. */ 53 | #ifndef YYTOKENTYPE 54 | # define YYTOKENTYPE 55 | /* Put the tokens into the symbol table, so that GDB and other debuggers 56 | know about them. */ 57 | enum yytokentype { 58 | NUMBER = 258, 59 | POWER = 259, 60 | SINE = 260, 61 | NUMBER_F = 261, 62 | COSINE = 262, 63 | TANGENT = 263, 64 | LOGARITHM = 264, 65 | SQ_ROOT = 265, 66 | COTANGENT = 266, 67 | SECANT = 267, 68 | COSECANT = 268 69 | }; 70 | #endif 71 | 72 | 73 | #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED 74 | typedef int YYSTYPE; 75 | # define YYSTYPE_IS_TRIVIAL 1 76 | # define yystype YYSTYPE /* obsolescent; will be withdrawn */ 77 | # define YYSTYPE_IS_DECLARED 1 78 | #endif 79 | 80 | extern YYSTYPE yylval; 81 | 82 | #ifdef YYPARSE_PARAM 83 | #if defined __STDC__ || defined __cplusplus 84 | int yyparse (void *YYPARSE_PARAM); 85 | #else 86 | int yyparse (); 87 | #endif 88 | #else /* ! YYPARSE_PARAM */ 89 | #if defined __STDC__ || defined __cplusplus 90 | int yyparse (void); 91 | #else 92 | int yyparse (); 93 | #endif 94 | #endif /* ! YYPARSE_PARAM */ 95 | 96 | #endif /* !YY_YY_CALCULATOR_TAB_H_INCLUDED */ 97 | -------------------------------------------------------------------------------- /Lab4-ParsingIntroductions/Q2.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | class Q2 4 | { 5 | /** 6 | * Solution for Question 2 7 | * Please don't use any non-alphabetical characters ot Terminals other than A-L 8 | * An example input is provided in the file in2.txt 9 | * Please note that epsilon should be denoted by the "@" symbol 10 | * For the output, if it shows A->[B,Cd], that shows the production A->B|Cd 11 | * Please don't use terminals with >1 character 12 | */ 13 | public static void main(String args[])throws IOException 14 | { 15 | Q2 obj=new Q2(); 16 | obj.go(); 17 | } 18 | int a=-1; 19 | String getChar() 20 | { 21 | a++; 22 | return ((char)('M'+a))+""; 23 | } 24 | public void go()throws IOException 25 | { 26 | BufferedReader br=new BufferedReader(new FileReader("in2.txt")); 27 | String str=""; 28 | ArrayList arrr=new ArrayList<>(); 29 | while((str=br.readLine())!=null) 30 | { 31 | arrr.add(str); 32 | } 33 | for(int op=0;op"); 37 | String left=str.substring(0,l).trim(); 38 | String right=str.substring(l+2).trim(); 39 | String token[]=right.split("[|]");//Split all rules 40 | int i; 41 | l=token.length; 42 | int j; 43 | ArrayList al[]=new ArrayList[52];//Hash the characters so that we know when atleast first characters of two productions match 44 | for(i=0;i<52;i++) 45 | al[i]=new ArrayList<>(); 46 | int flag=0; 47 | for(i=0;i0) 50 | if(Character.isUpperCase(token[i].charAt(0))) 51 | al[token[i].charAt(0)-65].add(token[i]); 52 | else 53 | al[token[i].charAt(0)-97+26].add(token[i]); 54 | else 55 | { 56 | flag=1;//This to handle epsilons 57 | } 58 | } 59 | String rhs=""; 60 | for(i=0;i<52;i++) 61 | { 62 | ArrayList a=al[i]; 63 | if(a.size()>=2) 64 | { 65 | l=a.size(); 66 | int max=lcp(a.get(0),a.get(1)); 67 | //LCP is min of all LCPs 68 | for(j=2;j";//Break after LCP 76 | for(j=0;j"+rhs.substring(0,rhs.length()-1)); 92 | if(flag==1) 93 | System.out.println("|@"); 94 | else 95 | System.out.println(""); 96 | } 97 | } 98 | //Return longest common prefix among two Strings 99 | int lcp(String a,String b) 100 | { 101 | int i,l=a.length(); 102 | l=(b.length() 3 | #include "lex.yy.c" 4 | int flag=0; 5 | void yyerror(const char *str); 6 | %} 7 | %locations 8 | %token AND ASSIGN COLON COMMA DEF DIV DOT ELSE END EQ EXITLOOP FLOAT FLOAT_CONST FORMAT FROM FUN GE GLOBAL GT ID IF INT INT_CONST LEFT_PAREN LEFT_SQ_BKT LE LT MINUS MOD MULT NE NOT NUL OR PLUS PRINT PRODUCT READ RETURN RETURNS RIGHT_PAREN RIGHT_SQ_BKT SEMICOLON SKIP STEP STRING TO WHILE 9 | 10 | %left PLUS MINUS 11 | %left MULT DIV MOD 12 | %nonassoc UMINUS UPLUS 13 | %nonassoc DOT 14 | %left AND OR 15 | %nonassoc NOT 16 | %left LEFT_SQ_BKT RIGHT_SQ_BKT 17 | %left LEFT_PAREN RIGHT_PAREN 18 | %nonassoc IFX 19 | %nonassoc ELSE 20 | 21 | %start S 22 | 23 | /* Rule Section */ 24 | %% 25 | S: prog 26 | { 27 | printf("Successfully parsed"); 28 | return 0; 29 | }; 30 | prog : GLOBAL declList stmtListO END {} ; 31 | 32 | declList: decl declList {} 33 | | {}; 34 | 35 | decl: DEF typeList END {} 36 | |FUN funDef END {} ; 37 | 38 | typeList: typeList SEMICOLON varList COLON type {} 39 | |varList COLON type {} 40 | |typeDef {}; 41 | 42 | varList: var COMMA varList {} 43 | |var {}; 44 | 45 | var: ID sizeListO {}; 46 | 47 | sizeListO: sizeList {} 48 | | {}; 49 | 50 | sizeList: sizeList LEFT_SQ_BKT INT_CONST RIGHT_SQ_BKT {} 51 | |LEFT_SQ_BKT INT_CONST RIGHT_SQ_BKT {}; 52 | 53 | type: INT {} 54 | |FLOAT {} 55 | |STRING {} 56 | |NUL {} 57 | |typeDef {} 58 | |ID {}; 59 | 60 | typeDef: ID ASSIGN PRODUCT typeList END {}; 61 | 62 | funDef: funID fParamListO RETURNS type funBody {}; 63 | 64 | funID: ID {}; 65 | 66 | fParamListO: fParamList {} 67 | | {}; 68 | 69 | fParamList: fParamList SEMICOLON pList COLON type {} 70 | |pList COLON type {}; 71 | 72 | pList: pList COMMA idP {} 73 | |idP {}; 74 | 75 | idP: ID sizeListO {}; 76 | 77 | funBody: declList stmtListO {}; 78 | 79 | stmtListO: stmtList {} 80 | | {}; 81 | 82 | stmtList: stmtList SEMICOLON stmt {} 83 | | stmt {}; 84 | 85 | stmt: assignmentStmt {} 86 | |readStmt {} 87 | |printStmt {} 88 | |ifStmt {} 89 | |whileStmt {} 90 | |loopStmt {} 91 | |callStmt {} 92 | |returnStmt {} 93 | |exitLoop {} 94 | |skip{}; 95 | 96 | assignmentStmt: dotId ASSIGN exp {}; 97 | 98 | dotId: id {} 99 | |id DOT dotId {}; 100 | 101 | readStmt: READ FORMAT exp {}; 102 | 103 | printStmt: PRINT STRING {} 104 | |PRINT FORMAT exp {}; 105 | 106 | ifStmt: IF bExp COLON stmtList elsePart END {}; 107 | 108 | elsePart: ELSE stmtList {} 109 | | {}; 110 | 111 | whileStmt: WHILE bExp COLON stmtList END {}; 112 | 113 | loopStmt: FROM id ASSIGN exp TO exp stepPart COLON stmtListO END {}; 114 | 115 | stepPart: STEP exp {} 116 | | {}; 117 | 118 | callStmt: LEFT_PAREN ID COLON actParamList RIGHT_PAREN {}; 119 | 120 | returnStmt: RETURN expO {}; 121 | 122 | expO: exp {} 123 | | {}; 124 | 125 | exitLoop: EXITLOOP {}; 126 | 127 | skip: SKIP {}; 128 | 129 | id: ID indxListO {}; 130 | 131 | indxListO: indxList {} 132 | | {}; 133 | 134 | indxList: indxList LEFT_SQ_BKT exp RIGHT_SQ_BKT {} 135 | | LEFT_SQ_BKT exp RIGHT_SQ_BKT{}; 136 | 137 | bExp: bExp OR bExp {} 138 | | bExp AND bExp {} 139 | | NOT bExp {} 140 | | LEFT_PAREN bExp RIGHT_PAREN{} 141 | | exp relOP exp {}; 142 | 143 | relOP: EQ {} 144 | |LE {} 145 | |LT {} 146 | |GE {} 147 | |GT {} 148 | |NE {}; 149 | 150 | exp: exp PLUS exp {} 151 | | exp MINUS exp {} 152 | | exp MULT exp {} 153 | | exp DIV exp {} 154 | | exp MOD exp {} 155 | | MINUS exp {} 156 | | PLUS exp {} 157 | | exp DOT exp {} 158 | | LEFT_PAREN exp RIGHT_PAREN {} 159 | | id {} 160 | | LEFT_PAREN ID COLON actParamListO RIGHT_PAREN {} 161 | | INT_CONST {} 162 | | FLOAT_CONST {}; 163 | 164 | actParamListO: actParamList {} 165 | | {}; 166 | 167 | actParamList: actParamList COMMA exp {} 168 | | exp {}; 169 | 170 | %% 171 | 172 | void main() 173 | { 174 | extern FILE *yyin; 175 | yyin = fopen("a.txt","r"); 176 | yyparse(); 177 | if(flag==0) 178 | printf("\nEntered program is Valid\n\n"); 179 | } 180 | 181 | void yyerror(const char *str) 182 | { 183 | fprintf(stderr,"Error | Line: %d\n%s\n",yylineno,str); 184 | flag=1; 185 | } 186 | 187 | -------------------------------------------------------------------------------- /Lab5-PredictiveParsing/Q2_5.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | class Q2_5 4 | { 5 | String fLine=""; 6 | ArrayList ntMap=new ArrayList<>(); 7 | ArrayList tMap=new ArrayList<>(); 8 | static void fill(HashMap map1, HashMap map2,HashMap rmap1,HashMap rmap2) 9 | { 10 | char ch='A'; 11 | String nonTerminals="AE BE D DL E F ES IOS IS NE P PE RE S SL T TY VL WS U W V X Y [ Z"; 12 | String terminals="+ - * / = < > ( ) { } := ; and else end ic id if int do fc float not or print prog scan str then while"; 13 | String s1[]=nonTerminals.split(" "); 14 | int i; 15 | for(i=0;i map1=new HashMap<>(); 66 | HashMap map2=new HashMap<>(); 67 | HashMap rmap1=new HashMap<>(); 68 | HashMap rmap2=new HashMap<>(); 69 | BufferedReader br=new BufferedReader(new FileReader("utt.txt")); 70 | String str=""; 71 | int i; 72 | while((str=br.readLine())!=null)//Read the string, put in map 73 | { 74 | String tokens[]=str.split(" "); 75 | for(i=0;i")) 78 | System.out.print("-> "); 79 | else if(tokens[i].equals("|")) 80 | System.out.print("| "); 81 | else if(tokens[i].charAt(0)>=65&&tokens[i].charAt(0)<=91) 82 | { 83 | System.out.print(map1.get(tokens[i])+" "); 84 | } 85 | else 86 | { 87 | System.out.print(map2.get(tokens[i])+" "); 88 | } 89 | } 90 | System.out.println(); 91 | } 92 | } 93 | public static void main(String args[])throws IOException 94 | { 95 | String str=""; 96 | FirstAndFollow obj=new FirstAndFollow(); 97 | ArrayList arr[][]=obj.module1("grammarLL_2.txt"); 98 | if(arr==null) 99 | { 100 | System.out.println("Exiting...:("); 101 | } 102 | BufferedReader br=new BufferedReader(new FileReader("map2.txt")); 103 | String p=""; 104 | while((str=br.readLine())!=null) 105 | { 106 | p=p+str+" "; 107 | } 108 | p=p+"$ "; 109 | System.out.print("+ $ "); 110 | obj.module2(arr,"+ $"); 111 | System.out.print("+ p $ "); 112 | obj.module2(arr,"+ p $ "); 113 | System.out.print("+ t r m p $ "); 114 | obj.module2(arr,"+ t r m p $"); 115 | //The input program 116 | System.out.print(p+" "); 117 | obj.module2(arr,p); 118 | } 119 | } -------------------------------------------------------------------------------- /Lab12-AST/dag.y: -------------------------------------------------------------------------------- 1 | %{ 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | typedef struct node{ 8 | int isOp; 9 | char type; 10 | int id; 11 | struct node *left; 12 | struct node *right; 13 | }node; 14 | 15 | #define YYSTYPE node* 16 | 17 | void yyerror(char *s); 18 | void postorder(node *x, int visited[]); 19 | int check(char temp[100]); 20 | 21 | int flag=0; 22 | int index1=0; 23 | char expressions[100][100]; 24 | node* list[100]; 25 | 26 | #include "dag.tab.h" 27 | #include "lex.yy.c" 28 | 29 | %} 30 | 31 | %token ID 32 | 33 | %left '+' '-' 34 | %left '*' '/' 35 | 36 | %% 37 | 38 | ArithmeticExpression: 39 | E 40 | { 41 | printf("\nResult\n"); 42 | int visited[index1]; 43 | int i; 44 | for(i=0;iid],expressions[$3->id]); 53 | 54 | int ret = check(temp); 55 | if(ret >= 0) 56 | $$ = list[ret]; 57 | else 58 | { 59 | node *newnode=(node *)malloc(sizeof(node)); 60 | newnode->isOp=1; 61 | newnode->type='+'; 62 | newnode->left=$1; 63 | newnode->right=$3; 64 | newnode->id = index1; 65 | 66 | $$=newnode; 67 | 68 | list[index1] = $$; 69 | strcpy(expressions[index1++],temp); 70 | } 71 | } 72 | 73 | |E'-'E 74 | { 75 | char temp[100]; 76 | sprintf(temp,"%s - %s",expressions[$1->id],expressions[$3->id]); 77 | 78 | int ret = check(temp); 79 | if(ret >= 0) 80 | $$ = list[ret]; 81 | else 82 | { 83 | node *newnode=(node *)malloc(sizeof(node)); 84 | newnode->isOp=1; 85 | newnode->type='-'; 86 | newnode->left=$1; 87 | newnode->right=$3; 88 | newnode->id = index1; 89 | 90 | $$=newnode; 91 | 92 | list[index1] = $$; 93 | strcpy(expressions[index1++],temp); 94 | } 95 | } 96 | 97 | |E'*'E 98 | { 99 | //printf("In multiply"); 100 | char temp[100]; 101 | //strcpy(temp,$1-> 102 | sprintf(temp,"%s * %s",expressions[$1->id],expressions[$3->id]); 103 | //printf("temp is: %s\n",temp); 104 | //printf("Didn't crash"); 105 | int ret = check(temp); 106 | if(ret >= 0) 107 | $$ = list[ret]; 108 | else 109 | { 110 | node *newnode=(node *)malloc(sizeof(node)); 111 | newnode->isOp=1; 112 | newnode->type='*'; 113 | newnode->left=$1; 114 | newnode->right=$3; 115 | newnode->id = index1; 116 | 117 | $$=newnode; 118 | 119 | list[index1] = $$; 120 | strcpy(expressions[index1++],temp); 121 | } 122 | } 123 | 124 | |E'/'E 125 | { 126 | char temp[100]; 127 | sprintf(temp,"%s / %s",expressions[$1->id], expressions[$3->id]); 128 | 129 | int ret = check(temp); 130 | if(ret >= 0) 131 | $$ = list[ret]; 132 | else 133 | { 134 | node *newnode=(node *)malloc(sizeof(node)); 135 | newnode->isOp=1; 136 | newnode->type='/'; 137 | newnode->left=$1; 138 | newnode->right=$3; 139 | newnode->id = index1; 140 | 141 | $$=newnode; 142 | 143 | list[index1] = $$; 144 | strcpy(expressions[index1++],temp); 145 | } 146 | } 147 | 148 | |ID 149 | { 150 | //printf("ID %c :)\n",$1->type); 151 | $$=$1; 152 | } 153 | |'(' E ')' 154 | { 155 | $$=$2; 156 | } 157 | ; 158 | 159 | %% 160 | 161 | int main() 162 | { 163 | printf("Enter Any Arithmetic Expression with +,-,* and / only: "); 164 | yyparse(); 165 | return 1; 166 | } 167 | 168 | int check(char temp[100]){ 169 | 170 | int i; 171 | for(i=0;iid]){ 185 | printf("node: %s (done)\n",expressions[x->id]); 186 | return; 187 | } 188 | 189 | visited[x->id] = 1; 190 | 191 | postorder(x->left,visited); 192 | postorder(x->right,visited); 193 | 194 | printf("node: %c\n",x->type); 195 | 196 | } 197 | 198 | void yyerror(char *s) 199 | { 200 | printf("Entered arithmetic expression is Invalid\n"); 201 | flag=1; 202 | } -------------------------------------------------------------------------------- /Parser_Library/PrettyPrinter.java: -------------------------------------------------------------------------------- 1 | import java.io.PrintStream; 2 | import java.util.*; 3 | import static java.lang.String.format; 4 | import static java.lang.System.out; 5 | 6 | public final class PrettyPrinter { 7 | 8 | private static final char BORDER_KNOT = '+'; 9 | private static final char HORIZONTAL_BORDER = '-'; 10 | private static final char VERTICAL_BORDER = '|'; 11 | 12 | private static final String DEFAULT_AS_NULL = "(NULL)"; 13 | 14 | private final PrintStream out; 15 | private final String asNull; 16 | 17 | public PrettyPrinter(PrintStream out) { 18 | this(out, DEFAULT_AS_NULL); 19 | } 20 | 21 | public PrettyPrinter(PrintStream out, String asNull) { 22 | if ( out == null ) { 23 | throw new IllegalArgumentException("No print stream provided"); 24 | } 25 | if ( asNull == null ) { 26 | throw new IllegalArgumentException("No NULL-value placeholder provided"); 27 | } 28 | this.out = out; 29 | this.asNull = asNull; 30 | } 31 | public void convert(ArrayList table[][]) 32 | { 33 | String t[][]=new String[table.length][table[0].length]; 34 | int i,j; 35 | for(i=0;i max ) { 97 | max = row.length; 98 | } 99 | } 100 | return max; 101 | } 102 | 103 | private void adjustColumnWidths(String[][] rows, int[] widths) { 104 | for ( final String[] row : rows ) { 105 | if ( row != null ) { 106 | for ( int c = 0; c < widths.length; c++ ) { 107 | final String cv = getCellValue(safeGet(row, c, asNull)); 108 | final int l = cv.length(); 109 | if ( widths[c] < l ) { 110 | widths[c] = l; 111 | } 112 | } 113 | } 114 | } 115 | } 116 | 117 | private static String padRight(String s, int n) { 118 | return format("%1$-" + n + "s", s); 119 | } 120 | 121 | private static String safeGet(String[] array, int index, String defaultValue) { 122 | return index < array.length ? array[index] : defaultValue; 123 | } 124 | 125 | private String getCellValue(Object value) { 126 | return value == null ? asNull : value.toString(); 127 | } 128 | 129 | } -------------------------------------------------------------------------------- /Lab6-SLRParsing/PrettyPrinter.java: -------------------------------------------------------------------------------- 1 | import java.io.PrintStream; 2 | import java.util.*; 3 | import static java.lang.String.format; 4 | import static java.lang.System.out; 5 | 6 | public final class PrettyPrinter { 7 | 8 | private static final char BORDER_KNOT = '+'; 9 | private static final char HORIZONTAL_BORDER = '-'; 10 | private static final char VERTICAL_BORDER = '|'; 11 | 12 | private static final String DEFAULT_AS_NULL = "(NULL)"; 13 | 14 | private final PrintStream out; 15 | private final String asNull; 16 | 17 | public PrettyPrinter(PrintStream out) { 18 | this(out, DEFAULT_AS_NULL); 19 | } 20 | 21 | public PrettyPrinter(PrintStream out, String asNull) { 22 | if ( out == null ) { 23 | throw new IllegalArgumentException("No print stream provided"); 24 | } 25 | if ( asNull == null ) { 26 | throw new IllegalArgumentException("No NULL-value placeholder provided"); 27 | } 28 | this.out = out; 29 | this.asNull = asNull; 30 | } 31 | public void convert(ArrayList table[][]) 32 | { 33 | String t[][]=new String[table.length][table[0].length]; 34 | int i,j; 35 | for(i=0;i max ) { 97 | max = row.length; 98 | } 99 | } 100 | return max; 101 | } 102 | 103 | private void adjustColumnWidths(String[][] rows, int[] widths) { 104 | for ( final String[] row : rows ) { 105 | if ( row != null ) { 106 | for ( int c = 0; c < widths.length; c++ ) { 107 | final String cv = getCellValue(safeGet(row, c, asNull)); 108 | final int l = cv.length(); 109 | if ( widths[c] < l ) { 110 | widths[c] = l; 111 | } 112 | } 113 | } 114 | } 115 | } 116 | 117 | private static String padRight(String s, int n) { 118 | return format("%1$-" + n + "s", s); 119 | } 120 | 121 | private static String safeGet(String[] array, int index, String defaultValue) { 122 | return index < array.length ? array[index] : defaultValue; 123 | } 124 | 125 | private String getCellValue(Object value) { 126 | return value == null ? asNull : value.toString(); 127 | } 128 | 129 | } -------------------------------------------------------------------------------- /Lab5-PredictiveParsing/PrettyPrinter.java: -------------------------------------------------------------------------------- 1 | import java.io.PrintStream; 2 | import java.util.*; 3 | import static java.lang.String.format; 4 | import static java.lang.System.out; 5 | 6 | public final class PrettyPrinter { 7 | 8 | private static final char BORDER_KNOT = '+'; 9 | private static final char HORIZONTAL_BORDER = '-'; 10 | private static final char VERTICAL_BORDER = '|'; 11 | 12 | private static final String DEFAULT_AS_NULL = "(NULL)"; 13 | 14 | private final PrintStream out; 15 | private final String asNull; 16 | 17 | public PrettyPrinter(PrintStream out) { 18 | this(out, DEFAULT_AS_NULL); 19 | } 20 | 21 | public PrettyPrinter(PrintStream out, String asNull) { 22 | if ( out == null ) { 23 | throw new IllegalArgumentException("No print stream provided"); 24 | } 25 | if ( asNull == null ) { 26 | throw new IllegalArgumentException("No NULL-value placeholder provided"); 27 | } 28 | this.out = out; 29 | this.asNull = asNull; 30 | } 31 | public void convert(ArrayList table[][]) 32 | { 33 | String t[][]=new String[table.length][table[0].length]; 34 | int i,j; 35 | for(i=0;i max ) { 97 | max = row.length; 98 | } 99 | } 100 | return max; 101 | } 102 | 103 | private void adjustColumnWidths(String[][] rows, int[] widths) { 104 | for ( final String[] row : rows ) { 105 | if ( row != null ) { 106 | for ( int c = 0; c < widths.length; c++ ) { 107 | final String cv = getCellValue(safeGet(row, c, asNull)); 108 | final int l = cv.length(); 109 | if ( widths[c] < l ) { 110 | widths[c] = l; 111 | } 112 | } 113 | } 114 | } 115 | } 116 | 117 | private static String padRight(String s, int n) { 118 | return format("%1$-" + n + "s", s); 119 | } 120 | 121 | private static String safeGet(String[] array, int index, String defaultValue) { 122 | return index < array.length ? array[index] : defaultValue; 123 | } 124 | 125 | private String getCellValue(Object value) { 126 | return value == null ? asNull : value.toString(); 127 | } 128 | 129 | } -------------------------------------------------------------------------------- /Lab9-SelfCorrectingParser/PrettyPrinter.java: -------------------------------------------------------------------------------- 1 | import java.io.PrintStream; 2 | import java.util.*; 3 | import static java.lang.String.format; 4 | import static java.lang.System.out; 5 | 6 | public final class PrettyPrinter { 7 | 8 | private static final char BORDER_KNOT = '+'; 9 | private static final char HORIZONTAL_BORDER = '-'; 10 | private static final char VERTICAL_BORDER = '|'; 11 | 12 | private static final String DEFAULT_AS_NULL = "(NULL)"; 13 | 14 | private final PrintStream out; 15 | private final String asNull; 16 | 17 | public PrettyPrinter(PrintStream out) { 18 | this(out, DEFAULT_AS_NULL); 19 | } 20 | 21 | public PrettyPrinter(PrintStream out, String asNull) { 22 | if ( out == null ) { 23 | throw new IllegalArgumentException("No print stream provided"); 24 | } 25 | if ( asNull == null ) { 26 | throw new IllegalArgumentException("No NULL-value placeholder provided"); 27 | } 28 | this.out = out; 29 | this.asNull = asNull; 30 | } 31 | public void convert(ArrayList table[][]) 32 | { 33 | String t[][]=new String[table.length][table[0].length]; 34 | int i,j; 35 | for(i=0;i max ) { 97 | max = row.length; 98 | } 99 | } 100 | return max; 101 | } 102 | 103 | private void adjustColumnWidths(String[][] rows, int[] widths) { 104 | for ( final String[] row : rows ) { 105 | if ( row != null ) { 106 | for ( int c = 0; c < widths.length; c++ ) { 107 | final String cv = getCellValue(safeGet(row, c, asNull)); 108 | final int l = cv.length(); 109 | if ( widths[c] < l ) { 110 | widths[c] = l; 111 | } 112 | } 113 | } 114 | } 115 | } 116 | 117 | private static String padRight(String s, int n) { 118 | return format("%1$-" + n + "s", s); 119 | } 120 | 121 | private static String safeGet(String[] array, int index, String defaultValue) { 122 | return index < array.length ? array[index] : defaultValue; 123 | } 124 | 125 | private String getCellValue(Object value) { 126 | return value == null ? asNull : value.toString(); 127 | } 128 | 129 | } -------------------------------------------------------------------------------- /Lab12-AST/3address.y: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | void yyerror(char *s); 4 | int index1=0; 5 | typedef struct node{ 6 | char addr[10]; 7 | char code[100]; 8 | }node; 9 | #define YYSTYPE node* 10 | #include "3address.tab.h" 11 | #include "lex.yy.c" 12 | char label[5]; 13 | void makeLabel(); 14 | %} 15 | 16 | 17 | %left '+' '-' 18 | %left '/' '*' 19 | 20 | %token ID NUMBER 21 | %start prog 22 | %% 23 | 24 | prog: S { 25 | printf("Output is:\n%s\n",$1->code); 26 | /*int i; 27 | for(i=0;i<100;i++) 28 | if($1->code[i]=='\0') 29 | break; 30 | else 31 | printf("%c",$1->code[i]); 32 | printf("\n");*/ 33 | } 34 | /*|BE { 35 | printf("Output is:\n%s\n",$1->code); 36 | } 37 | */ 38 | 39 | S: ID '=' E { 40 | node *newnode=(node *)malloc(sizeof(node)); 41 | //printf("Values are: %s,%s\n",$3->code,$3->addr); 42 | strcpy(newnode->code,$3->code); 43 | strcat(newnode->code,$1->addr); 44 | strcat(newnode->code,"="); 45 | strcat(newnode->code,$3->addr); 46 | $$=newnode; 47 | }; 48 | 49 | E: E '+' E { 50 | node *newnode=(node *)malloc(sizeof(node)); 51 | makeLabel(); 52 | //printf("%s\n",label); 53 | strcpy(newnode->addr,label); 54 | strcpy(newnode->code,$1->code); 55 | strcat(newnode->code,$3->code); 56 | //printf("Code block in 1(in): %s\n",newnode->code); 57 | char newcode[10]; 58 | strcpy(newcode,newnode->addr); 59 | strcat(newcode,"="); 60 | strcat(newcode,$1->addr); 61 | strcat(newcode,"+"); 62 | strcat(newcode,$3->addr); 63 | //printf("newcode block in 1: %s\n",newcode); 64 | strcat(newnode->code,newcode); 65 | strcat(newnode->code,"\n"); 66 | //printf("Code block in 1: %s\n",newnode->code); 67 | $$=newnode; 68 | } 69 | |E '*' E { 70 | node *newnode=(node *)malloc(sizeof(node)); 71 | makeLabel(); 72 | //printf("%s\n",label); 73 | strcpy(newnode->addr,label); 74 | strcpy(newnode->code,$1->code); 75 | strcat(newnode->code,$3->code); 76 | //printf("Code block in 1(in): %s\n",newnode->code); 77 | char newcode[10]; 78 | strcpy(newcode,newnode->addr); 79 | strcat(newcode,"="); 80 | strcat(newcode,$1->addr); 81 | strcat(newcode,"*"); 82 | strcat(newcode,$3->addr); 83 | //printf("newcode block in 1: %s\n",newcode); 84 | strcat(newnode->code,newcode); 85 | strcat(newnode->code,"\n"); 86 | //printf("Code block in 1: %s\n",newnode->code); 87 | $$=newnode; 88 | } 89 | |E '-' E { 90 | node *newnode=(node *)malloc(sizeof(node)); 91 | makeLabel(); 92 | //printf("%s\n",label); 93 | strcpy(newnode->addr,label); 94 | strcpy(newnode->code,$1->code); 95 | strcat(newnode->code,$3->code); 96 | //printf("Code block in 1(in): %s\n",newnode->code); 97 | char newcode[10]; 98 | strcpy(newcode,newnode->addr); 99 | strcat(newcode,"="); 100 | strcat(newcode,$1->addr); 101 | strcat(newcode,"-"); 102 | strcat(newcode,$3->addr); 103 | //printf("newcode block in 1: %s\n",newcode); 104 | strcat(newnode->code,newcode); 105 | strcat(newnode->code,"\n"); 106 | //printf("Code block in 1: %s\n",newnode->code); 107 | $$=newnode; 108 | } 109 | |E '/' E { 110 | node *newnode=(node *)malloc(sizeof(node)); 111 | makeLabel(); 112 | //printf("%s\n",label); 113 | strcpy(newnode->addr,label); 114 | strcpy(newnode->code,$1->code); 115 | strcat(newnode->code,$3->code); 116 | //printf("Code block in 1(in): %s\n",newnode->code); 117 | char newcode[10]; 118 | strcpy(newcode,newnode->addr); 119 | strcat(newcode,"="); 120 | strcat(newcode,$1->addr); 121 | strcat(newcode,"/"); 122 | strcat(newcode,$3->addr); 123 | //printf("newcode block in 1: %s\n",newcode); 124 | strcat(newnode->code,newcode); 125 | strcat(newnode->code,"\n"); 126 | //printf("Code block in 1: %s\n",newnode->code); 127 | $$=newnode; 128 | } 129 | | '-' E { 130 | node *newnode=(node *)malloc(sizeof(node)); 131 | makeLabel(); 132 | strcpy(newnode->addr,label); 133 | strcpy(newnode->code,$2->code); 134 | strcat(newnode->code,newnode->addr); 135 | strcat(newnode->code,"=-"); 136 | strcat(newnode->code,$2->addr); 137 | strcat(newnode->code,"\n"); 138 | $$=newnode; 139 | } 140 | | '(' E ')' { 141 | node *newnode=(node *)malloc(sizeof(node)); 142 | strcpy(newnode->addr,$2->addr); 143 | strcpy(newnode->code,$2->code); 144 | $$=newnode; 145 | } 146 | |ID { 147 | $$=$1; 148 | //printf("ID Values are: %s,%s\n",$1->code,$1->addr); 149 | } 150 | |NUMBER { 151 | $$=$1; 152 | //printf("NUMBER Values are: %s,%s\n",$1->code,$1->addr); 153 | }; 154 | 155 | //BE: E RELOP E 156 | %% 157 | 158 | void yyerror(char *s){ 159 | printf("Error: %s",s); 160 | } 161 | 162 | void makeLabel() 163 | { 164 | int i=0; 165 | for(i=0;i<5;i++) 166 | label[i]='\0'; 167 | label[0]='L'; 168 | char str[4]; 169 | sprintf(str, "%d", index1++); 170 | strcat(label,str); 171 | } 172 | 173 | int main(){ 174 | printf("Enter the expression: "); 175 | yyparse(); 176 | return 0; 177 | } -------------------------------------------------------------------------------- /Lab13-Extended3AddressCode/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Solution 3 | 4 | First of all, I defined a node type to hold the result as follows: 5 | 6 | ```C 7 | %union { 8 | int ival; //Useful to hold integer numbers 9 | float fval; //Useful for floating point numbers 10 | char *sval; //Strings, id, label, etc. 11 | exprType *EXPRTYPE; //The whole expression which is propagated upwards 12 | } 13 | ``` 14 | 15 | Where exprtype itself is a struct with two fields, **address** and **code**. 16 | 17 | The *modified* grammar: (Contains a subset of grammar in assignment 7) alongside SDD is given below. **Note**: This grammar requires semicolons to work, although that could have been omitted. Also, I used C style operators (&&, ||, etc.) although that can be easily changed in the lex file. 18 | 19 | ```bash 20 | S: prog {Final output; adds the final label at end for any exits like exit(0) from within code} 21 | prog : prog construct 22 | | construct 23 | |list 24 | 25 | construct : block 26 | | WHILE ‘(‘ bool ‘)’ block { Backpatching happens here. We first search for the label TRUE and then replace it with a newlabel, and do the same thing to labels NEXT and FAIL. We keep doing this recursively} 27 | | IF ‘( bool ’)’ block {Same backpatching as while} 28 | | IF ‘(‘ bool ‘)’ block else block {Same backpatching as while} 29 | 30 | block: '{' list '}' 31 | | ‘{‘ construct ‘}’ 32 | 33 | list: stat 34 | | list stat 35 | 36 | stat: ';' 37 | | READ FORMAT stat {They simplay assign the variables to $$ and propagate values upwards} 38 | | PRINT FORMAT stat 39 | | PRINT text ‘;’ 40 | | expr ';' 41 | | dec ‘;’ 42 | | dec ‘=’ expr ‘;’ 43 | 44 | dec: TYPES text 45 | 46 | bool: expr RELOP expr { We know this happens only for if/else statements or while statements, but as per our grammar, this is only for if/else. So first we add the code of both expression to a new node, then we generate the line “if {addr1} goto TRUE”, add a newline and then write “goto FAIL” } 47 | | bool OR bool {AND, OR, NOT is similar -> They first generate a newlabel, then they use the _strstr_ function inside C to find the label true (inserted when the expressions evaluate to true/false either directly or due to evaluation of itself) and replaces with the newlabel. This is like backpatching.)} 48 | | bool AND bool 49 | | NOT bool 50 | | ‘(‘ bool ‘) 51 | | TRUE {adds code “goto TRUE”} 52 | | FALSE {adds code “goto FAIL”} 53 | 54 | expr: expr ‘+’ expr // And so on, like, ‘-‘, ‘/’, etc. { gen(node); Add expr1’s address, arithmetic symbol and expr2’s address to node; Add their code, if any and return node. } 55 | 56 | text: ID {return the string to propagate upwards} 57 | 58 | number: FLOAT {convert floating value to string and return;} | DIGIT {convert integer value to string and return;} 59 | ``` 60 | **Example**: Let fragment be 61 | 62 | ```C 63 | if (x<100) 64 | { 65 | print x; 66 | } 67 | ``` 68 | Parser expands it as: *S -> prog -> construct -> block -> if ‘(‘ bool ‘)’ block -> if ‘(‘ expr RELOPT expr ‘)’ block -> if ‘(‘ expr RELOPT expr ‘)’ ‘{ list ‘}’ -> if ‘(‘ expr RELOPT expr ‘)’ ‘{ stat ‘}’ -> if ‘(‘ expr RELOPT expr ‘)’ ‘{ PRINT text ‘;’ ‘}’* 69 | 70 | Now, the innermost _PRINT text;_ evaluates to _PRINT x_ (as text->id gives id=x)_._ This code is passed untouched to _stat, list_ and finally ‘block’ of _if ‘( bool ’)’ block_ as we can see by walking backwards in the tree 71 | 72 | Then, _expr RELOP expr_ gives us, as per SDD: _if x < 100 goto TRUE \n goto FAIL_. There will be no code associated with x or 100, they will simply be propagated as x and 100 and their addresses will be added to the text. 73 | 74 | Now, if ‘( bool ‘)’ block handles it as follows: It first searches for substring true and replaces it with new label, so we now have : *if x<100 goto L1 \n goto FAIL* 75 | 76 | Next, it searches for FAIL and replaces it, so we get if x<100 goto L1 \n goto L2. 77 | 78 | Now the code of _block_ is concatenated with it, so we get: if x<100 goto L1\n goto L2 T1=print x; 79 | 80 | So, finally, output is: 81 | 82 | _if x<100 goto L1 83 | goto L2 84 | L1: T1 = print x 85 | L2_ 86 | 87 | The code expects to read from the file input.txt in the same directory. The sample code is already written there (changed a little, like ‘:=’ to ‘=’) to suit this C-style grammar. Compile with **lex 3address.l & yacc -d 3address.y & gcc 3address.tab.c**. 88 | 89 | **Note**: The *basic* idea is very simple. We force all expressions to be evaluated first and add TRUE/FAIL/NEXT statements to it as we don’t know where it will go yet, and when everything is evaluated inside the if/else or while block, we use substrings to change those true/false to new labels. 90 | 91 | **Output for input.txt:** 92 | 93 | ``` 94 | T1=y+5 95 | x=T1 96 | T3=x*2 97 | z=T3 98 | T5=x+z 99 | a=T5 100 | T7=PRINT abc 101 | T8=READ %f zxc 102 | L3 : L1 : if(awe>qwe) goto L2 103 | goto L8 104 | L2 : T9=PRINT qwe123 105 | T10=qwe+1 106 | jkl=T10 107 | T12=qwe+2 108 | qwe=T12 109 | goto L1 110 | L8 : if(awe!=qwe) goto L5 111 | goto L4 112 | L4 : T14=qwe+abc 113 | if(T14>50) goto L5 114 | goto L7 115 | L5 : if(abc==10.234000) goto L6 116 | goto L7 117 | L6 : T15=PRINT POI123QWE 118 | goto L9 119 | L7 : T16=PRINT abc 120 | T17=PRINT lkj 121 | L9 122 | ``` -------------------------------------------------------------------------------- /Parser_Library/LR0Parser.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | public class LR0Parser extends Parser 4 | { 5 | LR0Parser() 6 | { 7 | super(); 8 | } 9 | public void buildDFA() 10 | { 11 | augment(); 12 | dfa.id=getId(); 13 | for(Map.Entry>> mp: rules.entrySet()) 14 | { 15 | for(ArrayList al: mp.getValue()) 16 | { 17 | dfa.rules.add(new Pair(mp.getKey()+" -> "+join(al," "),0)); 18 | } 19 | } 20 | states.add(dfa); 21 | int i=0; 22 | boolean done=false; 23 | while(!done) 24 | { 25 | done=true; 26 | for(i=0;i Goto=getGoto(current.rules,str); 32 | int index=getIndex(Goto); 33 | if(index>=0) 34 | { 35 | current.transitions.put(str,states.get(index)); 36 | } 37 | else 38 | { 39 | DFA new_DFA=new DFA(); 40 | new_DFA.id=getId(); 41 | new_DFA.rules=Goto; 42 | states.add(new_DFA); 43 | current.transitions.put(str,new_DFA); 44 | done=false; 45 | } 46 | } 47 | } 48 | } 49 | unAugment(); 50 | minId=-1; 51 | } 52 | public boolean getParsingTable(boolean output) 53 | { 54 | terminals.add("$"); 55 | table=new ArrayList[states.size()][terminals.size()+nonTerminals.size()]; 56 | int i,j; 57 | for(i=0;i(); 60 | ArrayList colMap=new ArrayList<>(); 61 | colMap.addAll(terminals); 62 | colMap.addAll(nonTerminals); 63 | allSymbols.clear(); 64 | allSymbols.addAll(colMap); 65 | int row=0; 66 | boolean isLR0=true; 67 | for(DFA dfa:states) 68 | { 69 | for(Map.Entry mp:dfa.transitions.entrySet()) 70 | { 71 | int index=getIndex(mp.getValue().rules); 72 | if(terminals.contains(mp.getKey())) 73 | { 74 | if (states.get(index).rules.size()!=0) 75 | table[row][colMap.indexOf(mp.getKey())].add("Shift "+getIndex(mp.getValue().rules)); 76 | } 77 | else 78 | { 79 | if (states.get(index).rules.size()!=0) 80 | table[row][colMap.indexOf(mp.getKey())].add(getIndex(mp.getValue().rules)+""); 81 | } 82 | } 83 | for(Pair p:dfa.rules) 84 | { 85 | String str[]=p.rule.substring(p.rule.indexOf("->")+2).trim().split(" "); 86 | String left=p.rule.substring(0,p.rule.indexOf("->")).trim(); 87 | if(left.equals(startSymbol+"'")&&p.dot==str.length) 88 | { 89 | table[row][colMap.indexOf("$")].add("Accept :)"); 90 | } 91 | if((p.dot==str.length)||(p.dot==0&&str[0].equals("@"))) 92 | { 93 | for(i=0;i pretty[][]=new ArrayList[table.length+1][table[0].length+1]; 102 | for(i=0;i(); 107 | } 108 | } 109 | pretty[0][0].add("State"); 110 | for(i=1;i1) 123 | { 124 | int shift=0,reduce=0; 125 | for(String string:table[i-1][j-1]) 126 | { 127 | if(string.indexOf("Shift")>=0) 128 | shift++; 129 | else if(string.indexOf("Reduce")>=0) 130 | reduce++; 131 | } 132 | if ((shift>=1&&reduce>=1)||reduce>=2) 133 | isLR0=false; 134 | } 135 | pretty[i][j].addAll(table[i-1][j-1]); 136 | } 137 | } 138 | if(output) 139 | { 140 | PrettyPrinter printer = new PrettyPrinter(System.out); 141 | printer.convert(pretty); 142 | } 143 | terminals.remove("$"); 144 | if(output) 145 | { 146 | if(isLR0) 147 | System.out.println("Grammar is LR0 :)"); 148 | else 149 | System.out.println("Grammar isn't LR0 :("); 150 | } 151 | return isLR0; 152 | } 153 | } -------------------------------------------------------------------------------- /Parser_Library/SLRParser.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | public class SLRParser extends Parser 4 | { 5 | SLRParser() 6 | { 7 | super(); 8 | } 9 | public void buildDFA() 10 | { 11 | augment(); 12 | dfa.id=getId(); 13 | for(Map.Entry>> mp: rules.entrySet()) 14 | { 15 | for(ArrayList al: mp.getValue()) 16 | { 17 | dfa.rules.add(new Pair(mp.getKey()+" -> "+join(al," "),0)); 18 | } 19 | } 20 | states.add(dfa); 21 | int i=0; 22 | boolean done=false; 23 | while(!done) 24 | { 25 | done=true; 26 | for(i=0;i Goto=getGoto(current.rules,str); 32 | int index=getIndex(Goto); 33 | if(index>=0) 34 | { 35 | current.transitions.put(str,states.get(index)); 36 | } 37 | else 38 | { 39 | DFA new_DFA=new DFA(); 40 | new_DFA.id=getId(); 41 | new_DFA.rules=Goto; 42 | states.add(new_DFA); 43 | current.transitions.put(str,new_DFA); 44 | done=false; 45 | } 46 | } 47 | } 48 | } 49 | unAugment(); 50 | minId=-1; 51 | } 52 | public boolean getParsingTable(boolean output) 53 | { 54 | terminals.add("$"); 55 | table=new ArrayList[states.size()][terminals.size()+nonTerminals.size()]; 56 | int i,j; 57 | for(i=0;i(); 60 | ArrayList colMap=new ArrayList<>(); 61 | colMap.addAll(terminals); 62 | colMap.addAll(nonTerminals); 63 | allSymbols.clear(); 64 | allSymbols.addAll(colMap); 65 | int row=0; 66 | boolean isSLR=true; 67 | for(DFA dfa: states) 68 | { 69 | for(Pair p:dfa.rules) 70 | { 71 | String str[]=p.rule.substring(p.rule.indexOf("->")+2).trim().split(" "); 72 | String left=p.rule.substring(0,p.rule.indexOf("->")).trim(); 73 | if(p.dot<0||p.dot>str.length) 74 | continue; 75 | if(left.equals(startSymbol+"'")&&p.dot==str.length) 76 | { 77 | table[row][colMap.indexOf("$")].add("Accept :)"); 78 | } 79 | else if((p.dot==str.length)||(p.dot==0&&str[0].equals("@")))//Condition 2 for epsilon only 80 | { 81 | ArrayList al=utils._follow.get(left); 82 | for(String s:al) 83 | { 84 | boolean add=true; 85 | for(String sss:table[row][colMap.indexOf(s)]) 86 | { 87 | if(sss.equals("Reduce "+p.rule)) 88 | { 89 | add=false; 90 | break; 91 | } 92 | } 93 | if(add) 94 | table[row][colMap.indexOf(s)].add("Reduce "+p.rule); 95 | } 96 | } 97 | else if(terminals.contains(str[p.dot])) 98 | { 99 | HashSet hs=getGoto(dfa.rules,str[p.dot]); 100 | int index=getIndex(hs); 101 | if(index>=0) 102 | { 103 | boolean add=true; 104 | for(String sss:table[row][colMap.indexOf(str[p.dot].trim())]) 105 | { 106 | if(sss.equals("Shift "+index)) 107 | { 108 | add=false; 109 | break; 110 | } 111 | } 112 | if(add) 113 | table[row][colMap.indexOf(str[p.dot].trim())].add("Shift "+index); 114 | } 115 | } 116 | } 117 | for(String ss:nonTerminals) 118 | { 119 | HashSet hs=getGoto(dfa.rules,ss); 120 | int index=getIndex(hs); 121 | if(index>=0&&states.get(index).rules.size()!=0) 122 | { 123 | table[row][colMap.indexOf(ss)].add(index+""); 124 | } 125 | } 126 | row++; 127 | } 128 | ArrayList pretty[][]=new ArrayList[table.length+1][table[0].length+1]; 129 | for(i=0;i(); 134 | } 135 | } 136 | pretty[0][0].add("State"); 137 | for(i=1;i1) 150 | isSLR=false; 151 | pretty[i][j].addAll(table[i-1][j-1]); 152 | } 153 | } 154 | if(output) 155 | { 156 | PrettyPrinter printer = new PrettyPrinter(System.out); 157 | printer.convert(pretty); 158 | } 159 | terminals.remove("$"); 160 | if(output) 161 | { 162 | if(isSLR) 163 | System.out.println("Grammar is SLR :)"); 164 | else 165 | System.out.println("Grammar isn't SLR :("); 166 | } 167 | return isSLR; 168 | } 169 | } -------------------------------------------------------------------------------- /Lab12-AST/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Solution 3 | We start by defining an AST node. In C style, it will be: 4 | ```c 5 | typedef struct node{ 6 | int isOp; //Decides if it is an operator or not 7 | int val; //0 for addition, 1 for subtraction, 2 for multiplication and 3 for division, //however we consider it only if isOp = 1, else it holds the number 8 | struct node *left; //The left child node 9 | struct node *right; //The right child node 10 | }node; 11 | ``` 12 | The grammar is then simply: 13 | ``` 14 | Start: E -> E + T {E.val = new PlusNode(E.val, T.val) } 15 | Here, by PlusNode we refer to creating a node with isOp set to 1 (true) and type set to 0. Similarly, MinusNode, MultNode and DivNode will have isOp = 1 and type = 1, 2 and 3 respectively 16 | | E -> E – T { E.val = new MinusNode(E.val, T.val) } 17 | | T { E.val = T.val} 18 | T -> T * F {T.val = new MultNode(T.val, F.val)} 19 | | T / F {T.val = new DivNode(T.val, F.val)} 20 | | F {T.val=F.val} 21 | F -> NUMBER {F.val = new ValNode} 22 | For valnode, left and right are NULL as AST stops at numbers. Also, isOp = 0 (false) so type holds the actual value of the number 23 | | (NUMBER) {F.val = number} //That is, the actual numerical value 24 | Using this, we write a simple preorder traversal of tree as follows: 25 | ``` 26 | ## How does this work? 27 | Note, for each semantic action, we are creating an AST node with symbol as root and expressions as subtrees. With that in mind, we get: 28 | Let expression to parse = ```5 + 6 * 7``` 29 | **Parser actions**: ```Start -> E -> E + T -> E + T * F -> T + T * T -> F + F * F``` 30 | ## AST construction: 31 | We walk backwards. All the literals ‘F’ create the **ASTNode** *ValNode*, and then ```T + T * T``` gets *PlusNode* and *MultNode* respectively by their semantic actions. Also, *PlusNode* is processed earlier, followed by *MultNode* as is the order in the syntax tree. 32 | **Output**: `1+ 5 * 6 7` 33 | 34 | ## 3-Address Code 35 | The 3 address code construction is much simpler. The grammar here is: (For the old version. Go to Lab13 readme for the better version's explanation) 36 | ``` 37 | Start -> Letter ‘=’ Expression, i.e of the form a = b op c op … op z. The associated semantic action is {$$=addToTable($1, $3, ‘=’)} 38 | Now, Expression (E) is defined as: 39 | E -> E + E {$$=addToTable($1, $3, ‘+’)} 40 | | E – E {$$=addToTable($1, $3, ‘-’)} 41 | | E * E {$$=addToTable($1, $3, ‘*’)} 42 | | E / E {$$=addToTable($1, $3, ‘/’)} 43 | | ( E ) {$$=$2} 44 | |NUMBER {$$ = (char)$1;} 45 | |LETTER {(char)$1;}; *//That is, numbers and operators are returned unchanged* 46 | ``` 47 | Now, this is written in pure YACC style, but here all \$$ is referring to is the result (LHS), while \$1, \$2…\$n refers to the RHS tokens, in order. So, what is happening is the following: Since in 3-address-code we can only have 3 operators in RHS at maximum, everytime we find that, we add that subcomponent to a table (done by function addToTable()) and return their result ($$) as a new token to be processed further and to be consumed by other nodes. 48 | 49 | Let expression to parse: `a = 5+6*7` 50 | *Parser actions*: `Start -> Letter = E -> a = E -> a = E + E -> a = E + E * E -> a = NUMBER + NUMBER * NUMBER` 51 | 52 | - In step 1, we insert (‘Letter’, ‘Expression’, ‘=’) in table. 53 | - In step 2, we do E -> E + E, so table gets entry (‘E’, ’E’, ‘+’) and returned result is ‘B’ 54 | - So in step 3, we have E -> A * E, which causes entry (‘A’, ‘E’, ‘*’) to be inserted in table and returned result is ‘C’. 55 | - However, we must remember that these semantic actions can only be performed after the parsing is complete (for LR grammars), o the ‘E’ and ‘A’ are now filled with the return values after their expansion into terminal token NUMBER. So, the table actually has: 56 | ``` 57 | A = 6 * 7 58 | B = 5 + A // Since the * nodes are expanded at a later stage, they come earlier when recursion backtracking starts 59 | ``` 60 | 61 | ## DAG construction: 62 | The DAG construction is pretty simple too. The node structure is similar to ast, except an additional attribute, **id**: 63 | ```c 64 | typedef struct node{ 65 | int isOp; //Decides if it is an operator or not 66 | int val; //0 for addition, 1 for subtraction, 2 for multiplication and 3 for division, //however we consider it only if isOp = 1, else it holds the number 67 | int id; //Stores the value at this node in symbol table array 68 | struct node *left; //The left child node 69 | struct node *right; //The right child node 70 | }node; 71 | ``` 72 | 73 | What we do is as follows: When we are at a terminal (for simplicity, here terminals are single characters, `a-z`), we push that value to symbol table. Now, whenever we visit a node with an expression rule (say, `E -> E + E`), we first check if that value has already been computed or not by traversing through symbol table: if yes, we set it to that value and return, else we make a new node, push the value to symbol table and return. 74 | 75 | Let expression to parse: `a*b+c+a*b` 76 | *Parser actions*: `ArithmeticExpression -> E -> E * E -> E * E + E -> E * E + E + E -> E * E + E + E * E ... (all changed to IDs) 77 | Now, when we first get a*b, it will not be in table, but when we again go to a*b, it will be there, so we will not make the new node and just push it directly` 78 | 79 | 80 | **Note**: Compilation 81 | - lex ast.l & yacc -d ast.y & gcc ast.tab.c 82 | - lex 3address.l & yacc -d 3address.y & gcc 3address.tab.c 83 | - lex 3address(old).l & yacc -d 3address(old).y & gcc lex.yy.c 3address(old).tab.c for the older versions. *Footnote: 3address_1.y has a simpler version that prints symbols as it sees them and is probably more intuitive. To make it work, change the second line in `3address(old).l` to `# include 3address_1.tab.h"`)* 84 | - lex dag.l & yacc -d dag.y & gcc dag.tab.c 85 | 86 | Replace ast.tab.c, dag.tab.c and 3address.tab.c with y.tab.c on linux 😁 87 | 88 | **Note 2**: 89 | 90 | A brilliant astParser implementation in Python and graphviz can be found [here](https://github.com/rspivak/lsbasi/tree/master/part7/python) 91 | 92 | **Note 3:** 93 | 94 | The *DAG* code can only optimize nodes that appear in the tree order, so `a*b+c+a*b` will be optimized, but `a+b+c+a+b` will not be, as it fails to identify the common sub-expression `a+b` due to the linear tree. To handle that, the code called **transformInput.py** is given, which attempts to identify such common sub-expressions and place brackets around them, so that the linear nature is broken. 95 | 96 | *Usage Example*: 97 | - echo a+b+c+a+b | python transformInput.py | dag 98 | - echo a+b+c+a+b * (a+b) | python transformInput.py | dag 99 | 100 | Use only the first pipe to see the intermediate python output 101 | -------------------------------------------------------------------------------- /Lab4-ParsingIntroductions/Q1.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | /** 4 | * Solution for Question 1 5 | * Please use <13 non-Terminals and name them from A to L 6 | * An example input is provided in the file in1.txt 7 | * Please note that epsilon should be denoted by the "@" symbol 8 | * For the output, if it shows A->[B,Cd], that shows the production A->B|Cd 9 | * Please don't use non terminals or terminals with >1 character 10 | */ 11 | class Q1 12 | { 13 | /*Describes three possible straegies to order the keys*/ 14 | enum Strategy 15 | { 16 | KEYS_ASCENDING, 17 | KEYS_DESCENDING, 18 | KEYS_NATURAL; 19 | } 20 | public static void main(String args[])throws IOException 21 | { 22 | Q1 obj=new Q1(); 23 | obj.go(); 24 | } 25 | int a=-1; 26 | //Get the new symbol 27 | String getChar() 28 | { 29 | a++; 30 | return ((char)('M'+a))+""; 31 | } 32 | //Strategy to reorder the map keys 33 | ArrayList keyGen(ArrayList keys, Strategy strategy) 34 | { 35 | if(strategy==Strategy.KEYS_ASCENDING) 36 | { 37 | Collections.sort(keys); 38 | } 39 | else if(strategy==Strategy.KEYS_DESCENDING) 40 | { 41 | Collections.sort(keys, Collections.reverseOrder()); 42 | } 43 | return keys; 44 | } 45 | public void go()throws IOException 46 | { 47 | BufferedReader br=new BufferedReader(new FileReader("in1.txt")); 48 | String str=""; 49 | int i; 50 | HashMap> hm=new HashMap<>(); 51 | HashMap> processed=new HashMap<>(); 52 | while((str=br.readLine())!=null)//Read the string, put in map 53 | { 54 | if(str.length()>15) 55 | break; 56 | int l=str.indexOf("->"); 57 | String left=str.substring(0,l).trim(); 58 | String right=str.substring(l+2).trim(); 59 | String tokens[]=right.split("[|]"); 60 | hm.put(left,new ArrayList(Arrays.asList(tokens)));//Put all the rules in the map 61 | } 62 | ArrayList keys = new ArrayList<>(hm.keySet()); 63 | /** 64 | * Set Strategy here for iterating the map; KEYS_ASCENDING for ascending iterator, KEYS_DESCENDING for descending itertor, 65 | * KEYS_NATURAL for natural order of map; 66 | */ 67 | keyGen(keys,Strategy.KEYS_NATURAL); 68 | System.out.println("The order of processing will be: "+keys); 69 | for(int k=0;k al=hm.get(left); 73 | int l; 74 | /** 75 | * Debug 76 | */ 77 | /*System.out.println("Map: "+left+"->"+al); 78 | for(Map.Entry> mpp:processed.entrySet()) 79 | { 80 | System.out.println("Processed: "+mpp.getKey()+"->"+mpp.getValue().toString()); 81 | }*/ 82 | /** 83 | * End Debug 84 | */ 85 | //Critical step: We see productions of form Ai->AjY, and replace them as Ai->ExY|EyY|EzY, where Aj has already been processed 86 | //and gives production Aj->Ex|Ey|Ez 87 | for(i=0;i noNeed=new ArrayList<>();//Will store rules with no immediate left recursion 98 | ArrayList need=new ArrayList<>();//Will have rules with immediate left recursion 99 | for(i=0;i> so that we can 130 | //store it in the 'processed' HashMap 131 | ArrayList forHashSake=new ArrayList<>(); 132 | for(i=0;i forHashSake2=new ArrayList<>(); 146 | for(i=0;i forHashSake=new ArrayList<>(); 164 | for(i=0;i> mp:processed.entrySet()) 171 | { 172 | System.out.println(mp.getKey()+"->"+mp.getValue().toString()); 173 | } 174 | } 175 | } -------------------------------------------------------------------------------- /Parser_Library/LALRParser.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | public class LALRParser extends Parser 4 | { 5 | HashMap new_map; 6 | LALRParser() 7 | { 8 | super(); 9 | new_map=new HashMap<>(); 10 | } 11 | private String getCorePart(String x) 12 | { 13 | int l=x.indexOf(","); 14 | return x.substring(0,l).trim(); 15 | } 16 | private ArrayList> getMergerList(ArrayList states) 17 | { 18 | ArrayList> al=new ArrayList<>(); 19 | HashSet visited=new HashSet<>(); 20 | int i,j; 21 | for(i=0;i a=new ArrayList<>(); 27 | a.add(i); 28 | for(j=i+1;j already_counted=new HashSet<>(); 32 | for(Pair p:states.get(j).rules) 33 | { 34 | int index=0; 35 | String r=getCorePart(p.rule); 36 | for(Pair p2:states.get(i).rules) 37 | { 38 | String x=getCorePart(p2.rule); 39 | if(x.equals(r)&&p2.dot==p.dot&&!already_counted.contains(index)) 40 | { 41 | howMany++; 42 | already_counted.add(index); 43 | break; 44 | } 45 | index++; 46 | } 47 | } 48 | if(howMany==states.get(i).rules.size()&&howMany==states.get(j).rules.size()) 49 | { 50 | a.add(j); 51 | visited.add(j); 52 | } 53 | } 54 | al.add(a); 55 | } 56 | return al; 57 | } 58 | private int getRoot(String str) 59 | { 60 | return new_map.get(Integer.parseInt(str)); 61 | } 62 | public void buildDFA() 63 | { 64 | LR1Parser obj=new LR1Parser(); 65 | obj.rules.putAll(rules); 66 | obj.terminals.addAll(terminals); 67 | obj.nonTerminals.addAll(nonTerminals); 68 | obj.allSymbols.addAll(allSymbols); 69 | obj.utils=utils; 70 | obj.startSymbol=startSymbol; 71 | obj.buildDFA(); 72 | states.addAll(obj.states); 73 | } 74 | public boolean getParsingTable(boolean output) 75 | { 76 | LR1Parser obj=new LR1Parser(); 77 | obj.rules.putAll(rules); 78 | obj.terminals.addAll(terminals); 79 | obj.nonTerminals.addAll(nonTerminals); 80 | obj.allSymbols.addAll(allSymbols); 81 | obj.utils=utils; 82 | obj.startSymbol=startSymbol; 83 | obj.buildDFA(); 84 | obj.getParsingTable(false); 85 | ArrayList> al=getMergerList(obj.states); 86 | int i,j,k,l; 87 | for(i=0;i colMap=new ArrayList<>(); 95 | terminals.add("$"); 96 | colMap.addAll(terminals); 97 | colMap.addAll(nonTerminals); 98 | allSymbols.clear(); 99 | allSymbols.addAll(colMap); 100 | ArrayList table2[][]=new ArrayList[al.size()][terminals.size()+nonTerminals.size()]; 101 | for(i=0;i(); 104 | for(i=0;i pretty[][]=new ArrayList[table.length+1][table[0].length+1]; 165 | boolean isLALR=true; 166 | for(i=0;i(); 171 | } 172 | } 173 | pretty[0][0].add("State"); 174 | for(i=1;i1) 187 | isLALR=false; 188 | pretty[i][j].addAll(table[i-1][j-1]); 189 | } 190 | } 191 | if(output) 192 | { 193 | PrettyPrinter printer = new PrettyPrinter(System.out); 194 | printer.convert(pretty); 195 | } 196 | terminals.remove("$"); 197 | if(output) 198 | { 199 | if(isLALR) 200 | System.out.println("Grammar is LALR(1) :)"); 201 | else 202 | System.out.println("Grammar isn't LALR(1) :("); 203 | } 204 | return isLALR; 205 | } 206 | } -------------------------------------------------------------------------------- /Parser_Library/LR1Parser.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | public class LR1Parser extends Parser 4 | { 5 | LR1Parser() 6 | { 7 | super(); 8 | } 9 | public void buildDFA() 10 | { 11 | augment(); 12 | dfa.id=getId(); 13 | dfa.rules.add(new Pair(startSymbol+"' -> "+startSymbol+" , $",0)); 14 | getLR1Closure(dfa.rules); 15 | states.add(dfa); 16 | int i=0; 17 | boolean done=false; 18 | while(!done) 19 | { 20 | done=true; 21 | for(i=0;i Goto=getLR1Goto(current.rules,str); 27 | int index=getIndex(Goto); 28 | if(index>=0) 29 | { 30 | current.transitions.put(str,states.get(index)); 31 | } 32 | else 33 | { 34 | DFA new_DFA=new DFA(); 35 | new_DFA.id=getId(); 36 | new_DFA.rules=Goto; 37 | states.add(new_DFA); 38 | current.transitions.put(str,new_DFA); 39 | done=false; 40 | } 41 | } 42 | } 43 | } 44 | unAugment(); 45 | minId=-1; 46 | } 47 | public boolean getParsingTable(boolean output) 48 | { 49 | terminals.add("$"); 50 | table=new ArrayList[states.size()][terminals.size()+nonTerminals.size()]; 51 | int i,j; 52 | for(i=0;i(); 55 | ArrayList colMap=new ArrayList<>(); 56 | colMap.addAll(terminals); 57 | colMap.addAll(nonTerminals); 58 | allSymbols.clear(); 59 | allSymbols.addAll(colMap); 60 | int row=0; 61 | boolean isLR1=true; 62 | for(DFA dfa: states) 63 | { 64 | for(Pair p:dfa.rules) 65 | { 66 | int l=p.rule.indexOf("->"); 67 | int l2=p.rule.indexOf(","); 68 | String left=p.rule.substring(0,l).trim(); 69 | String mid=p.rule.substring(l+2,l2).trim(); 70 | String right=p.rule.substring(l2+2).trim(); 71 | String str[]=mid.split(" "); 72 | if(p.dot<0||p.dot>str.length) 73 | continue; 74 | if(left.equals(startSymbol+"'")&&p.dot==str.length) 75 | { 76 | table[row][colMap.indexOf("$")].add("Accept :)"); 77 | } 78 | else if((p.dot==str.length)||(p.dot==0&&str[0].equals("@")))//Condition 2 for epsilon only 79 | { 80 | String G[]=right.split("[|]"); 81 | for(String g:G) 82 | table[row][colMap.indexOf(g.trim())].add("Reduce "+left+" -> "+mid); 83 | } 84 | else if(terminals.contains(str[p.dot])) 85 | { 86 | HashSet hs=getLR1Goto(dfa.rules,str[p.dot]); 87 | int index=getIndex(hs); 88 | if(index>=0) 89 | { 90 | boolean add=true; 91 | for(String s: table[row][colMap.indexOf(str[p.dot].trim())]) 92 | { 93 | if(s.equals("Shift "+index)) 94 | add=false; 95 | } 96 | if(add) 97 | table[row][colMap.indexOf(str[p.dot].trim())].add("Shift "+index); 98 | } 99 | } 100 | } 101 | for(String ss:nonTerminals) 102 | { 103 | HashSet hs=getLR1Goto(dfa.rules,ss); 104 | int index=getIndex(hs); 105 | if(index>=0&&states.get(index).rules.size()!=0) 106 | { 107 | table[row][colMap.indexOf(ss)].add(index+""); 108 | } 109 | } 110 | row++; 111 | } 112 | ArrayList pretty[][]=new ArrayList[table.length+1][table[0].length+1]; 113 | for(i=0;i(); 118 | } 119 | } 120 | pretty[0][0].add("State"); 121 | for(i=1;i1) 134 | isLR1=false; 135 | pretty[i][j].addAll(table[i-1][j-1]); 136 | } 137 | } 138 | if(output) 139 | { 140 | PrettyPrinter printer = new PrettyPrinter(System.out); 141 | printer.convert(pretty); 142 | } 143 | terminals.remove("$"); 144 | if(output) 145 | { 146 | if(isLR1) 147 | System.out.println("Grammar is LR(1) :)"); 148 | else 149 | System.out.println("Grammar isn't LR(1) :("); 150 | } 151 | return isLR1; 152 | } 153 | private void getLR1Closure(HashSet closure) 154 | { 155 | boolean done=false; 156 | while(!done) 157 | { 158 | done=true; 159 | Iterator iterator=closure.iterator(); 160 | HashSet addAble=new HashSet<>(); 161 | while(iterator.hasNext()) 162 | { 163 | Pair pair=(Pair)iterator.next(); 164 | int l=pair.rule.indexOf("->"),i; 165 | int l2=pair.rule.indexOf(","); 166 | String left=pair.rule.substring(0,l).trim(); 167 | String mid=pair.rule.substring(l+2,l2).trim(); 168 | String right=pair.rule.substring(l2+2).trim(); 169 | String tokens[]=mid.split(" "); 170 | String newRight=""; 171 | if(pair.dot>=tokens.length-1) 172 | { 173 | newRight=right; 174 | } 175 | else 176 | { 177 | if(terminals.contains(tokens[pair.dot+1])) 178 | newRight=tokens[pair.dot+1]; 179 | else 180 | newRight=join(utils._first.get(tokens[pair.dot+1])," | "); 181 | } 182 | if(pair.dot>=tokens.length||pair.dot<0) 183 | continue; 184 | else if(nonTerminals.contains(tokens[pair.dot])) 185 | { 186 | ArrayList> al=rules.get(tokens[pair.dot]); 187 | for(i=0;i "+str.trim()+" , "+newRight,0); 191 | if(!closure.contains(p)) 192 | { 193 | done=false; 194 | addAble.add(p); 195 | } 196 | } 197 | } 198 | } 199 | closure.addAll(addAble); 200 | } 201 | } 202 | private HashSet getLR1Goto(HashSet X, String I) 203 | { 204 | HashSet goTo=new HashSet<>(); 205 | HashSet add=new HashSet<>(); 206 | for(Pair p: X) 207 | { 208 | String str[]=p.rule.substring(p.rule.indexOf("->")+2).trim().split(" "); 209 | if(p.dot>=str.length||p.dot<0) 210 | continue; 211 | if(str[p.dot].equals(I)) 212 | goTo.add(new Pair(p.rule,p.dot+1)); 213 | } 214 | for(Pair p:goTo) 215 | { 216 | HashSet temp=new HashSet<>(); 217 | temp.add(p); 218 | getLR1Closure(temp); 219 | add.addAll(temp); 220 | } 221 | goTo.addAll(add); 222 | return goTo; 223 | } 224 | } -------------------------------------------------------------------------------- /Lab4-ParsingIntroductions/Q3.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | class Q3 4 | { 5 | /** 6 | * The grammar is already there in in3.txt 7 | * The map shows the changed representations. 8 | * Map: E'->A 9 | * epsilon->@ 10 | * id->i 11 | * T'->C 12 | * Solution for Question 3. For new grammar, please don't use terminals with >1 character and Terminals should be in Uppercase 13 | * For the output, if it shows A->[B,Cd], that shows the production A->B|Cd 14 | * The recursive-descent algorithm is implemented in the method call dfs() 15 | * Also implemented BFS version to check relative performance 16 | * There method valid() is overridden; the HashSets can be removed from method call to use them and it is necessary for cyclic grammars 17 | * where we can't find if a character can lead to epsilon production or not 18 | */ 19 | public static void main(String args[])throws IOException 20 | { 21 | Q3 obj=new Q3(); 22 | obj.go(); 23 | } 24 | long t1,t2; 25 | boolean containsBad(String str) 26 | { 27 | int i,l=str.length(); 28 | for(i=0;i> rules=new HashMap<>(); 42 | int line=0; 43 | Queue q=new LinkedList<>(); 44 | ArrayList dfsSources=new ArrayList<>(); 45 | HashSet epsilonAble=new HashSet<>(); 46 | HashSet notEpsilonAble=new HashSet<>(); 47 | while((str=br1.readLine())!=null) 48 | { 49 | if(str.length()>15) 50 | break; 51 | l=str.indexOf("->"); 52 | String left=str.substring(0,l).trim(); 53 | String right=str.substring(l+2).trim(); 54 | String token[]=right.split("[|]"); 55 | ArrayList al=new ArrayList<>(); 56 | for(i=0;i keys = new ArrayList<>(rules.keySet()); 69 | /** 70 | * Find out if symbol is epsilonable, that is if it can lead to epsilon or not. 71 | * Rule 1: If it has an epsilon production, it is epsilonable 72 | * Rule 2: If it has a production with all non-terminals and they are epsilonable, it is epsilonable 73 | * If the above two doesn't hold, symbol is not epsilonable 74 | */ 75 | for(int k=0;k al=rules.get(left); 81 | boolean done=false; 82 | int count=0,epsCount=0; 83 | for(String s:al) 84 | { 85 | if(s.equals("@"))//Rule 1 86 | { 87 | epsilonAble.add(left); 88 | done=true; 89 | break; 90 | } 91 | else if(containsBad(s))//This has a terminal, so rule 2 can't hold 92 | { 93 | count++; 94 | continue; 95 | } 96 | else//This rule has all nonterminals 97 | { 98 | for(int r=0;rBC and we don't yet know if B is epsilonble or not, so save the task for later 124 | keys.add(left); 125 | } 126 | str=br.readLine(); 127 | t1=System.nanoTime(); 128 | bfs(q,str,rules,epsilonAble,notEpsilonAble); 129 | //Call dfs from all start productions. If it succeeds, System.exit() prevents other calls. 130 | for(String s:dfsSources) 131 | { 132 | t1=System.nanoTime(); 133 | dfs(str,s,rules,new HashSet(),epsilonAble,notEpsilonAble); 134 | } 135 | t2=System.nanoTime(); 136 | System.out.println("Failed. DFS took: "+(((t2-t1)*(1.0))/1000)+" microsecends"); 137 | System.out.println("Not accepted :("); 138 | } 139 | boolean nonTerminal(int ch) 140 | { 141 | return ch>=65&&ch<=90; 142 | } 143 | //Naive version 144 | boolean valid(String str, String target) 145 | { 146 | int count=0,i,l=str.length(),l1=target.length(),j; 147 | for(i=0;i e,HashSet nE) 156 | { 157 | int count=0,i,l=str.length(),l1=target.length(),j; 158 | for(i=0;i> rules, HashSet visited,HashSet e,HashSet nE) 166 | { 167 | int i,l; 168 | if(formed.equals(target)) 169 | { 170 | t2=System.nanoTime(); 171 | System.out.println("Succesful. DFS took: "+(((t2-t1)*(1.0))/1000)+" microsecends"); 172 | System.out.println("Accepted"); 173 | System.exit(0); 174 | } 175 | visited.add(formed); 176 | l=formed.length(); 177 | for(i=0;i al=rules.get(ch+""); 183 | for(String s:al) 184 | { 185 | if(s.equals("@")) 186 | s=""; 187 | String possible=formed.substring(0,i)+s+formed.substring(i+1); 188 | if(valid(possible,target,e,nE)&&!visited.contains(possible)) 189 | { 190 | visited.add(possible); 191 | dfs(target,possible,rules,visited,e,nE); 192 | } 193 | } 194 | } 195 | } 196 | } 197 | void bfs(Queue q,String target, HashMap> rules,HashSet e,HashSet nE) 198 | { 199 | int i,l; 200 | HashSet visited=new HashSet<>(); 201 | while(!q.isEmpty()) 202 | { 203 | String str=q.poll(); 204 | visited.add(str); 205 | if(str.equals(target)) 206 | { 207 | t2=System.nanoTime(); 208 | System.out.println("BFS took: "+(((t2-t1)*(1.0))/1000)+" microsecends"); 209 | System.out.println("Accepted"); 210 | return; 211 | } 212 | l=str.length(); 213 | for(i=0;i al=rules.get(ch+""); 219 | for(String s:al) 220 | { 221 | if(s.equals("@")) 222 | s=""; 223 | String possible=str.substring(0,i)+s+str.substring(i+1); 224 | if(valid(possible,target,e,nE)&&!visited.contains(possible)) 225 | { 226 | //System.out.println("Will explore: "+str+"--->"+target+", on applying rule: "+ch+"->"+((s.length()==0)?"@":s)); 227 | q.add(possible); 228 | visited.add(possible); 229 | } 230 | } 231 | } 232 | } 233 | } 234 | t2=System.nanoTime(); 235 | System.out.println("BFS took: "+(((t2-t1)*(1.0))/1000)+" microsecends"); 236 | System.out.println("Not accepted :("); 237 | } 238 | } -------------------------------------------------------------------------------- /Parser_Library/Parser.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | public class Parser 4 | { 5 | HashMap>> rules; 6 | HashSet terminals; 7 | HashSet nonTerminals; 8 | ArrayList allSymbols; 9 | ArrayList table[][]; 10 | String startSymbol; 11 | AugmentedFirstAndFollow utils; 12 | ArrayList states; 13 | DFA dfa; 14 | int minId; 15 | static class Pair 16 | { 17 | String rule; 18 | int dot; 19 | Pair(String c,int d) 20 | { 21 | rule=c; 22 | dot=d; 23 | } 24 | @Override 25 | public String toString() 26 | { 27 | int l=rule.indexOf("->"),i; 28 | String left=rule.substring(0,l).trim(); 29 | String right=rule.substring(l+2).trim(); 30 | StringBuilder sb=new StringBuilder(); 31 | sb.append(left+" -> "); 32 | String tokens[]=right.split(" "); 33 | for(i=0;i rules; 75 | int id; 76 | HashMap transitions; 77 | DFA() 78 | { 79 | rules=new HashSet<>(); 80 | id=-1; 81 | transitions=new HashMap<>(); 82 | } 83 | @Override 84 | public String toString() 85 | { 86 | return "Id: "+id+" , Rules: "+rules+"\n";//Mapping: "+transitions+"\n\n"; 87 | } 88 | } 89 | Parser() 90 | { 91 | rules=new HashMap<>(); 92 | startSymbol=""; 93 | terminals=new HashSet<>(); 94 | nonTerminals=new HashSet<>(); 95 | allSymbols=new ArrayList<>(); 96 | minId=-1; 97 | dfa=new DFA(); 98 | utils=new AugmentedFirstAndFollow(); 99 | states=new ArrayList<>(); 100 | } 101 | protected int getId() 102 | { 103 | return ++minId; 104 | } 105 | void modify(AugmentedFirstAndFollow utils) 106 | { 107 | utils.ntCount.clear(); 108 | utils.ntCount.addAll(nonTerminals); 109 | utils.tCount.clear(); 110 | utils.tCount.addAll(terminals); 111 | utils.tCount.add("$"); 112 | utils.ntCount.add(startSymbol+"'"); 113 | } 114 | public void read_grammar(String filePath) 115 | { 116 | String str=""; 117 | int line=0; 118 | try 119 | { 120 | BufferedReader br=new BufferedReader(new FileReader(filePath)); 121 | str=br.readLine(); 122 | String _terminals[]=str.split(" "); 123 | for(int i=0;i<_terminals.length;i++) 124 | terminals.add(_terminals[i]); 125 | str=br.readLine(); 126 | String _nonTerminals[]=str.split(" "); 127 | for(int i=0;i<_nonTerminals.length;i++) 128 | nonTerminals.add(_nonTerminals[i]); 129 | allSymbols.addAll(terminals); 130 | allSymbols.addAll(nonTerminals); 131 | while((str=br.readLine())!=null)//Read the string, put in map 132 | { 133 | int l=str.indexOf("->"),i,j; 134 | String left=str.substring(0,l).trim(); 135 | String right=str.substring(l+2).trim(); 136 | l=right.length(); 137 | String tokens[]=right.split("[|]"); 138 | if(line==0) 139 | { 140 | startSymbol=left; 141 | } 142 | line++; 143 | ArrayList> al=new ArrayList<>(); 144 | for(i=0;i temp=new ArrayList<>(); 148 | for(j=0;j v, String delim) 167 | { 168 | if(v==null||v.size()==0) 169 | return ""; 170 | StringBuilder ss=new StringBuilder(); 171 | for(int i = 0; i < v.size(); ++i) 172 | { 173 | if(i != 0) 174 | ss.append(delim); 175 | ss.append(v.get(i)); 176 | } 177 | return ss.toString(); 178 | } 179 | public void getClosure(HashSet closure) 180 | { 181 | boolean done=false; 182 | while(!done) 183 | { 184 | done=true; 185 | Iterator iterator=closure.iterator(); 186 | HashSet addAble=new HashSet<>(); 187 | while(iterator.hasNext()) 188 | { 189 | Pair pair=(Pair)iterator.next(); 190 | int l=pair.rule.indexOf("->"),i; 191 | String left=pair.rule.substring(0,l).trim(); 192 | String right=pair.rule.substring(l+2).trim(); 193 | String tokens[]=right.split(" "); 194 | if(pair.dot>=tokens.length||pair.dot<0) 195 | continue; 196 | else if(nonTerminals.contains(tokens[pair.dot])) 197 | { 198 | ArrayList> al=rules.get(tokens[pair.dot]); 199 | for(i=0;i "+str,0); 203 | if(!closure.contains(p)) 204 | { 205 | done=false; 206 | addAble.add(new Pair(tokens[pair.dot]+" -> "+str.trim(),0)); 207 | } 208 | } 209 | } 210 | } 211 | closure.addAll(addAble); 212 | } 213 | } 214 | public HashSet getGoto(HashSet X, String I) 215 | { 216 | HashSet goTo=new HashSet<>(); 217 | HashSet add=new HashSet<>(); 218 | for(Pair p: X) 219 | { 220 | String str[]=p.rule.substring(p.rule.indexOf("->")+2).trim().split(" "); 221 | if(p.dot>=str.length||p.dot<0) 222 | continue; 223 | if(str[p.dot].equals(I)) 224 | goTo.add(new Pair(p.rule,p.dot+1)); 225 | } 226 | for(Pair p:goTo) 227 | { 228 | HashSet temp=new HashSet<>(); 229 | temp.add(p); 230 | getClosure(temp); 231 | add.addAll(temp); 232 | } 233 | goTo.addAll(add); 234 | return goTo; 235 | } 236 | public void augment() 237 | { 238 | ArrayList> al=new ArrayList<>(); 239 | ArrayList al2=new ArrayList<>(); 240 | al2.add(startSymbol); 241 | al.add(al2); 242 | rules.put(startSymbol+"'",al); 243 | } 244 | public void unAugment() 245 | { 246 | rules.remove(startSymbol+"'"); 247 | } 248 | public boolean parse(String _toParse, boolean output) 249 | { 250 | _toParse=_toParse+" $"; 251 | Stack stack=new Stack<>(); 252 | ArrayList> al=new ArrayList<>(); 253 | ArrayList a=new ArrayList<>(); 254 | a.add("Step"); 255 | a.add("Stack"); 256 | a.add("Action"); 257 | a.add("Input"); 258 | al.add(a); 259 | stack.push("$"); 260 | stack.push("0"); 261 | int pointer=0,i,step=0; 262 | String toParse[]=_toParse.split(" "); 263 | while(!stack.empty()&&pointer(); 266 | int row=Integer.parseInt(stack.peek()); 267 | int col=allSymbols.indexOf(toParse[pointer]); 268 | a.add(step+""); 269 | a.add(stack+""); 270 | if(col<0) 271 | { 272 | a.add("Parse error"); 273 | al.add(a); 274 | if(output) 275 | pretty_it(al); 276 | break; 277 | } 278 | if(table[row][col].size()==0) 279 | { 280 | a.add("Parse error"); 281 | al.add(a); 282 | if(output) 283 | pretty_it(al); 284 | break; 285 | } 286 | String action=table[row][col].get(0); 287 | a.add(action); 288 | String str[]=action.split(" "); 289 | String left=str[0].trim(); 290 | String right=""; 291 | for(i=1;i")).trim(); 303 | right=right.substring(right.indexOf("->")+2).trim(); 304 | if(right.charAt(0)!='@') 305 | { 306 | for(i=0;i<2*(str.length-3);i++) 307 | { 308 | if(stack.size()!=0) 309 | stack.pop(); 310 | else 311 | { 312 | a.add("Parse error"); 313 | al.add(a); 314 | if(output) 315 | pretty_it(al); 316 | return false; 317 | } 318 | } 319 | } 320 | int top=Integer.parseInt(stack.peek()); 321 | stack.push(left); 322 | stack.push(table[top][allSymbols.indexOf(left)].get(0)); 323 | } 324 | else if(left.equals("Accept")&&pointer==toParse.length-1) 325 | { 326 | String ppp=""; 327 | for(i=pointer;i> al) 348 | { 349 | int n=al.size(),i,j; 350 | String t[][]=new String[n][4]; 351 | for(i=0;i Goto) 365 | { 366 | int i=0; 367 | for(DFA dfa: states) 368 | { 369 | if((dfa.rules.containsAll(Goto)&&Goto.containsAll(dfa.rules))) 370 | return i; 371 | i++; 372 | } 373 | return -1; 374 | } 375 | protected void print_transitions() 376 | { 377 | for(DFA dfa: states) 378 | { 379 | System.out.println("Map for state: "+dfa); 380 | System.out.println("Transitions: "); 381 | for(Map.Entry mp:dfa.transitions.entrySet()) 382 | { 383 | System.out.println(mp.getKey()+"->"+mp.getValue().rules+" ( S"+getIndex(mp.getValue().rules)+" )"); 384 | } 385 | System.out.println(); 386 | } 387 | } 388 | } -------------------------------------------------------------------------------- /Parser_Library/AugmentedFirstAndFollow.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | public class AugmentedFirstAndFollow 4 | { 5 | String fLine; 6 | ArrayList ntMap; 7 | ArrayList tMap; 8 | HashSet ntCount; 9 | HashSet tCount; 10 | HashMap> _first; 11 | HashMap> _follow; 12 | AugmentedFirstAndFollow() 13 | { 14 | fLine=""; 15 | ntMap=new ArrayList<>(); 16 | tMap=new ArrayList<>(); 17 | ntCount=new HashSet<>(); 18 | tCount=new HashSet<>(); 19 | _first=new HashMap<>(); 20 | _follow=new HashMap<>(); 21 | } 22 | String join(ArrayList v, String delim) 23 | { 24 | StringBuilder ss=new StringBuilder(); 25 | for(int i = 0; i < v.size(); ++i) 26 | { 27 | if(i != 0) 28 | ss.append(delim); 29 | ss.append(v.get(i)); 30 | } 31 | return ss.toString(); 32 | } 33 | String getChar(String s) 34 | { 35 | return s+"'"; 36 | } 37 | public void module2(ArrayList arr[][],String expr) 38 | { 39 | String tokens[]=expr.split(" "); 40 | Stack stack=new Stack<>(); 41 | stack.push("$"); 42 | stack.push(fLine); 43 | int i,j,l; 44 | for(i=0;i")+2).trim(); 60 | String s[]=str.split(" "); 61 | l=s.length; 62 | for(j=l-1;j>=0;j--) 63 | { 64 | if(s[j].equals("@")) 65 | continue; 66 | stack.push(s[j]); 67 | } 68 | } 69 | else 70 | { 71 | if(ch.equals(top)) 72 | { 73 | i++; 74 | stack.pop(); 75 | } 76 | else 77 | { 78 | System.out.println("Can't be derived :("); 79 | break; 80 | } 81 | } 82 | } 83 | if(stack.empty()&&i==tokens.length) 84 | System.out.println("Can be derived :) "); 85 | } 86 | public ArrayList[][] module1(String filename, boolean augment,boolean output)throws IOException 87 | { 88 | BufferedReader br=new BufferedReader(new FileReader(filename)); 89 | String str=""; 90 | int i,line=0,j; 91 | HashMap>> hm=new HashMap<>(); 92 | HashMap> first=new HashMap<>(); 93 | HashMap> follow=new HashMap<>(); 94 | str=br.readLine(); 95 | String _terminals[]=str.split(" "); 96 | for(i=0;i<_terminals.length;i++) 97 | tCount.add(_terminals[i]); 98 | str=br.readLine(); 99 | String _nonTerminals[]=str.split(" "); 100 | for(i=0;i<_nonTerminals.length;i++) 101 | ntCount.add(_nonTerminals[i]); 102 | while((str=br.readLine())!=null) 103 | { 104 | int l=str.indexOf("->"); 105 | String left=str.substring(0,l).trim(); 106 | String right=str.substring(l+2).trim(); 107 | l=right.length(); 108 | String tokens[]=right.split("[|]"); 109 | if(line==0) 110 | { 111 | fLine=left; 112 | } 113 | line++; 114 | ArrayList> al=new ArrayList<>(); 115 | for(i=0;i temp=new ArrayList<>(); 119 | for(j=0;j> al=new ArrayList<>(); 128 | ArrayList al2=new ArrayList<>(); 129 | al2.add(fLine); 130 | al.add(al2); 131 | hm.put(fLine+"'",al); 132 | } 133 | if(output) 134 | System.out.println(hm); 135 | br.close(); 136 | try 137 | { 138 | if(output) 139 | System.out.println("The first set: "); 140 | calculateFirst(hm,first,output); 141 | if(output) 142 | System.out.println("The follow set:"); 143 | calculateFollow(hm,first,follow,output,augment); 144 | if(output) 145 | System.out.println("Table: "); 146 | _first.putAll(first); 147 | _follow.putAll(follow); 148 | return null; 149 | //return getMatrix(tCount,ntCount,first,follow,hm); 150 | }catch(Exception e) 151 | { 152 | System.out.println("Not a well defined grammar. Please check for infinite productions/left recursion,etc."); 153 | } 154 | System.out.println(fLine); 155 | return null; 156 | } 157 | ArrayList[][] getMatrix(HashSet tCount, HashSet ntCount,HashMap> first, HashMap> follow, 158 | HashMap>> hm) 159 | { 160 | ArrayList arr[][]=new ArrayList[ntCount.size()][tCount.size()]; 161 | ntMap.addAll(ntCount); 162 | tMap.addAll(tCount); 163 | System.out.println(ntMap); 164 | System.out.println(tMap); 165 | int i,j; 166 | for(i=0;i(); 171 | } 172 | } 173 | for(Map.Entry>> mp:hm.entrySet()) 174 | { 175 | String terminal=mp.getKey(); 176 | ArrayList> rules=mp.getValue(); 177 | System.out.println("Considering: "+terminal+"->"+rules); 178 | for(ArrayList rule:rules) 179 | { 180 | String ss=rule.get(0); 181 | if(ntCount.contains(ss)) 182 | { 183 | ArrayList al=first.get(ss); 184 | for(String str:al) 185 | { 186 | ss=str.trim(); 187 | int row=ntMap.indexOf(terminal); 188 | int col=tMap.indexOf(ss); 189 | System.out.println(row+","+col+","+terminal+"->"+rule); 190 | if(arr[row][col].size()==0) 191 | arr[row][col].add(terminal+" -> "+join(rule," ")); 192 | } 193 | } 194 | else if(!ss.equals("@")) 195 | { 196 | int row=ntMap.indexOf(terminal); 197 | int col=tMap.indexOf(ss); 198 | arr[row][col].add(terminal+" -> "+join(rule," ")); 199 | } 200 | } 201 | if(first.get(terminal).contains("@")) 202 | { 203 | for(String str:follow.get(terminal)) 204 | { 205 | int row=ntMap.indexOf(terminal); 206 | int col=tMap.indexOf(str); 207 | arr[row][col].add(terminal+" -> @ "); 208 | } 209 | } 210 | } 211 | boolean flag=false; 212 | for(i=0;i1) 217 | { 218 | if(arr[i][j].size()==2&&((arr[i][j].get(0).indexOf("@")>0)||(arr[i][j].get(1).indexOf("@")>0))) 219 | continue; 220 | flag=true; 221 | } 222 | } 223 | } 224 | ArrayList pretty[][]=new ArrayList[ntCount.size()+1][tCount.size()+1]; 225 | for(i=0;i(); 230 | } 231 | } 232 | pretty[0][0].add("(0,0)"); 233 | for(i=1;i>> hm, HashMap> first,boolean output) 261 | { 262 | for(Map.Entry>> mp:hm.entrySet()) 263 | { 264 | String terminal=mp.getKey(); 265 | ArrayList> rules=mp.getValue(); 266 | if(first.get(terminal)!=null)//Already done 267 | { 268 | if(output) 269 | System.out.println(terminal+"->"+unique(first.get(terminal))); 270 | continue; 271 | } 272 | calculateFirstUtil(hm,first,terminal,rules); 273 | if(output) 274 | System.out.println(terminal+"->"+unique(calculateFirstUtil(hm,first,terminal,rules))); 275 | } 276 | } 277 | ArrayList calculateFirstUtil(HashMap>> hm, HashMap> first, 278 | String terminal, ArrayList> rules) 279 | { 280 | if(first.get(terminal)!=null) 281 | return first.get(terminal); 282 | for(ArrayList rule:rules) 283 | { 284 | int i,l=rule.size(); 285 | for(i=0;i a=first.get(terminal); 289 | if(a==null) 290 | { 291 | a=new ArrayList<>(); 292 | first.put(terminal,a);//no NPE 293 | a=first.get(terminal); 294 | } 295 | if(!ntCount.contains(ss)) 296 | { 297 | a.add(ss); 298 | first.put(terminal,a); 299 | break; 300 | } 301 | else 302 | { 303 | if(ss.equals(terminal))//for left-recursive grammars 304 | break; 305 | ArrayList temp=calculateFirstUtil(hm,first,ss,hm.get(ss)); 306 | a.addAll(temp); 307 | first.put(terminal,a); 308 | if(!temp.contains("@")) 309 | break; 310 | } 311 | } 312 | } 313 | return first.get(terminal); 314 | } 315 | ArrayList uniqueAndEpsilonLess(ArrayList al) 316 | { 317 | HashSet hs=new HashSet<>(); 318 | hs.addAll(al); 319 | hs.remove("@"); 320 | al.clear(); 321 | al.addAll(hs); 322 | return al; 323 | } 324 | ArrayList unique(ArrayList al) 325 | { 326 | HashSet hs=new HashSet<>(); 327 | hs.addAll(al); 328 | al.clear(); 329 | al.addAll(hs); 330 | return al; 331 | } 332 | void calculateFollow(HashMap>> hm, HashMap> first, HashMap> follow 333 | ,boolean output,boolean augment) 334 | { 335 | for(Map.Entry>> mp:hm.entrySet()) 336 | { 337 | String terminal=mp.getKey(); 338 | ArrayList> rules=mp.getValue(); 339 | if(follow.get(terminal)!=null)//Already done 340 | { 341 | if(output) 342 | System.out.println(terminal+"->"+uniqueAndEpsilonLess(follow.get(terminal))); 343 | continue; 344 | } 345 | calculateFollowUtil(hm,first,follow,terminal,augment); 346 | if(output) 347 | System.out.println(terminal+"->"+uniqueAndEpsilonLess(calculateFollowUtil(hm,first,follow,terminal,augment))); 348 | } 349 | } 350 | ArrayList calculateFollowUtil(HashMap>> hm, HashMap> first, 351 | HashMap> follow, String terminal,boolean augment) 352 | { 353 | if(follow.get(terminal)!=null) 354 | return follow.get(terminal); 355 | for(Map.Entry>> mp:hm.entrySet()) 356 | { 357 | ArrayList> rules=mp.getValue(); 358 | for(ArrayList rule:rules) 359 | { 360 | int i,l=rule.size(); 361 | if(rule.contains("@")&&l==1) 362 | continue; 363 | for(i=0;i a=follow.get(terminal); 367 | if(a==null) 368 | a=new ArrayList<>(); 369 | follow.put(terminal,a);//No NPE 370 | if((fLine).equals(terminal)&&!a.contains("$")&&!augment) 371 | { 372 | a.add("$"); 373 | follow.put(terminal,a); 374 | a=follow.get(terminal); 375 | } 376 | if((fLine+"'").equals(terminal)&&!a.contains("$")&&augment) 377 | { 378 | a.add("$"); 379 | follow.put(terminal,a); 380 | a=follow.get(terminal); 381 | } 382 | if(terminal.equals(ss)&&i!=l-1) 383 | { 384 | i++; 385 | ss=rule.get(i).trim(); 386 | if(!ntCount.contains(ss)) 387 | { 388 | if(!ss.equals("@")) 389 | { 390 | a.add(ss); 391 | follow.put(terminal,a); 392 | } 393 | } 394 | else 395 | { 396 | a.addAll(first.get(ss)); 397 | while(first.get(ss).contains("@")&&i+1 temp=calculateFollowUtil(hm,first,follow,mp.getKey(),augment); 406 | a.addAll(temp); 407 | } 408 | follow.put(terminal,a); 409 | } 410 | } 411 | else if(terminal.equals(ss)&&i==l-1&&!mp.getKey().equals(terminal)) 412 | { 413 | ArrayList temp=calculateFollowUtil(hm,first,follow,mp.getKey(),augment); 414 | a.addAll(temp); 415 | follow.put(terminal,a); 416 | } 417 | } 418 | } 419 | } 420 | return follow.get(terminal); 421 | } 422 | } --------------------------------------------------------------------------------