├── hw1-NFA2DFA ├── README.md ├── DFAresult.txt ├── NFA2DFA.exe ├── runDFA.exe ├── DFA.txt ├── DFAjudge.txt ├── NFA.txt ├── runDFA.cpp ├── NFA2DFA.cpp └── RegexToNFA[simple][v3].cpp ├── hw2-CFG-FirstSet ├── README.md ├── input.txt ├── output.txt └── CFG_FirstSet.cpp ├── yacc-ACMProblem ├── UVa11291 │ ├── testdata │ │ ├── ac_output~ │ │ ├── ac_output │ │ └── input │ ├── input~ │ ├── a.out │ ├── a.tab.o │ ├── lex.yy.o │ ├── make.sh~ │ ├── make.sh │ ├── uva11291.l~ │ ├── a.l~ │ ├── a.l │ ├── uva11291.y~ │ ├── a.y │ ├── a.y~ │ └── a.tab.h └── README.md ├── Advanced ├── LLVM │ ├── Simple-DCE-pass │ │ ├── Hello │ │ │ ├── Hello.exports │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakeLists.txt-backup │ │ │ ├── Hello.cpp │ │ │ └── Makefile │ │ ├── MyDCE │ │ │ ├── CMakeLists.txt │ │ │ ├── MyDCE.h │ │ │ ├── MyDCE.cpp │ │ │ └── Makefile │ │ ├── R04922067-Report.docx │ │ ├── test │ │ │ ├── case1.c │ │ │ ├── clean.sh │ │ │ ├── case4.c │ │ │ ├── case2.c │ │ │ ├── case3.c │ │ │ └── test.sh │ │ ├── CMakeLists.txt │ │ └── README.md │ ├── GlobalRegisterAllocation │ │ ├── README.md │ │ ├── test │ │ │ ├── clear.sh │ │ │ ├── call-lib.c │ │ │ ├── case1.c │ │ │ └── test.sh │ │ ├── patch │ │ │ ├── README.md │ │ │ └── patch │ │ ├── source │ │ │ ├── lib │ │ │ │ ├── Transforms │ │ │ │ │ ├── TestPass │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ └── TestPass.cpp │ │ │ │ │ └── CMakeLists.txt │ │ │ │ └── Target │ │ │ │ │ └── X86 │ │ │ │ │ ├── X86TestPassLoader.cpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── X86.h │ │ │ │ │ └── X86TargetMachine.cpp │ │ │ └── X86RenameRegister.cpp │ │ ├── R04922067-Report.docx │ │ ├── R04922067-Report.pdf │ │ └── install.sh │ └── Simple-CSE-pass │ │ ├── MyCSE │ │ ├── CMakeLists.txt │ │ ├── MyCSE.h │ │ ├── Makefile │ │ └── MyCSE.cpp │ │ ├── R04922067-Report.docx │ │ ├── test │ │ ├── case2.c │ │ ├── case1.c │ │ ├── case3.c │ │ ├── clean.sh │ │ ├── case5.c │ │ ├── test.sh │ │ └── case4.c │ │ └── CMakeLists.txt └── Dataflow │ ├── Liveness │ ├── .gitignore │ ├── Makefile │ ├── images │ │ └── example.png │ ├── sample.in │ ├── README.md │ └── Liveness.cpp │ ├── AvailableExpr │ ├── .gitignore │ ├── Makefile │ ├── sample.in │ ├── sample2.in │ ├── sample2.out │ ├── sample.out │ ├── README.md │ └── AvailableExpr.cpp │ └── ReachingDefinition │ ├── .gitignore │ ├── Makefile │ ├── images │ └── example.png │ ├── sample.in │ ├── README.md │ └── ReachingDefinition.cpp ├── bonus1_100502205_v1 ├── output.txt ├── input.txt └── CFG_FollowSet.cpp ├── bonus2_100502205_v1 ├── input.txt ├── output.txt └── CFG_CFSM.cpp ├── SLR(1)-ACMProblem └── UVa171 │ └── 171 - Car Trialling.cpp ├── hw3-CFG-PredicSet ├── output.txt ├── input.txt └── CFG_PredicSet.cpp ├── README.md ├── LL(1)-ACMProblem ├── README.md └── UVa134 │ └── 134 - Loglan-A Logical Language.cpp └── hwA-CFG-LR(0) └── CFG_LR.cpp /hw1-NFA2DFA/README.md: -------------------------------------------------------------------------------- 1 | # 使用注意事項 -------------------------------------------------------------------------------- /hw1-NFA2DFA/DFAresult.txt: -------------------------------------------------------------------------------- 1 | error 2 | -------------------------------------------------------------------------------- /hw2-CFG-FirstSet/README.md: -------------------------------------------------------------------------------- 1 | # 使用注意事項 -------------------------------------------------------------------------------- /yacc-ACMProblem/UVa11291/testdata/ac_output~: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Advanced/LLVM/Simple-DCE-pass/Hello/Hello.exports: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bonus1_100502205_v1/output.txt: -------------------------------------------------------------------------------- 1 | A:b,l 2 | B:a 3 | C:b,l 4 | -------------------------------------------------------------------------------- /Advanced/Dataflow/Liveness/.gitignore: -------------------------------------------------------------------------------- 1 | *.exe 2 | Liveness 3 | -------------------------------------------------------------------------------- /Advanced/Dataflow/AvailableExpr/.gitignore: -------------------------------------------------------------------------------- 1 | *.exe 2 | AvailableExpr 3 | -------------------------------------------------------------------------------- /yacc-ACMProblem/UVa11291/input~: -------------------------------------------------------------------------------- 1 | 7 2 | (.5 3 9) 3 | (0.3 2 (1 1 -10)) 4 | 5 | -------------------------------------------------------------------------------- /Advanced/Dataflow/ReachingDefinition/.gitignore: -------------------------------------------------------------------------------- 1 | *.exe 2 | ReachingDefinition 3 | -------------------------------------------------------------------------------- /Advanced/LLVM/GlobalRegisterAllocation/README.md: -------------------------------------------------------------------------------- 1 | ## README.md ## 2 | 3 | 精神 AC,屍體永存 -------------------------------------------------------------------------------- /bonus1_100502205_v1/input.txt: -------------------------------------------------------------------------------- 1 | A->BaAb 2 | A->cC 3 | B->d 4 | B->l 5 | C->eA 6 | C->l 7 | -------------------------------------------------------------------------------- /yacc-ACMProblem/UVa11291/testdata/ac_output: -------------------------------------------------------------------------------- 1 | 7.00 2 | 3.00 3 | 5.60 4 | -1.00 5 | 6 | -------------------------------------------------------------------------------- /Advanced/LLVM/Simple-CSE-pass/MyCSE/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(MyCSE MODULE MyCSE.cpp) 2 | -------------------------------------------------------------------------------- /Advanced/LLVM/Simple-DCE-pass/MyDCE/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(MyDCE MODULE MyDCE.cpp) 2 | -------------------------------------------------------------------------------- /Advanced/LLVM/Simple-DCE-pass/Hello/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(LLVMHello2 MODULE Hello.cpp) 2 | -------------------------------------------------------------------------------- /Advanced/LLVM/GlobalRegisterAllocation/test/clear.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | rm *.ll *.o *.s *.out 4 | -------------------------------------------------------------------------------- /bonus2_100502205_v1/input.txt: -------------------------------------------------------------------------------- 1 | S->E$ 2 | E->E+T 3 | E->T 4 | T->T*P 5 | T->P 6 | P-># 7 | P->(E) 8 | -------------------------------------------------------------------------------- /hw1-NFA2DFA/NFA2DFA.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/morris821028/Compiler/HEAD/hw1-NFA2DFA/NFA2DFA.exe -------------------------------------------------------------------------------- /hw1-NFA2DFA/runDFA.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/morris821028/Compiler/HEAD/hw1-NFA2DFA/runDFA.exe -------------------------------------------------------------------------------- /Advanced/Dataflow/Liveness/Makefile: -------------------------------------------------------------------------------- 1 | CXX=g++ 2 | all: 3 | $(CXX) -std=c++11 Liveness.cpp -o Liveness 4 | -------------------------------------------------------------------------------- /hw1-NFA2DFA/DFA.txt: -------------------------------------------------------------------------------- 1 | (a,b) 2 | (1,2)(*3,4,5)(0) 3 | (*3,4,5)(*5)(*4,5) 4 | (*5)(0)(0) 5 | (*4,5)(*5)(*5) 6 | -------------------------------------------------------------------------------- /bonus2_100502205_v1/output.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/morris821028/Compiler/HEAD/bonus2_100502205_v1/output.txt -------------------------------------------------------------------------------- /yacc-ACMProblem/UVa11291/a.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/morris821028/Compiler/HEAD/yacc-ACMProblem/UVa11291/a.out -------------------------------------------------------------------------------- /Advanced/Dataflow/AvailableExpr/Makefile: -------------------------------------------------------------------------------- 1 | CXX=g++ 2 | all: 3 | $(CXX) -std=c++11 AvailableExpr.cpp -o AvailableExpr 4 | -------------------------------------------------------------------------------- /Advanced/Dataflow/ReachingDefinition/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | g++ -std=c++11 ReachingDefinition.cpp -o ReachingDefinition 3 | -------------------------------------------------------------------------------- /bonus2_100502205_v1/CFG_CFSM.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/morris821028/Compiler/HEAD/bonus2_100502205_v1/CFG_CFSM.cpp -------------------------------------------------------------------------------- /hw1-NFA2DFA/DFAjudge.txt: -------------------------------------------------------------------------------- 1 | (a,b) 2 | (1,2)(*3,4,5)(0) 3 | (*3,4,5)(*5)(*4,5) 4 | (*5)(0)(0) 5 | (*4,5)(*5)(*5) 6 | abbbb 7 | -------------------------------------------------------------------------------- /yacc-ACMProblem/UVa11291/a.tab.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/morris821028/Compiler/HEAD/yacc-ACMProblem/UVa11291/a.tab.o -------------------------------------------------------------------------------- /yacc-ACMProblem/UVa11291/lex.yy.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/morris821028/Compiler/HEAD/yacc-ACMProblem/UVa11291/lex.yy.o -------------------------------------------------------------------------------- /hw1-NFA2DFA/NFA.txt: -------------------------------------------------------------------------------- 1 | (l,a,b,2) 2 | (2,0)(3,0)(0,0) 3 | (0,0)(4,5)(0,0) 4 | (0,0)(0,0)(4,0) 5 | (0,0)(5,0)(5,0) 6 | (*,*)(*,*)(*,*) 7 | -------------------------------------------------------------------------------- /yacc-ACMProblem/UVa11291/make.sh~: -------------------------------------------------------------------------------- 1 | bison -d a.y 2 | flex a.l 3 | gcc -c a.tab.c 4 | gcc -c lex.yy.c 5 | gcc lex.yy.o a.tab.o -lfl 6 | -------------------------------------------------------------------------------- /yacc-ACMProblem/UVa11291/make.sh: -------------------------------------------------------------------------------- 1 | bison -d a.y 2 | flex a.l 3 | gcc -c a.tab.c 4 | gcc -c lex.yy.c 5 | gcc lex.yy.o a.tab.o -lfl 6 | 7 | -------------------------------------------------------------------------------- /yacc-ACMProblem/UVa11291/testdata/input: -------------------------------------------------------------------------------- 1 | 7 2 | (.5 3 9) 3 | (0.3 2 (1 1 -10)) 4 | (1.0 (1.0 (1.0 -1 -2) (1.0 -1 -2)) (1.0 (1.0 1 2) 2)) 5 | 6 | -------------------------------------------------------------------------------- /Advanced/Dataflow/Liveness/images/example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/morris821028/Compiler/HEAD/Advanced/Dataflow/Liveness/images/example.png -------------------------------------------------------------------------------- /SLR(1)-ACMProblem/UVa171/171 - Car Trialling.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/morris821028/Compiler/HEAD/SLR(1)-ACMProblem/UVa171/171 - Car Trialling.cpp -------------------------------------------------------------------------------- /Advanced/LLVM/GlobalRegisterAllocation/patch/README.md: -------------------------------------------------------------------------------- 1 | ## README ## 2 | 3 | ``` 4 | $ cd /home/morris1028/LLVM/llvm-3.8.0.src 5 | $ git diff >patch 6 | ``` -------------------------------------------------------------------------------- /Advanced/LLVM/GlobalRegisterAllocation/source/lib/Transforms/TestPass/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_llvm_loadable_module(LLVMTestPass TestPass.cpp DEPENDS intrinsics_gen) 2 | -------------------------------------------------------------------------------- /Advanced/LLVM/Simple-CSE-pass/R04922067-Report.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/morris821028/Compiler/HEAD/Advanced/LLVM/Simple-CSE-pass/R04922067-Report.docx -------------------------------------------------------------------------------- /Advanced/LLVM/Simple-DCE-pass/R04922067-Report.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/morris821028/Compiler/HEAD/Advanced/LLVM/Simple-DCE-pass/R04922067-Report.docx -------------------------------------------------------------------------------- /Advanced/LLVM/Simple-DCE-pass/test/case1.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | int a = 5, e; 5 | a = a + 5; 6 | return 1; 7 | e = 0; 8 | } 9 | -------------------------------------------------------------------------------- /Advanced/Dataflow/ReachingDefinition/images/example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/morris821028/Compiler/HEAD/Advanced/Dataflow/ReachingDefinition/images/example.png -------------------------------------------------------------------------------- /hw3-CFG-PredicSet/output.txt: -------------------------------------------------------------------------------- 1 | S->Aa:a,b,d,e 2 | S->Bc:b,c 3 | A->D:a,b 4 | A->CA:d,e 5 | B->bA:b 6 | B->l:c 7 | C->dC:d 8 | C->e:e 9 | D->a:a 10 | D->b:b 11 | -------------------------------------------------------------------------------- /Advanced/LLVM/GlobalRegisterAllocation/R04922067-Report.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/morris821028/Compiler/HEAD/Advanced/LLVM/GlobalRegisterAllocation/R04922067-Report.docx -------------------------------------------------------------------------------- /Advanced/LLVM/GlobalRegisterAllocation/R04922067-Report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/morris821028/Compiler/HEAD/Advanced/LLVM/GlobalRegisterAllocation/R04922067-Report.pdf -------------------------------------------------------------------------------- /Advanced/LLVM/Simple-CSE-pass/test/case2.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int f(int a) { 4 | int x = (a * 4) + 2; 5 | int y = (a * 4) + 1; 6 | return (a ? x : y); 7 | } 8 | int main() { 9 | return f(1024); 10 | } 11 | -------------------------------------------------------------------------------- /Advanced/LLVM/Simple-DCE-pass/test/clean.sh: -------------------------------------------------------------------------------- 1 | 2 | for i in case1 case2 case3 case4; 3 | do 4 | rm -f ${i} ${i}.opt.ll ${i}.ll ${i}.opt.adce.ll 5 | rm -f ${i}-mem2reg.bc ${i}-constprop.bc ${i}-simplifycfg.bc ${i}.bc 6 | done; 7 | -------------------------------------------------------------------------------- /Advanced/Dataflow/AvailableExpr/sample.in: -------------------------------------------------------------------------------- 1 | ``` 2 | Entry -> B1 3 | B1 -> B2 4 | B2 -> B3 5 | B3 -> B4 6 | B4 -> Exit 7 | ``` 8 | ``` 9 | B1 10 | + a b c 11 | B2 12 | - b a d 13 | B3 14 | - c b c 15 | B4 16 | - d a d 17 | ``` 18 | -------------------------------------------------------------------------------- /Advanced/LLVM/Simple-CSE-pass/test/case1.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | int a = 30; 5 | int b = 40; 6 | int c = a + b + 10; 7 | int d = (a + b) * c; 8 | printf("%d\n", c + d); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /Advanced/LLVM/Simple-DCE-pass/test/case4.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | int a = 1, b = 1000000; 5 | if (a < 0) 6 | for (int i = 0; i < b; i++); 7 | else 8 | for (int j = 0; j < b; j++); 9 | return 1; 10 | } 11 | -------------------------------------------------------------------------------- /Advanced/Dataflow/AvailableExpr/sample2.in: -------------------------------------------------------------------------------- 1 | ``` 2 | Entry -> B:1 3 | B1 -> B2 4 | B1 -> B3 5 | B2 -> B4 6 | B3 -> B4 7 | B4 -> Exit 8 | ``` 9 | ``` 10 | B1 11 | + a b c 12 | + b a d 13 | B2 14 | + c e f 15 | B3 16 | + c e f 17 | B4 18 | + g x y 19 | ``` 20 | -------------------------------------------------------------------------------- /Advanced/LLVM/Simple-CSE-pass/test/case3.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int f(int a, int b) { 4 | int x = (a * 40) + 2; 5 | int y = a + b; 6 | int z = (a * 40 + 161); 7 | return (a > 0 ? x : z); 8 | } 9 | int main() { 10 | return f(514, 1024); 11 | } 12 | -------------------------------------------------------------------------------- /yacc-ACMProblem/UVa11291/uva11291.l~: -------------------------------------------------------------------------------- 1 | %{ 2 | #include "uva11291.tab.h" 3 | %} 4 | 5 | %% 6 | [0-9]*(\.[0-9]*) {sscanf(yytext, "%lf", &yylval); return NUMBER;} 7 | [(] {return LEFT_P;} 8 | [)] {return RIGHT_P;} 9 | \n {} 10 | . {} 11 | %% 12 | -------------------------------------------------------------------------------- /Advanced/LLVM/Simple-CSE-pass/test/clean.sh: -------------------------------------------------------------------------------- 1 | 2 | for i in case1 case2 case3 case4 case5; 3 | do 4 | rm -f ${i} ${i}.opt.ll ${i}.ll ${i}.opt.adce.ll 5 | rm -f *.bc 6 | rm -f ${i}-mem2reg.bc ${i}-constprop.bc ${i}-simplifycfg.bc ${i}.bc 7 | rm -f ${i} ${i}-cse ${i}-mem2reg 8 | done; 9 | -------------------------------------------------------------------------------- /Advanced/LLVM/Simple-DCE-pass/test/case2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | int f(int *arg) { 4 | int ret = 0; 5 | int a = 0, b = 0; 6 | if (*arg == 1) 7 | ret = 1; 8 | return 10; 9 | } 10 | 11 | int main(void) { 12 | int v = 1; 13 | return f(&v); 14 | } 15 | -------------------------------------------------------------------------------- /Advanced/Dataflow/Liveness/sample.in: -------------------------------------------------------------------------------- 1 | ``` 2 | Entry -> B1 3 | B1 -> B2 4 | B2 -> B3 5 | B2 -> B4 6 | B3 -> B4 7 | B4 -> B2 8 | B4 -> Exit 9 | ``` 10 | ``` 11 | B1 12 | d1 i m 13 | d2 j n 14 | d3 a u1 15 | B2 16 | d4 i i 17 | d5 j j 18 | B3 19 | d6 a u2 20 | B4 21 | d7 i u3 22 | ``` 23 | -------------------------------------------------------------------------------- /Advanced/LLVM/Simple-DCE-pass/test/case3.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int foo(int *arg) { 4 | const int a = 5; 5 | int b; 6 | if (a > 10 && arg == NULL) 7 | b = 10; 8 | else 9 | b = 20; 10 | arg = NULL; 11 | return b; 12 | } 13 | int main() { 14 | return foo(NULL); 15 | } 16 | -------------------------------------------------------------------------------- /Advanced/Dataflow/ReachingDefinition/sample.in: -------------------------------------------------------------------------------- 1 | ``` 2 | Entry -> B1 3 | B1 -> B2 4 | B2 -> B3 5 | B2 -> B4 6 | B3 -> B4 7 | B4 -> B2 8 | B4 -> Exit 9 | ``` 10 | ``` 11 | B1 12 | d1 i m 13 | d2 j n 14 | d3 a u1 15 | B2 16 | d4 i i 17 | d5 j j 18 | B3 19 | d6 a u2 20 | B4 21 | d7 i u3 22 | ``` 23 | -------------------------------------------------------------------------------- /hw3-CFG-PredicSet/input.txt: -------------------------------------------------------------------------------- 1 | S->Aa 2 | S->Bc 3 | A->D 4 | A->CA 5 | B->bA 6 | B->l 7 | C->dC 8 | C->e 9 | D->a 10 | D->b 11 | 12 | S:a,b,c,d,e,l 13 | A:a,b,d,e 14 | B:b,l 15 | C:d,e 16 | D:a,b 17 | a:a 18 | b:b 19 | c:c 20 | d:d 21 | e:e 22 | 23 | S:l 24 | A:a,c 25 | B:c 26 | C:a,b,d,e 27 | D:a,c 28 | -------------------------------------------------------------------------------- /Advanced/LLVM/Simple-CSE-pass/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.2) 2 | find_package(LLVM 3.7 REQUIRED CONFIG) 3 | set(CMAKE_CXX_STANDARD 11) 4 | 5 | add_definitions(${LLVM_DEFINITIONS}) 6 | include_directories(${LLVM_INCLUDE_DIRS}) 7 | set(CMAKE_CXX_FLAGS "-fno-rtti") 8 | 9 | add_subdirectory(MyCSE) 10 | -------------------------------------------------------------------------------- /Advanced/LLVM/GlobalRegisterAllocation/source/lib/Transforms/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(Utils) 2 | add_subdirectory(Instrumentation) 3 | add_subdirectory(InstCombine) 4 | add_subdirectory(Scalar) 5 | add_subdirectory(IPO) 6 | add_subdirectory(Vectorize) 7 | add_subdirectory(Hello) 8 | add_subdirectory(ObjCARC) 9 | add_subdirectory(TestPass) 10 | -------------------------------------------------------------------------------- /Advanced/LLVM/Simple-DCE-pass/MyDCE/MyDCE.h: -------------------------------------------------------------------------------- 1 | #include "llvm/Pass.h" 2 | #include "llvm/IR/Function.h" 3 | #include "llvm/Support/raw_ostream.h" 4 | 5 | using namespace llvm; 6 | 7 | class MyDCE : public FunctionPass { 8 | public: 9 | static char ID; 10 | MyDCE(): FunctionPass(ID) {} 11 | bool runOnFunction(Function &F) override; 12 | }; 13 | -------------------------------------------------------------------------------- /yacc-ACMProblem/UVa11291/a.l~: -------------------------------------------------------------------------------- 1 | %{ 2 | #include "a.tab.h" 3 | #include 4 | %} 5 | 6 | %% 7 | (-)[0-9]*\.[0-9]* {sscanf(yytext, "%f", &yylval.floatVal); return NUMBER;} 8 | (-)[0-9]+ {sscanf(yytext, "%f", &yylval.floatVal); return NUMBER;} 9 | "(" {return LEFT_P;} 10 | ")" {return RIGHT_P;} 11 | \n {} 12 | . {} 13 | %% 14 | -------------------------------------------------------------------------------- /Advanced/LLVM/Simple-DCE-pass/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.2) 2 | find_package(LLVM 3.7 REQUIRED CONFIG) 3 | set(CMAKE_CXX_STANDARD 11) 4 | 5 | add_definitions(${LLVM_DEFINITIONS}) 6 | include_directories(${LLVM_INCLUDE_DIRS}) 7 | set(CMAKE_CXX_FLAGS "-fno-rtti") 8 | 9 | add_subdirectory(Hello) 10 | add_subdirectory(MyDCE) 11 | 12 | -------------------------------------------------------------------------------- /yacc-ACMProblem/UVa11291/a.l: -------------------------------------------------------------------------------- 1 | %{ 2 | #include "a.tab.h" 3 | #include 4 | %} 5 | 6 | %% 7 | ([-]?)[0-9]*\.[0-9]* {sscanf(yytext, "%f", &yylval.floatVal); return NUMBER;} 8 | ([-]?)[0-9]+ {sscanf(yytext, "%f", &yylval.floatVal); return NUMBER;} 9 | "(" {return LEFT_P;} 10 | ")" {return RIGHT_P;} 11 | \n {} 12 | . {} 13 | %% 14 | -------------------------------------------------------------------------------- /Advanced/LLVM/Simple-CSE-pass/MyCSE/MyCSE.h: -------------------------------------------------------------------------------- 1 | #include "llvm/Pass.h" 2 | #include "llvm/IR/BasicBlock.h" 3 | #include "llvm/Support/raw_ostream.h" 4 | 5 | using namespace llvm; 6 | 7 | class MyCSE : public BasicBlockPass { 8 | public: 9 | static char ID; 10 | MyCSE(): BasicBlockPass(ID) {} 11 | bool runOnBasicBlock(BasicBlock &BB) override; 12 | }; 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 編譯器、計算理論 題組系列 ## 2 | 3 | 涉及 regex, DFA, NFA, CFG, LL(1), SLR, turing machine。同構判定,模擬操作,無法簡單地使用遞迴分析字串的情況下 ... 4 | 5 | * UVa 1671 - History of Languages 6 | * UVa 1672 - Disjoint Regular Expressions 7 | * UVa 10597 - Right Words 8 | * UVa 134 - Loglan-A Logical Language 9 | * UVa 171 - Car Trialling 10 | * UVa 11711 - Turing 11 | * UVa 12415 - Digit Patterns -------------------------------------------------------------------------------- /Advanced/LLVM/Simple-CSE-pass/test/case5.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define n 1024 4 | double a[n*n], b[n*n]; 5 | int main() { 6 | int i, j, k; 7 | for (i = 1; i < n-1; i++) { 8 | for (j = 1; j < n-1; j++) { 9 | b[i*n+j] = ( 10 | 5 * a[i*n+j] + a[(i-1)*n+j] + a[i*n+(j-1)] 11 | + a[(i+1)*n+j] + a[i*n+(j+1)] 12 | )/9; 13 | } 14 | } 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /Advanced/LLVM/GlobalRegisterAllocation/test/call-lib.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int f(int a, int b, int c[]) { 4 | int sum = 0; 5 | for (int i = 0; i < a; i++) 6 | c[i] = i * b; 7 | for (int i = 0; i < a; i++) 8 | sum += c[i]; 9 | return sum; 10 | } 11 | int main() { 12 | int a = 5, b = 10, c[32767] = {}; 13 | int sum = f(a, b, c); 14 | printf("%d\n", sum); 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /Advanced/LLVM/Simple-CSE-pass/test/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | make -C ../build -j12 4 | 5 | for i in case1 case2 case3 case4 case5; 6 | do 7 | echo "\033[35mTest ${i} \033[0m" 8 | clang ${i}.c -DDEBUG -S -emit-llvm -o ${i}.bc 9 | opt -mem2reg -S ${i}.bc -o ${i}-mem2reg.bc 10 | opt -load ../build/MyCSE/libMyCSE.so -myMagicCSE -S ${i}-mem2reg.bc -o ${i}-cse.bc 11 | clang ${i}-mem2reg.bc -o ${i}-mem2reg 12 | clang ${i}-cse.bc -o ${i}-cse 13 | done 14 | -------------------------------------------------------------------------------- /Advanced/LLVM/GlobalRegisterAllocation/source/lib/Target/X86/X86TestPassLoader.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "X86.h" 4 | #include "llvm/Pass.h" 5 | 6 | using namespace llvm; 7 | 8 | FunctionPass *(*loadableFunction)(); 9 | 10 | FunctionPass *llvm::createX86TestPass() { 11 | return loadableFunction(); 12 | } 13 | 14 | ModulePass *(*loadableFunction2)(); 15 | 16 | ModulePass *llvm::createX86TestPass2() { 17 | return loadableFunction2(); 18 | } 19 | -------------------------------------------------------------------------------- /Advanced/LLVM/GlobalRegisterAllocation/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | wget http://llvm.org/releases/3.8.0/llvm-3.8.0.src.tar.xz 4 | tar Jxvf llvm-3.8.0.src.tar.xz 5 | 6 | 7 | # ubuntu 14.04 8 | # $ wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key|sudo apt-key add - 9 | # $ vim /etc/apt/sources.lst 10 | # ## add into last line 11 | # deb http://llvm.org/apt/trusty/ llvm-toolchain-trusty-3.8 main 12 | # $ sudo apt-get update 13 | sudo apt-get install g++-multilib clang-3.8 14 | -------------------------------------------------------------------------------- /hw2-CFG-FirstSet/input.txt: -------------------------------------------------------------------------------- 1 | S->aSe 2 | S->B 3 | B->bBe 4 | B->C 5 | C->cCe 6 | C->d 7 | 8 | A->BaAb 9 | A->cC 10 | B->d 11 | B->l 12 | C->eA 13 | C->l 14 | 15 | A->aAd 16 | A->B 17 | B->bBd 18 | B->C 19 | C->cCd 20 | C->l 21 | 22 | E->TX 23 | X->+E 24 | X-># 25 | T->(E) 26 | T->intY 27 | Y->*T 28 | Y-># 29 | 30 | E->P(E) 31 | E->vT 32 | P->f 33 | P->l 34 | T->+E 35 | T->l 36 | 37 | S->aSe 38 | S->B 39 | B->bBe 40 | B->C 41 | C->cCe 42 | C->d 43 | 44 | S->ABc 45 | A->a 46 | A->l 47 | B->b 48 | B->l 49 | -------------------------------------------------------------------------------- /Advanced/LLVM/Simple-DCE-pass/Hello/CMakeLists.txt-backup: -------------------------------------------------------------------------------- 1 | # If we don't need RTTI or EH, there's no reason to export anything 2 | # from the hello plugin. 3 | if( NOT LLVM_REQUIRES_RTTI ) 4 | if( NOT LLVM_REQUIRES_EH ) 5 | set(LLVM_EXPORTED_SYMBOL_FILE ${CMAKE_CURRENT_SOURCE_DIR}/Hello.exports) 6 | endif() 7 | endif() 8 | 9 | if(WIN32 OR CYGWIN) 10 | set(LLVM_LINK_COMPONENTS Core Support) 11 | endif() 12 | 13 | add_llvm_loadable_module( LLVMHello 14 | Hello.cpp 15 | 16 | DEPENDS 17 | intrinsics_gen 18 | ) 19 | -------------------------------------------------------------------------------- /Advanced/LLVM/Simple-CSE-pass/test/case4.c: -------------------------------------------------------------------------------- 1 | /* 2 | Test for common subexpression elimination. 3 | */ 4 | #include 5 | int main(void){ 6 | int i, j, x, y, z, a, b, c, d, e; 7 | unsigned int checksum = 0; 8 | a = 10; b = 10; c = 10; d = 1; e = 1; 9 | for (i = 0; i < 5000; i += 1){ 10 | for (j = 0; j < 50000; j += 1){ 11 | x = a * b / c; 12 | y = a * b / c + d; 13 | z = a * b / c + d - e; 14 | checksum += x + y + z; 15 | } 16 | a += 1; b += 1; c += 1; d += 1; e += 1; 17 | } 18 | printf("%u\n", checksum); 19 | return 0; 20 | } 21 | 22 | -------------------------------------------------------------------------------- /Advanced/LLVM/Simple-DCE-pass/test/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | make -C ../build -j12 4 | 5 | for i in case1 case2; 6 | do 7 | echo "\033[35mTest ${i} \033[0m" 8 | clang ${i}.c -DDEBUG -S -emit-llvm -o ${i}.bc 9 | opt -mem2reg -S ${i}.bc -o ${i}-mem2reg.bc 10 | opt -constprop -S ${i}-mem2reg.bc -o ${i}-constprop.bc 11 | opt -simplifycfg -S ${i}-constprop.bc -o ${i}-simplifycfg.bc 12 | opt -load ../build/MyDCE/libMyDCE.so -myMagicDCE -S ${i}-simplifycfg.bc -o ${i}.opt.ll 13 | opt -adce -S ${i}-simplifycfg.bc -o ${i}.opt.adce.ll 14 | clang ${i}.opt.ll -o ${i} 15 | done 16 | -------------------------------------------------------------------------------- /hw2-CFG-FirstSet/output.txt: -------------------------------------------------------------------------------- 1 | B:b,c,d 2 | C:c,d 3 | S:a,b,c,d 4 | a:a 5 | b:b 6 | c:c 7 | d:d 8 | e:e 9 | A:a,c,d 10 | B:d,l 11 | C:e,l 12 | a:a 13 | b:b 14 | c:c 15 | d:d 16 | e:e 17 | A:a,b,c,l 18 | B:b,c,l 19 | C:c,l 20 | a:a 21 | b:b 22 | c:c 23 | d:d 24 | #:# 25 | (:( 26 | ):) 27 | *:* 28 | +:+ 29 | E:(,i 30 | T:(,i 31 | X:#,+ 32 | Y:#,* 33 | i:i 34 | n:n 35 | t:t 36 | (:( 37 | ):) 38 | +:+ 39 | E:(,f,v 40 | P:f,l 41 | T:+,l 42 | f:f 43 | v:v 44 | B:b,c,d 45 | C:c,d 46 | S:a,b,c,d 47 | a:a 48 | b:b 49 | c:c 50 | d:d 51 | e:e 52 | A:a,l 53 | B:b,l 54 | S:a,b,c 55 | a:a 56 | b:b 57 | c:c 58 | -------------------------------------------------------------------------------- /yacc-ACMProblem/UVa11291/uva11291.y~: -------------------------------------------------------------------------------- 1 | %{ 2 | 3 | #include 4 | #define YYSTYPE double 5 | int yylex(); 6 | double ans = 0; 7 | void yyerror(const char* message) { 8 | ans = -2147483647; 9 | printf("Invaild format\n"); 10 | }; 11 | %} 12 | 13 | %token LEFT_P RIGHT_P NUMBER 14 | 15 | %% 16 | startsymbol 17 | : LEFT_P NUMBER expression expression RIGHT_P { 18 | ans = $2 * $3 + (1 - $2) * $3; 19 | } 20 | ; 21 | expression 22 | : LEFT_P NUMBER expression expression RIGHT_P { 23 | $$ = $2 * $3 + (1 - $2) * $3; 24 | } 25 | | NUMBER { 26 | $$ = $1; 27 | } 28 | ; 29 | %% 30 | -------------------------------------------------------------------------------- /Advanced/LLVM/GlobalRegisterAllocation/test/case1.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | long long mul(long long a, long long b, long long mod) { 4 | long long ret = 0; 5 | for (a %= mod, b %= mod; b != 0; b>>=1, a <<= 1, a = a >= mod ? a - mod : a) { 6 | if (b&1) { 7 | ret += a; 8 | if (ret >= mod) ret -= mod; 9 | } 10 | } 11 | return ret; 12 | } 13 | unsigned long long mpow(unsigned long long x, unsigned long long y, unsigned long long mod) { 14 | unsigned long long ret = 1; 15 | while (y) { 16 | if (y&1) 17 | ret = mul(ret, x, mod); 18 | y >>= 1, x = mul(x, x, mod); 19 | } 20 | return ret % mod; 21 | } 22 | 23 | int main() { 24 | printf("%lld\n", mpow(2, 10, 1000)); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /Advanced/LLVM/GlobalRegisterAllocation/test/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | TEXT_RED=`tput setaf 1` 4 | TEXT_GREEN=`tput setaf 2` 5 | TEXT_RESET=`tput sgr0` 6 | 7 | export LLVM_DIR=/home/morris1028/LLVM/llvm-3.8.0.src/build/bin 8 | export PATH=$LLVM_DIR:$PATH 9 | export LD_LIBRARY_PATH=/home/morris1028/LLVM/llvm-3.8.0.src/build/lib:$LD_LIBRARY_PATH 10 | 11 | CLANG_ENGINE=clang-3.8 12 | #CFLAGS=-m32 13 | #LLCFLAGS=-march=x86 14 | 15 | for i in call-lib case1; 16 | do 17 | echo "[INFO] compile ${TEXT_GREEN}${i}${TEXT_RESET}" 18 | $CLANG_ENGINE $CFLAGS -fno-inline ${i}.c -S -emit-llvm -o ${i}.ll 19 | opt ${i}.ll -O2 -disable-inlining -o ${i}.1.ll 20 | llc ${i}.1.ll $LLCFLAGS -O3 -o ${i}.1.s 21 | $CLANG_ENGINE $CFLAGS ${i}.1.s -o ${i}.out 22 | done 23 | -------------------------------------------------------------------------------- /yacc-ACMProblem/UVa11291/a.y: -------------------------------------------------------------------------------- 1 | %{ 2 | 3 | #include 4 | int yylex(); 5 | double ans = 0; 6 | void yyerror(const char* message) { 7 | ans = -2147483647; 8 | printf("Invaild format\n"); 9 | }; 10 | %} 11 | 12 | %union { 13 | float floatVal; 14 | int intVal; 15 | } 16 | %type NUMBER 17 | %type expression 18 | %type startsymbol 19 | 20 | %token LEFT_P RIGHT_P NUMBER 21 | 22 | %% 23 | input 24 | : input startsymbol { 25 | ans = $2; 26 | printf("%.2f\n", ans); 27 | } 28 | | { 29 | } 30 | startsymbol 31 | : expression { 32 | $$ = $1; 33 | } 34 | ; 35 | expression 36 | : NUMBER { 37 | $$ = $1; 38 | } 39 | | LEFT_P NUMBER expression expression RIGHT_P { 40 | $$ = $2 * ($3 + $4) + (1.0f - $2) * ($3 - $4); 41 | } 42 | ; 43 | %% 44 | 45 | int main() { 46 | yyparse(); 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /yacc-ACMProblem/UVa11291/a.y~: -------------------------------------------------------------------------------- 1 | %{ 2 | 3 | #include 4 | int yylex(); 5 | double ans = 0; 6 | void yyerror(const char* message) { 7 | ans = -2147483647; 8 | printf("Invaild format\n"); 9 | }; 10 | %} 11 | 12 | %union { 13 | float floatVal; 14 | int intVal; 15 | } 16 | %type NUMBER 17 | %type expression 18 | %type startsymbol 19 | 20 | %token LEFT_P RIGHT_P NUMBER 21 | 22 | %% 23 | input 24 | : input startsymbol { 25 | ans = $2; 26 | printf("%f\n", ans); 27 | } 28 | | { 29 | } 30 | startsymbol 31 | : expression { 32 | $$ = $1; 33 | } 34 | ; 35 | expression 36 | : NUMBER { 37 | $$ = $1; 38 | } 39 | | LEFT_P NUMBER expression expression RIGHT_P { 40 | $$ = $2 * ($3 + $4) + (1.0f - $2) * ($3 - $4); 41 | } 42 | ; 43 | %% 44 | 45 | int main() { 46 | yyparse(); 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /Advanced/LLVM/Simple-DCE-pass/README.md: -------------------------------------------------------------------------------- 1 | ## Install LLVM by Source ## 2 | 3 | ``` 4 | mkdir -p ~/LLVM && cd ~/LLVM 5 | wget -O - http://llvm.org/releases/3.7.1/llvm-3.7.1.src.tar.xz | tar Jxf - 6 | wget -O - http://llvm.org/releases/3.7.1/cfe-3.7.1.src.tar.xz | \ 7 | tar Jxf - -C llvm-3.7.1.src/tools 8 | ``` 9 | 10 | ``` 11 | mkdir -p ~/LLVM/hw1/build 12 | ``` 13 | 14 | ``` 15 | cd ~/LLVM/llvm-3.7.1.src 16 | mkdir build && cd build 17 | cmake .. 18 | make -j12 19 | sudo cmake -DCMAKE_INSTALL_PREFIX=/home/morris1028/LLVM/hw1/build -P cmake_install.cmake 20 | cd /home/morris1028/LLVM/hw1/build && cmake .. && make 21 | ``` 22 | 23 | ``` 24 | export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games 25 | ``` 26 | 27 | ### Test Dead Code Elimination Algorithm ### 28 | 29 | #### build DCE.cpp source & compile testcases ### 30 | 31 | ``` 32 | cd ~/LLVM/hw1/test 33 | sh test.sh 34 | ``` 35 | 36 | #### clean #### 37 | 38 | ``` 39 | sh clean.sh 40 | ``` 41 | -------------------------------------------------------------------------------- /Advanced/Dataflow/AvailableExpr/sample2.out: -------------------------------------------------------------------------------- 1 | === Basic Block Information === 2 | --- Entry --- 3 | --- Exit --- 4 | --- B1 --- 5 | [0] a = + b c 6 | [1] b = + a d 7 | --- B2 --- 8 | [2] c = + e f 9 | --- B3 --- 10 | [3] c = + e f 11 | --- B4 --- 12 | [4] g = + x y 13 | === 14 | 15 | === Basic Block Available Expressions === 16 | --- Entry --- 17 | GEN : 18 | KILL: 19 | IN : 20 | OUT : 21 | --- Exit --- 22 | GEN : 23 | KILL: 24 | IN : 25 | [4] g = + x y 26 | OUT : 27 | [4] g = + x y 28 | --- B1 --- 29 | GEN : 30 | [0] a = + b c 31 | KILL: 32 | [1] b = + a d 33 | IN : 34 | OUT : 35 | [0] a = + b c 36 | --- B2 --- 37 | GEN : 38 | [2] c = + e f 39 | KILL: 40 | [0] a = + b c 41 | IN : 42 | [0] a = + b c 43 | OUT : 44 | [2] c = + e f 45 | --- B3 --- 46 | GEN : 47 | [3] c = + e f 48 | KILL: 49 | [0] a = + b c 50 | IN : 51 | [0] a = + b c 52 | OUT : 53 | [3] c = + e f 54 | --- B4 --- 55 | GEN : 56 | [4] g = + x y 57 | KILL: 58 | IN : 59 | OUT : 60 | [4] g = + x y 61 | === 62 | 63 | -------------------------------------------------------------------------------- /Advanced/Dataflow/AvailableExpr/sample.out: -------------------------------------------------------------------------------- 1 | === Basic Block Information === 2 | --- Entry --- 3 | --- Exit --- 4 | --- B1 --- 5 | [0] a = + b c 6 | --- B2 --- 7 | [1] b = - a d 8 | --- B3 --- 9 | [2] c = - b c 10 | --- B4 --- 11 | [3] d = - a d 12 | === 13 | 14 | === Basic Block Available Expressions === 15 | --- Entry --- 16 | GEN : 17 | KILL: 18 | IN : 19 | OUT : 20 | --- Exit --- 21 | GEN : 22 | KILL: 23 | IN : 24 | [2] c = - b c 25 | [3] d = - a d 26 | OUT : 27 | [2] c = - b c 28 | [3] d = - a d 29 | --- B1 --- 30 | GEN : 31 | [0] a = + b c 32 | KILL: 33 | [1] b = - a d 34 | [3] d = - a d 35 | IN : 36 | OUT : 37 | [0] a = + b c 38 | --- B2 --- 39 | GEN : 40 | [1] b = - a d 41 | KILL: 42 | [0] a = + b c 43 | [2] c = - b c 44 | IN : 45 | [0] a = + b c 46 | OUT : 47 | [1] b = - a d 48 | --- B3 --- 49 | GEN : 50 | [2] c = - b c 51 | KILL: 52 | [0] a = + b c 53 | IN : 54 | [1] b = - a d 55 | OUT : 56 | [1] b = - a d 57 | [2] c = - b c 58 | --- B4 --- 59 | GEN : 60 | [3] d = - a d 61 | KILL: 62 | [1] b = - a d 63 | IN : 64 | [1] b = - a d 65 | [2] c = - b c 66 | OUT : 67 | [2] c = - b c 68 | [3] d = - a d 69 | === 70 | 71 | -------------------------------------------------------------------------------- /yacc-ACMProblem/README.md: -------------------------------------------------------------------------------- 1 | More 2 | ===== 3 | 4 | [Blog 說明](http://morris821028.github.io/2014/05/12/uva-11291-with-yacc/) 5 | 6 | Problem 7 | ===== 8 | 9 | 詳細題目請參考 [UVa 11291 - Smeech](http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=2266) 10 | 11 | 語法 12 | ``` 13 | -> | (p ) 14 | -> #number 15 | ``` 16 | 17 | 目標計算出 `E[X] = p * (e1 + e2) + (1 - p) * (e1 - e2)` 18 | 19 | Yacc 20 | ===== 21 | 22 | Yacc 主要是根據 CFG 進行解析。 23 | 24 | 其中,要對於 Yacc 語法的回傳值明白操作情況。 25 | 26 | 對於語法回傳值,我們來個最簡單的範例: 27 | ``` 28 | expression -> LEFT_P NUMBER expression expression RIGHT_P 29 | $$ $1 $2 $3 $4 $5 30 | ``` 31 | 其中 `$$` 是回傳值,其中的 `$1`、`$2` ... 等,都是得到的回傳值。 32 | 33 | 對於 `yylval` 形態處理: 34 | ``` 35 | %union { 36 | float floatVal; 37 | int intVal; 38 | } 39 | ``` 40 | 通常使用 `union` 的方式來共用記憶體,在 lex 那邊就可以根據 `yylval.floatVal` 進行操作。 41 | 42 | 當然,我們也要對於每一個 `nonterminal` 定義回傳的型態 43 | 44 | ``` 45 | %type NUMBER 46 | %type expression 47 | %type startsymbol 48 | ``` 49 | 50 | 基本上就大功告成了。 51 | 52 | 接著要考慮如何去完成多組測資組的問題,在這裡可以利用 kleene star 來完成。 53 | 54 | 但是對於輸出順序,使用 `input -> input startsymbol` 跟 `input -> startsymbol input` 輸出順序是不同的,如果要順著輸出,請選擇前者。 55 | ... -------------------------------------------------------------------------------- /Advanced/LLVM/GlobalRegisterAllocation/source/lib/Target/X86/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(LLVM_TARGET_DEFINITIONS X86.td) 2 | 3 | tablegen(LLVM X86GenRegisterInfo.inc -gen-register-info) 4 | tablegen(LLVM X86GenDisassemblerTables.inc -gen-disassembler) 5 | tablegen(LLVM X86GenInstrInfo.inc -gen-instr-info) 6 | tablegen(LLVM X86GenAsmWriter.inc -gen-asm-writer) 7 | tablegen(LLVM X86GenAsmWriter1.inc -gen-asm-writer -asmwriternum=1) 8 | tablegen(LLVM X86GenAsmMatcher.inc -gen-asm-matcher) 9 | tablegen(LLVM X86GenDAGISel.inc -gen-dag-isel) 10 | tablegen(LLVM X86GenFastISel.inc -gen-fast-isel) 11 | tablegen(LLVM X86GenCallingConv.inc -gen-callingconv) 12 | tablegen(LLVM X86GenSubtargetInfo.inc -gen-subtarget) 13 | add_public_tablegen_target(X86CommonTableGen) 14 | 15 | set(sources 16 | X86TestPassLoader.cpp 17 | X86AsmPrinter.cpp 18 | X86CallFrameOptimization.cpp 19 | X86ExpandPseudo.cpp 20 | X86FastISel.cpp 21 | X86FloatingPoint.cpp 22 | X86FrameLowering.cpp 23 | X86ISelDAGToDAG.cpp 24 | X86ISelLowering.cpp 25 | X86InstrInfo.cpp 26 | X86MCInstLower.cpp 27 | X86MachineFunctionInfo.cpp 28 | X86PadShortFunction.cpp 29 | X86RegisterInfo.cpp 30 | X86SelectionDAGInfo.cpp 31 | X86ShuffleDecodeConstantPool.cpp 32 | X86Subtarget.cpp 33 | X86TargetMachine.cpp 34 | X86TargetObjectFile.cpp 35 | X86TargetTransformInfo.cpp 36 | X86VZeroUpper.cpp 37 | X86FixupLEAs.cpp 38 | X86WinEHState.cpp 39 | X86OptimizeLEAs.cpp 40 | ) 41 | 42 | add_llvm_target(X86CodeGen ${sources}) 43 | 44 | add_subdirectory(AsmParser) 45 | add_subdirectory(Disassembler) 46 | add_subdirectory(InstPrinter) 47 | add_subdirectory(MCTargetDesc) 48 | add_subdirectory(TargetInfo) 49 | add_subdirectory(Utils) 50 | -------------------------------------------------------------------------------- /Advanced/LLVM/Simple-DCE-pass/Hello/Hello.cpp: -------------------------------------------------------------------------------- 1 | //===- Hello.cpp - Example code from "Writing an LLVM Pass" ---------------===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // This file implements two versions of the LLVM "Hello World" pass described 11 | // in docs/WritingAnLLVMPass.html 12 | // 13 | //===----------------------------------------------------------------------===// 14 | 15 | #include "llvm/ADT/Statistic.h" 16 | #include "llvm/IR/Function.h" 17 | #include "llvm/Pass.h" 18 | #include "llvm/Support/raw_ostream.h" 19 | using namespace llvm; 20 | 21 | #define DEBUG_TYPE "hello" 22 | 23 | STATISTIC(HelloCounter, "Counts number of functions greeted"); 24 | 25 | namespace { 26 | // Hello - The first implementation, without getAnalysisUsage. 27 | struct Hello : public FunctionPass { 28 | static char ID; // Pass identification, replacement for typeid 29 | Hello() : FunctionPass(ID) {} 30 | 31 | bool runOnFunction(Function &F) override { 32 | ++HelloCounter; 33 | errs() << "Hello: "; 34 | errs().write_escaped(F.getName()) << '\n'; 35 | return false; 36 | } 37 | }; 38 | } 39 | 40 | char Hello::ID = 0; 41 | static RegisterPass X("hello", "Hello World Pass"); 42 | 43 | namespace { 44 | // Hello2 - The second implementation with getAnalysisUsage implemented. 45 | struct Hello2 : public FunctionPass { 46 | static char ID; // Pass identification, replacement for typeid 47 | Hello2() : FunctionPass(ID) {} 48 | 49 | bool runOnFunction(Function &F) override { 50 | ++HelloCounter; 51 | errs() << "Hello: "; 52 | errs().write_escaped(F.getName()) << '\n'; 53 | return false; 54 | } 55 | 56 | // We don't modify the program, so we preserve all analyses. 57 | void getAnalysisUsage(AnalysisUsage &AU) const override { 58 | AU.setPreservesAll(); 59 | } 60 | }; 61 | } 62 | 63 | char Hello2::ID = 0; 64 | static RegisterPass 65 | Y("hello2", "Hello World Pass (with getAnalysisUsage implemented)"); 66 | -------------------------------------------------------------------------------- /Advanced/Dataflow/AvailableExpr/README.md: -------------------------------------------------------------------------------- 1 | ## Liveness ## 2 | 3 | A variable is live out if used by a successor. 4 | 5 | ### Install ### 6 | 7 | ``` 8 | $ make CXX=g++ 9 | ``` 10 | 11 | or 12 | 13 | ``` 14 | $ make CXX=g++-4.8 15 | ``` 16 | 17 | ### Algorithm ### 18 | 19 | ``` 20 | // initialization 21 | IN[exit] = 0 22 | foreach B other than entry 23 | IN[B] = 0 24 | 25 | // iterating until reaching fixed point 26 | While some OUT[B] changes 27 | IN[B] = USE[B] union (OUT[B] - DEF[B]) 28 | OUT[B] = UNION IN[S] where S in Successor(B) 29 | ``` 30 | 31 | ### Example ### 32 | 33 | ``` 34 | +------------+ 35 | | | 36 | | a = b + c | B1 37 | | | 38 | +------------+ 39 | | 40 | | 41 | +---v--------+ 42 | | | 43 | | b = a - d | B2 44 | | | 45 | +------------+ 46 | | 47 | | 48 | +---v--------+ 49 | | | 50 | | c = b - c | B3 51 | | | 52 | +------------+ 53 | | 54 | | 55 | +---v--------+ 56 | | | 57 | | d = a - d | B4 58 | | | 59 | +------------+ 60 | ``` 61 | 62 | ### Sample Input 1 ### 63 | 64 | *** in sample.in *** 65 | 66 | ### Sample Output 1 ### 67 | 68 | *** in sample.out *** 69 | 70 | ### Example 2 ### 71 | 72 | ``` 73 | +-------------+ 74 | | | 75 | | a = b + c | B1 76 | | b = c + d | 77 | +----+ +----+ 78 | | +-------------+ | 79 | | | 80 | | | 81 | +------v------+ +------v------+ 82 | | | | | 83 | | c = e + f | B2 | c = e + f | B3 84 | | | | | 85 | +------+------+ +------+------+ 86 | | | 87 | | | 88 | | +-------------+ | 89 | +----> <----+ 90 | | g = x + y | 91 | | | B4 92 | +-------------+ 93 | ``` 94 | 95 | ### Sample Input 2 ### 96 | 97 | *** in sample2.in *** 98 | 99 | ### Sample Output 2 ### 100 | 101 | *** in sample2.out *** 102 | 103 | ### Reference ### 104 | 105 | NTU Department of Computer Science and Information Engineering - Advanced Compiler 106 | -------------------------------------------------------------------------------- /Advanced/Dataflow/ReachingDefinition/README.md: -------------------------------------------------------------------------------- 1 | ## Reaching Definition ## 2 | 3 | ### Algorithm ### 4 | 5 | ``` 6 | // initialization 7 | OUT[entry] = 0 8 | foreach B other than entry 9 | OUT[B] = 0 10 | 11 | // iterating until reaching fixed point 12 | While some OUT[B] changes 13 | OUT[B] = GEN[B] union (IN[B] - KILL[B]) 14 | IN[B] = UNION OUT[P] where P in Pred(B) 15 | ``` 16 | 17 | ### Example ### 18 | 19 | ![Textbook Example Figure 9.13](images/example.png) 20 | 21 | ### Sample Input ### 22 | 23 |
```
 24 | Entry -> B1
 25 | B1 -> B2
 26 | B2 -> B3
 27 | B2 -> B4
 28 | B3 -> B4
 29 | B4 -> B2
 30 | B4 -> Exit
 31 | ```
 32 | ```
 33 | B1
 34 | d1 i m
 35 | d2 j n
 36 | d3 a u1
 37 | B2
 38 | d4 i i
 39 | d5 j j
 40 | B3
 41 | d6 a u2
 42 | B4
 43 | d7 i u3
 44 | ```
45 | 46 | ### Sample Output ### 47 | 48 | ``` 49 | === Basic Block Information === 50 | --- Entry --- 51 | --- Exit --- 52 | --- B1 --- 53 | d1 : i , m 54 | d2 : j , n 55 | d3 : a , u1 56 | --- B2 --- 57 | d4 : i , i 58 | d5 : j , j 59 | --- B3 --- 60 | d6 : a , u2 61 | --- B4 --- 62 | d7 : i , u3 63 | === 64 | 65 | === Basic Block Reaching Definition === 66 | --- Entry --- 67 | GEN : 68 | KILL: 69 | IN : 70 | OUT : 71 | --- Exit --- 72 | GEN : 73 | KILL: 74 | IN : d3 d5 d6 d7 75 | OUT : d3 d5 d6 d7 76 | --- B1 --- 77 | GEN : d1 d2 d3 78 | KILL: d4 d5 d6 d7 79 | IN : 80 | OUT : d1 d2 d3 81 | --- B2 --- 82 | GEN : d4 d5 83 | KILL: d1 d2 d7 84 | IN : d1 d2 d3 d5 d6 d7 85 | OUT : d3 d4 d5 d6 86 | --- B3 --- 87 | GEN : d6 88 | KILL: d3 89 | IN : d3 d4 d5 d6 90 | OUT : d4 d5 d6 91 | --- B4 --- 92 | GEN : d7 93 | KILL: d1 d4 94 | IN : d3 d4 d5 d6 95 | OUT : d3 d5 d6 d7 96 | === 97 | ``` 98 | 99 | ### Reference ### 100 | 101 | NTU Department of Computer Science and Information Engineering - Advanced Compiler -------------------------------------------------------------------------------- /Advanced/Dataflow/Liveness/README.md: -------------------------------------------------------------------------------- 1 | ## Liveness ## 2 | 3 | A variable is live out if used by a successor. 4 | 5 | ### Algorithm ### 6 | 7 | ``` 8 | // initialization 9 | IN[exit] = 0 10 | foreach B other than entry 11 | IN[B] = 0 12 | 13 | // iterating until reaching fixed point 14 | While some OUT[B] changes 15 | IN[B] = USE[B] union (OUT[B] - DEF[B]) 16 | OUT[B] = UNION IN[S] where S in Successor(B) 17 | ``` 18 | 19 | ### Example ### 20 | 21 | ![Textbook Example Figure 9.13](images/example.png) 22 | 23 | ### Sample Input ### 24 | 25 |
```
 26 | Entry -> B1
 27 | B1 -> B2
 28 | B2 -> B3
 29 | B2 -> B4
 30 | B3 -> B4
 31 | B4 -> B2
 32 | B4 -> Exit
 33 | ```
 34 | ```
 35 | B1
 36 | d1 i m
 37 | d2 j n
 38 | d3 a u1
 39 | B2
 40 | d4 i i
 41 | d5 j j
 42 | B3
 43 | d6 a u2
 44 | B4
 45 | d7 i u3
 46 | ```
47 | 48 | ### Sample Output ### 49 | 50 | ``` 51 | === Basic Block Information === 52 | --- Entry --- 53 | --- Exit --- 54 | --- B1 --- 55 | d1 : i , m 56 | d2 : j , n 57 | d3 : a , u1 58 | --- B2 --- 59 | d4 : i , i 60 | d5 : j , j 61 | --- B3 --- 62 | d6 : a , u2 63 | --- B4 --- 64 | d7 : i , u3 65 | === 66 | 67 | === Basic Block Liveness === 68 | --- Entry --- 69 | DEF : 70 | USE : 71 | IN : m n u1 u2 u3 72 | OUT : m n u1 u2 u3 73 | --- Exit --- 74 | DEF : 75 | USE : 76 | IN : 77 | OUT : 78 | --- B1 --- 79 | DEF : i j a 80 | USE : m n u1 81 | IN : m n u1 u2 u3 82 | OUT : i j u2 u3 83 | --- B2 --- 84 | DEF : i j 85 | USE : i j 86 | IN : i j u2 u3 87 | OUT : j u2 u3 88 | --- B3 --- 89 | DEF : a 90 | USE : u2 91 | IN : j u2 u3 92 | OUT : j u2 u3 93 | --- B4 --- 94 | DEF : i 95 | USE : u3 96 | IN : j u2 u3 97 | OUT : i j u2 u3 98 | === 99 | ``` 100 | 101 | ### Reference ### 102 | 103 | NTU Department of Computer Science and Information Engineering - Advanced Compiler 104 | -------------------------------------------------------------------------------- /yacc-ACMProblem/UVa11291/a.tab.h: -------------------------------------------------------------------------------- 1 | /* A Bison parser, made by GNU Bison 2.5. */ 2 | 3 | /* Bison interface for Yacc-like parsers in C 4 | 5 | Copyright (C) 1984, 1989-1990, 2000-2011 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 | 34 | /* Tokens. */ 35 | #ifndef YYTOKENTYPE 36 | # define YYTOKENTYPE 37 | /* Put the tokens into the symbol table, so that GDB and other debuggers 38 | know about them. */ 39 | enum yytokentype { 40 | LEFT_P = 258, 41 | RIGHT_P = 259, 42 | NUMBER = 260 43 | }; 44 | #endif 45 | 46 | 47 | 48 | #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED 49 | typedef union YYSTYPE 50 | { 51 | 52 | /* Line 2068 of yacc.c */ 53 | #line 12 "a.y" 54 | 55 | float floatVal; 56 | int intVal; 57 | 58 | 59 | 60 | /* Line 2068 of yacc.c */ 61 | #line 62 "a.tab.h" 62 | } YYSTYPE; 63 | # define YYSTYPE_IS_TRIVIAL 1 64 | # define yystype YYSTYPE /* obsolescent; will be withdrawn */ 65 | # define YYSTYPE_IS_DECLARED 1 66 | #endif 67 | 68 | extern YYSTYPE yylval; 69 | 70 | 71 | -------------------------------------------------------------------------------- /Advanced/LLVM/Simple-DCE-pass/MyDCE/MyDCE.cpp: -------------------------------------------------------------------------------- 1 | #include "llvm/ADT/SmallPtrSet.h" 2 | #include "llvm/ADT/SmallVector.h" 3 | #include "llvm/IR/InstIterator.h" // inst_range 4 | #include "llvm/IR/Instructions.h" // TerminatorInst 5 | using namespace llvm; 6 | 7 | #include "MyDCE.h" 8 | #include 9 | #include 10 | #include 11 | 12 | char MyDCE::ID = 0; 13 | static RegisterPass X("myMagicDCE", "My DCE Pass", false, false); 14 | 15 | #define MDEBUG 16 | 17 | bool MyDCE::runOnFunction(Function &F) { 18 | /** 19 | * Mark-and-Sweep Algorithm 20 | */ 21 | SmallVector Worklist; // use as a stack 22 | SmallPtrSet Marked; 23 | 24 | #ifdef MDEBUG 25 | puts("\t\033[36mFind Critical Instruction\033[0m"); 26 | #endif 27 | 28 | for (Instruction &Inst : inst_range(F)) { 29 | if (Inst.mayHaveSideEffects() || Inst.isTerminator()) { 30 | Worklist.push_back(&Inst); 31 | Marked.insert(&Inst); 32 | 33 | #ifdef MDEBUG 34 | Inst.dump(); 35 | if (Inst.isTerminator()) 36 | puts("\033[1;31m\tTerminatorInst \033[0m\n"); 37 | if (Inst.mayHaveSideEffects()) 38 | puts("\033[1;31m\tmayHaveSideEffects \033[0m\n"); 39 | #endif 40 | } 41 | } 42 | 43 | #ifdef MDEBUG 44 | puts("\t\033[36mFind Dependency Instruction\033[0m"); 45 | #endif 46 | 47 | while (!Worklist.empty()) { 48 | Instruction &Inst = *Worklist.pop_back_val(); 49 | for (auto op = Inst.op_begin(); op != Inst.op_end(); op++) { 50 | if (isa(op->get())) { 51 | Instruction &j = static_cast(*(op->get())); 52 | if (Marked.count(&j) == 0) { 53 | Worklist.push_back(&j); 54 | Marked.insert(&j); 55 | 56 | #ifdef MDEBUG 57 | j.dump(); 58 | #endif 59 | 60 | } 61 | } 62 | } 63 | } 64 | 65 | bool Changed = false; 66 | int EliminateCnt = 0; 67 | 68 | #ifdef MDEBUG 69 | puts("Safe-Remove"); 70 | #endif 71 | 72 | for (Instruction &Inst : inst_range(F)) { 73 | if (Marked.count(&Inst) == 0) { 74 | Inst.dropAllReferences(); 75 | Worklist.push_back(&Inst); 76 | } 77 | } 78 | 79 | #ifdef MDEBUG 80 | puts("DEAD"); 81 | #endif 82 | 83 | for (auto Inst : Worklist) { 84 | 85 | #ifdef MDEBUG 86 | Inst->dump(); 87 | #endif 88 | 89 | Inst->eraseFromParent(); 90 | Changed = true; 91 | EliminateCnt++; 92 | } 93 | 94 | #ifdef MDEBUG 95 | printf("\033[32m\t%s, #EliminateInst %d \033[0m\n", Changed ? "Changed" : "Unchanged", EliminateCnt); 96 | #endif 97 | 98 | return Changed; 99 | } 100 | -------------------------------------------------------------------------------- /Advanced/LLVM/GlobalRegisterAllocation/source/X86RenameRegister.cpp: -------------------------------------------------------------------------------- 1 | //===-------- X86RenameRegister.cpp - rename register ---------------------===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // test 11 | // 12 | //===----------------------------------------------------------------------===// 13 | 14 | #include 15 | 16 | #include "X86.h" 17 | #include "X86InstrInfo.h" 18 | #include "X86Subtarget.h" 19 | #include "llvm/ADT/Statistic.h" 20 | #include "llvm/CodeGen/MachineFunctionPass.h" 21 | #include "llvm/CodeGen/MachineInstrBuilder.h" 22 | #include "llvm/CodeGen/MachineRegisterInfo.h" 23 | #include "llvm/CodeGen/Passes.h" 24 | #include "llvm/IR/Function.h" 25 | #include "llvm/Support/Debug.h" 26 | #include "llvm/Support/raw_ostream.h" 27 | #include "llvm/Target/TargetInstrInfo.h" 28 | 29 | using namespace llvm; 30 | 31 | #define DEBUG_TYPE "x86-rename-register" 32 | 33 | STATISTIC(RenameRegister, "x86 rename register"); 34 | 35 | namespace { 36 | 37 | struct RenameReg : public MachineFunctionPass { 38 | static char ID; 39 | RenameReg() : MachineFunctionPass(ID) {} 40 | 41 | bool runOnMachineFunction(MachineFunction &MF) override; 42 | 43 | const char *getPassName() const override { 44 | return "X86 Rename Register"; 45 | } 46 | 47 | private: 48 | }; 49 | 50 | char RenameReg::ID = 0; 51 | } 52 | 53 | FunctionPass *llvm::createX86RenameRegister() { 54 | return new RenameReg(); 55 | } 56 | 57 | bool RenameReg::runOnMachineFunction(MachineFunction &MF) { 58 | for (auto &MBB: MF) { 59 | for (auto &MI: MBB) { 60 | for (auto &MO: MI.operands()) { 61 | if (!MO.isReg()) 62 | continue; 63 | unsigned r = MO.getReg(); 64 | switch (r) { 65 | case X86::RDX: 66 | MO.setReg(X86::RBX); break; 67 | case X86::RBX: 68 | MO.setReg(X86::RDX); break; 69 | case X86::EDX: 70 | MO.setReg(X86::EBX); break; 71 | case X86::EBX: 72 | MO.setReg(X86::EDX); break; 73 | case X86::DX: 74 | MO.setReg(X86::BX); break; 75 | case X86::BX: 76 | MO.setReg(X86::DX); break; 77 | case X86::DH: 78 | MO.setReg(X86::BH); break; 79 | case X86::BH: 80 | MO.setReg(X86::DH); break; 81 | case X86::DL: 82 | MO.setReg(X86::BL); break; 83 | case X86::BL: 84 | MO.setReg(X86::DL); break; 85 | 86 | } 87 | } 88 | } 89 | } 90 | return true; 91 | } 92 | -------------------------------------------------------------------------------- /Advanced/LLVM/GlobalRegisterAllocation/patch/patch: -------------------------------------------------------------------------------- 1 | diff --git a/.gitignore b/.gitignore 2 | index c64b5c2..7a3ebab 100644 3 | --- a/.gitignore 4 | +++ b/.gitignore 5 | @@ -7,6 +7,7 @@ 6 | #==============================================================================# 7 | 8 | build 9 | +tags 10 | 11 | #==============================================================================# 12 | # File extensions to be ignored anywhere in the tree. 13 | diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp 14 | index 939c500..91fc89d 100644 15 | --- a/lib/CodeGen/PrologEpilogInserter.cpp 16 | +++ b/lib/CodeGen/PrologEpilogInserter.cpp 17 | @@ -182,6 +182,13 @@ bool PEI::runOnMachineFunction(MachineFunction &Fn) { 18 | BitVector SavedRegs; 19 | TFI->determineCalleeSaves(Fn, SavedRegs, RS); 20 | 21 | + dbgs() << F->getName() << ":"; 22 | + for (int i = 0; i < SavedRegs.size(); i++) { 23 | + if (SavedRegs.test(i)) 24 | + dbgs() << " " << i; 25 | + } 26 | + dbgs() << "\n"; 27 | + 28 | // Insert spill code for any callee saved registers that are modified. 29 | assignCalleeSavedSpillSlots(Fn, SavedRegs); 30 | 31 | diff --git a/lib/Target/X86/CMakeLists.txt b/lib/Target/X86/CMakeLists.txt 32 | index 5594915..1f1ec22 100644 33 | --- a/lib/Target/X86/CMakeLists.txt 34 | +++ b/lib/Target/X86/CMakeLists.txt 35 | @@ -13,6 +13,7 @@ tablegen(LLVM X86GenSubtargetInfo.inc -gen-subtarget) 36 | add_public_tablegen_target(X86CommonTableGen) 37 | 38 | set(sources 39 | + X86RenameRegister.cpp 40 | X86AsmPrinter.cpp 41 | X86CallFrameOptimization.cpp 42 | X86ExpandPseudo.cpp 43 | diff --git a/lib/Target/X86/X86.h b/lib/Target/X86/X86.h 44 | index 01e65b8..06c74d8 100644 45 | --- a/lib/Target/X86/X86.h 46 | +++ b/lib/Target/X86/X86.h 47 | @@ -23,6 +23,8 @@ class FunctionPass; 48 | class ImmutablePass; 49 | class X86TargetMachine; 50 | 51 | +FunctionPass *createX86RenameRegister(); 52 | + 53 | /// This pass converts a legalized DAG into a X86-specific DAG, ready for 54 | /// instruction scheduling. 55 | FunctionPass *createX86ISelDag(X86TargetMachine &TM, 56 | diff --git a/lib/Target/X86/X86CallingConv.td b/lib/Target/X86/X86CallingConv.td 57 | index ed2e880..a902c76 100644 58 | --- a/lib/Target/X86/X86CallingConv.td 59 | +++ b/lib/Target/X86/X86CallingConv.td 60 | @@ -817,7 +817,8 @@ def CC_X86 : CallingConv<[ 61 | def CSR_NoRegs : CalleeSavedRegs<(add)>; 62 | 63 | def CSR_32 : CalleeSavedRegs<(add ESI, EDI, EBX, EBP)>; 64 | -def CSR_64 : CalleeSavedRegs<(add RBX, R12, R13, R14, R15, RBP)>; 65 | +def CSR_64 : CalleeSavedRegs<(add RBX, R12, R13, R14, R15, RBP, 66 | + RCX, RDX, RDI, RSI, R8, R9, R10, R11)>; 67 | 68 | def CSR_32EHRet : CalleeSavedRegs<(add EAX, EDX, CSR_32)>; 69 | def CSR_64EHRet : CalleeSavedRegs<(add RAX, RDX, CSR_64)>; 70 | diff --git a/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp 71 | index 0e7e4c0..5f2e407 100644 72 | --- a/lib/Target/X86/X86TargetMachine.cpp 73 | +++ b/lib/Target/X86/X86TargetMachine.cpp 74 | @@ -277,4 +277,6 @@ void X86PassConfig::addPreEmitPass() { 75 | addPass(createX86PadShortFunctions()); 76 | addPass(createX86FixupLEAs()); 77 | } 78 | + 79 | + addPass(createX86RenameRegister()); 80 | } 81 | -------------------------------------------------------------------------------- /hw1-NFA2DFA/runDFA.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | using namespace std; 11 | class State { 12 | public: 13 | State(int ac=0) { 14 | accepted = ac; 15 | } 16 | bool accepted; 17 | int nameLabel; 18 | map > trans; 19 | }; 20 | class DFA { 21 | public: 22 | State* Q0; 23 | vector Q, F; 24 | int runDFA(const char s[]); 25 | }; 26 | int DFA::runDFA(const char s[]) { 27 | State *p; 28 | p = Q0; 29 | for(int i = 0; s[i]; i++) { 30 | if(p->trans.find(s[i]) == p->trans.end()) 31 | return 0; 32 | p = p->trans[s[i]][0]; 33 | } 34 | return p->accepted; 35 | } 36 | vector parsingAlphabetSet(char s[]) { 37 | #define isValidAlpha(x) ((x) != ',' && (x) != '(' && (x) != ')' && !((x) >= '0' && (x) <= '9')) 38 | for(int i = 0; s[i]; i++) { 39 | if(!isValidAlpha(s[i])) 40 | s[i] = ' '; 41 | } 42 | vector ret; 43 | stringstream sin(s); 44 | string token; 45 | while(sin >> token) 46 | ret.push_back(token[0]); 47 | return ret; 48 | } 49 | int parsingStateTrans(char s[], int column, vector< vector< string > > &table) { 50 | for(int i = 0; s[i]; i++) { 51 | if(s[i] == '(' || s[i] == ')') 52 | s[i] = ' '; 53 | } 54 | stringstream sin(s); 55 | vector< string > R; 56 | for(int i = 0; i < column + 1; i++) { 57 | string token; 58 | sin >> token; 59 | R.push_back(token); 60 | } 61 | table.push_back(R); 62 | int ac = 0; 63 | for(int i = 0; i < R[0].length(); i++) 64 | if(R[0][i] == '*') 65 | ac = 1; 66 | return ac; 67 | } 68 | int main() { 69 | freopen("DFAjudge.txt", "r+t", stdin); 70 | freopen("DFAresult.txt", "w+t", stdout); 71 | DFA dfa; 72 | char s[1024]; 73 | gets(s); 74 | vector alpha = parsingAlphabetSet(s); 75 | 76 | int state_count = 0; 77 | vector< vector< string > > table; 78 | vector hasStar; 79 | while(gets(s)) { 80 | if(s[0] != '(') break; 81 | int ac = parsingStateTrans(s, alpha.size(), table); 82 | hasStar.push_back(ac); 83 | state_count++; 84 | } 85 | for(int i = 0; i < state_count; i++) { 86 | dfa.Q.push_back(new State(hasStar[i])); 87 | dfa.Q[i]->nameLabel = i; 88 | if(hasStar[i]) dfa.F.push_back(dfa.Q[i]); 89 | } 90 | dfa.Q0 = dfa.Q[0]; 91 | int i = 0; 92 | for(vector< vector< string > >::iterator it = table.begin(); 93 | it != table.end(); it++, i++) { 94 | string start = table[i][0]; 95 | for(int j = 1; j <= alpha.size(); j++) { 96 | string end = table[i][j]; 97 | for(int k = 0; k < table.size(); k++) { 98 | if(table[k][0] == end) 99 | dfa.Q[i]->trans[alpha[j-1]].push_back(dfa.Q[k]); 100 | } 101 | } 102 | } 103 | puts(dfa.runDFA(s) ? "valid" : "error"); 104 | return 0; 105 | } 106 | /* 107 | Sample Input: 108 | (a,b) 109 | (1,2)(*3,4,5)(0) 110 | (*3,4,5)(*5)(*4,5) 111 | (*5)(0)(0) 112 | (*4,5)(*5)(*5) 113 | abbbb 114 | 115 | (a,b) 116 | (1,2)(*3,4,5)(0) 117 | (*3,4,5)(*5)(*4,5) 118 | (*5)(0)(0) 119 | (*4,5)(*5)(*5) 120 | ab 121 | 122 | (a,b) 123 | (1,2,3)(*1,2,3,4)(*2,3,4) 124 | (*1,2,3,4)(*1,2,3,4)(*2,3,4) 125 | (*2,3,4)(*1,2,3,4)(*2,3,4) 126 | a 127 | ------------------ 128 | Sample Output: 129 | error 130 | valid 131 | valid 132 | */ 133 | -------------------------------------------------------------------------------- /Advanced/LLVM/GlobalRegisterAllocation/source/lib/Target/X86/X86.h: -------------------------------------------------------------------------------- 1 | //===-- X86.h - Top-level interface for X86 representation ------*- C++ -*-===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // This file contains the entry points for global functions defined in the x86 11 | // target library, as used by the LLVM JIT. 12 | // 13 | //===----------------------------------------------------------------------===// 14 | 15 | #ifndef LLVM_LIB_TARGET_X86_X86_H 16 | #define LLVM_LIB_TARGET_X86_X86_H 17 | 18 | #include "llvm/Support/CodeGen.h" 19 | #include "llvm/Pass.h" 20 | 21 | namespace llvm { 22 | 23 | class FunctionPass; 24 | class ImmutablePass; 25 | class X86TargetMachine; 26 | 27 | FunctionPass *createX86TestPass(); 28 | ModulePass *createX86TestPass2(); 29 | ModulePass *createMyTestPass2(); 30 | 31 | /// This pass converts a legalized DAG into a X86-specific DAG, ready for 32 | /// instruction scheduling. 33 | FunctionPass *createX86ISelDag(X86TargetMachine &TM, 34 | CodeGenOpt::Level OptLevel); 35 | 36 | /// This pass initializes a global base register for PIC on x86-32. 37 | FunctionPass *createX86GlobalBaseRegPass(); 38 | 39 | /// This pass combines multiple accesses to local-dynamic TLS variables so that 40 | /// the TLS base address for the module is only fetched once per execution path 41 | /// through the function. 42 | FunctionPass *createCleanupLocalDynamicTLSPass(); 43 | 44 | /// This function returns a pass which converts floating-point register 45 | /// references and pseudo instructions into floating-point stack references and 46 | /// physical instructions. 47 | FunctionPass *createX86FloatingPointStackifierPass(); 48 | 49 | /// This pass inserts AVX vzeroupper instructions before each call to avoid 50 | /// transition penalty between functions encoded with AVX and SSE. 51 | FunctionPass *createX86IssueVZeroUpperPass(); 52 | 53 | /// Return a pass that pads short functions with NOOPs. 54 | /// This will prevent a stall when returning on the Atom. 55 | FunctionPass *createX86PadShortFunctions(); 56 | 57 | /// Return a pass that selectively replaces certain instructions (like add, 58 | /// sub, inc, dec, some shifts, and some multiplies) by equivalent LEA 59 | /// instructions, in order to eliminate execution delays in some processors. 60 | FunctionPass *createX86FixupLEAs(); 61 | 62 | /// Return a pass that removes redundant LEA instructions and redundant address 63 | /// recalculations. 64 | FunctionPass *createX86OptimizeLEAs(); 65 | 66 | /// Return a pass that optimizes the code-size of x86 call sequences. This is 67 | /// done by replacing esp-relative movs with pushes. 68 | FunctionPass *createX86CallFrameOptimization(); 69 | 70 | /// Return an IR pass that inserts EH registration stack objects and explicit 71 | /// EH state updates. This pass must run after EH preparation, which does 72 | /// Windows-specific but architecture-neutral preparation. 73 | FunctionPass *createX86WinEHStatePass(); 74 | 75 | /// Return a Machine IR pass that expands X86-specific pseudo 76 | /// instructions into a sequence of actual instructions. This pass 77 | /// must run after prologue/epilogue insertion and before lowering 78 | /// the MachineInstr to MC. 79 | FunctionPass *createX86ExpandPseudoPass(); 80 | } // End llvm namespace 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /LL(1)-ACMProblem/README.md: -------------------------------------------------------------------------------- 1 | ## Problem ## 2 | 3 | Loglan is a synthetic speakable language designed to test some of the fundamental problems of linguistics, such as the Sapir Whorf hypothesis. It is syntactically unambiguous, culturally neutral and metaphysically parsimonious. What follows is a gross over-simplification of an already very small grammar of some 200 rules. 4 | 5 | Loglan sentences consist of a series of words and names, separated by spaces, and are terminated by a period (.). Loglan words all end with a vowel; names, which are derived extra-linguistically, end with a consonant. Loglan words are divided into two classes--little words which specify the structure of a sentence, and predicates which have the form CCVCV or CVCCV where C represents a consonant and V represents a vowel (see examples later). 6 | 7 | The subset of Loglan that we are considering uses the following grammar: 8 | 9 | ``` 10 | A → a | e | i | o | u 11 | MOD → ga | ge | gi | go | gu 12 | BA → ba | be | bi | bo | bu 13 | DA → da | de | di | do | du 14 | LA → la | le | li | lo | lu 15 | NAM → {all names} 16 | PREDA → {all predicates} 17 | | 18 | BA | DA 19 | | A 20 | → LA | NAM 21 | → PREDA | PREDA 22 | | 23 | → MOD 24 | ``` 25 | Write a program that will read a succession of strings and determine whether or not they are correctly formed Loglan sentences. 26 | 27 | ## Input and Output ## 28 | 29 | Each Loglan sentence will start on a new line and will be terminated by a period (.). The sentence may occupy more than one line and words may be separated by more than one whitespace character. The input will be terminated by a line containing a single `#'. You can assume that all words will be correctly formed. 30 | 31 | Output will consist of one line for each sentence containing either `Good' or `Bad!'. 32 | 33 | ## Sample input ## 34 | ``` 35 | la mutce bunbo mrenu bi ditca. 36 | la fumna bi le mrenu. 37 | djan ga vedma le negro ketpi. 38 | # 39 | ``` 40 | 41 | ## Sample output ## 42 | ``` 43 | Good 44 | Bad! 45 | Good 46 | ``` 47 | ## Solution ## 48 | 49 | 其實這一題有比較好的解法,但是在正在學編譯器,因此把 LL(1) parser 運用在此題 50 | ,所以代碼會稍微長一點。 51 | 52 | ``` 53 | -> 54 | -> DA 55 | -> 56 | -> 57 | -> 58 | -> BA 59 | -> 60 | -> 61 | -> A 62 | -> l 63 | -> LA 64 | -> NAM 65 | -> PREDA 66 | -> PREDA 67 | -> l 68 | -> 69 | -> 70 | -> l 71 | -> MOD 72 | ``` 73 | 74 | 為了要符合 LL(1) 的形式,要想辦法將 Grammar 符合規格,也就是每一條 production rule 的 predict set 不會有模稜兩個的情況,也就是說當我看到某個 non-terminal 在 stack 上,在去看下一個 token,然後可以對於 (non-terminal, token) 只找到一條規則去匹配。 75 | 76 | predict set 是根據每一條 production rule 所產生的,也就是說這個推論可以產生的第一個 token 是什麼,假使有相同的前綴時,則必須拉出做調整。// 因為這將會造成模稜兩可的情況。 77 | 78 | 遇到 79 | ``` 80 | A -> BCx 81 | A -> BCy 82 | ``` 83 | 應調整成 84 | ``` 85 | A -> BCW 86 | W -> x 87 | W -> y 88 | ``` 89 | 90 | 在 parsing 問題上,應避免替換的無限迴圈。 91 | 遇到 92 | ``` 93 | A -> AC 94 | A -> X 95 | A -> Y 96 | ``` 97 | 應調整成 98 | ``` 99 | A -> WD 100 | D -> CD 101 | D -> lambda 102 | W -> X 103 | W -> Y 104 | ``` 105 | 106 | 發現對照課本的 parsing function 撰寫起來才發現有些不完善的地方,對於 `lldriver()` 會沒有辦法應對輸入結束,要吐出 lambda 的問題。 107 | -------------------------------------------------------------------------------- /hw2-CFG-FirstSet/CFG_FirstSet.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | class Production { 10 | public: 11 | string LHS; 12 | vector RHS; 13 | Production(string L = "", vector R = vector()) { 14 | LHS = L; 15 | RHS = R; 16 | } 17 | }; 18 | class Grammar { 19 | public: 20 | static const string lambda; 21 | vector rules; 22 | map > first_set; 23 | map derives_lambda; 24 | 25 | map mark_lambda(); 26 | void fill_first_set(); 27 | bool isNonterminal(string token); 28 | set compute_first(vector rhs); 29 | }; 30 | const string Grammar::lambda("l"); 31 | set Grammar::compute_first(vector rhs) { 32 | set result; 33 | size_t i; 34 | 35 | if(rhs.size() == 0 || rhs[0] == Grammar::lambda) { 36 | result.insert(Grammar::lambda); 37 | } else { 38 | result = first_set[rhs[0]]; 39 | for(i = 1; i < rhs.size() && 40 | first_set[rhs[i-1]].find(Grammar::lambda) != first_set[rhs[i-1]].end(); i++) { 41 | set f = first_set[rhs[i]]; 42 | f.erase(Grammar::lambda); 43 | result.insert(f.begin(), f.end()); 44 | } 45 | if(i == rhs.size() 46 | && first_set[rhs[i-1]].find(Grammar::lambda) != first_set[rhs[i-1]].end()) { 47 | result.insert(Grammar::lambda); 48 | } else { 49 | result.erase(Grammar::lambda); 50 | } 51 | } 52 | 53 | return result; 54 | } 55 | bool Grammar::isNonterminal(string token) { 56 | if(token == Grammar::lambda) 57 | return false; 58 | for(size_t i = 0; i < token.length(); i++) { 59 | if(isupper(token[i])) 60 | return false; 61 | } 62 | return true; 63 | } 64 | map Grammar::mark_lambda() { 65 | bool rhs_derives_lambda; 66 | bool changes; 67 | Production p; 68 | 69 | derives_lambda.clear(); 70 | 71 | /* initially, nothing is marked. */ 72 | for(size_t i = 0; i < rules.size(); i++) { 73 | derives_lambda[rules[i].LHS] = false; 74 | } 75 | do { 76 | changes = false; 77 | for(size_t i = 0; i < rules.size(); i++) { 78 | p = rules[i]; 79 | if(!derives_lambda[p.LHS]) { 80 | if(p.RHS.size() == 0 || p.RHS[0] == Grammar::lambda) { 81 | changes = derives_lambda[p.LHS] = true; 82 | continue; 83 | } 84 | /* does each part of RHS derive lambda ? */ 85 | rhs_derives_lambda = derives_lambda[string(p.RHS[0])]; 86 | for(size_t j = 1; j < p.RHS.size(); j++) { 87 | rhs_derives_lambda &= derives_lambda[p.RHS[j]]; 88 | } 89 | if(rhs_derives_lambda) { 90 | changes = true; 91 | derives_lambda[p.LHS] = true; 92 | } 93 | } 94 | } 95 | } while(changes); 96 | return derives_lambda; 97 | } 98 | void Grammar::fill_first_set() { 99 | 100 | string A; 101 | string a; 102 | Production p; 103 | bool changes; 104 | 105 | mark_lambda(); 106 | first_set.clear(); 107 | 108 | for(size_t i = 0; i < rules.size(); i++) { 109 | A = rules[i].LHS; 110 | if(derives_lambda[A]) 111 | first_set[A].insert(Grammar::lambda); 112 | } 113 | 114 | for(size_t i = 0; i < rules.size(); i++) { 115 | for(size_t j = 0; j < rules[i].RHS.size(); j++) { 116 | a = rules[i].RHS[j]; 117 | if(isNonterminal(a)) { 118 | first_set[a].insert(a); 119 | if(j == 0) { // A -> aXX 120 | first_set[rules[i].LHS].insert(a); 121 | } 122 | } 123 | } 124 | } 125 | 126 | do { 127 | changes = false; 128 | for(size_t i = 0; i < rules.size(); i++) { 129 | p = rules[i]; 130 | set rfirst = compute_first(p.RHS); 131 | size_t oldsize = first_set[p.LHS].size(); 132 | first_set[p.LHS].insert(rfirst.begin(), rfirst.end()); 133 | size_t newsize = first_set[p.LHS].size(); 134 | if(oldsize != newsize) 135 | changes = true; 136 | } 137 | } while(changes); 138 | } 139 | void parsingProduction(string r, Grammar &g) { 140 | string div("->"); 141 | size_t found = r.find(div); 142 | if(found != std::string::npos) { 143 | string rhs = r.substr(found + div.length()); 144 | vector tokens; 145 | for(size_t i = 0; i < rhs.size(); i++) 146 | tokens.push_back(rhs.substr(i, 1)); 147 | Production p(r.substr(0, found), tokens); 148 | g.rules.push_back(p); 149 | } 150 | } 151 | int main() { 152 | freopen("input.txt", "r+t", stdin); 153 | freopen("output.txt", "w+t", stdout); 154 | char in[1024]; 155 | while(gets(in)) { 156 | Grammar g; 157 | parsingProduction(in, g); 158 | while(gets(in) && in[0] != '\0') { 159 | parsingProduction(in, g); 160 | } 161 | 162 | g.fill_first_set(); 163 | 164 | for(map >::iterator it = g.first_set.begin(); 165 | it != g.first_set.end(); it++) { 166 | cout << it->first << ":"; 167 | bool comma = false; 168 | for(set::iterator jt = it->second.begin(); 169 | jt != it->second.end(); jt++) { 170 | if(comma == true) cout << ","; 171 | comma = true; 172 | cout << *jt; 173 | } 174 | cout << endl; 175 | } 176 | } 177 | return 0; 178 | } 179 | /* 180 | A->BaAb 181 | A->cC 182 | B->d 183 | B->l 184 | C->eA 185 | C->l 186 | 187 | A->aAd 188 | A->B 189 | B->bBd 190 | B->C 191 | C->cCd 192 | C->l 193 | 194 | E->TX 195 | X->+E 196 | X-># 197 | T->(E) 198 | T->intY 199 | Y->*T 200 | Y-># 201 | 202 | E->P(E) 203 | E->vT 204 | P->f 205 | P->l 206 | T->+E 207 | T->l 208 | 209 | S->aSe 210 | S->B 211 | B->bBe 212 | B->C 213 | C->cCe 214 | C->d 215 | 216 | S->ABc 217 | A->a 218 | A->l 219 | B->b 220 | B->l 221 | 222 | */ 223 | -------------------------------------------------------------------------------- /Advanced/LLVM/Simple-CSE-pass/MyCSE/Makefile: -------------------------------------------------------------------------------- 1 | # CMAKE generated file: DO NOT EDIT! 2 | # Generated by "Unix Makefiles" Generator, CMake Version 3.2 3 | 4 | # Default target executed when no arguments are given to make. 5 | default_target: all 6 | .PHONY : default_target 7 | 8 | # Allow only one "make -f Makefile2" at a time, but pass parallelism. 9 | .NOTPARALLEL: 10 | 11 | #============================================================================= 12 | # Special targets provided by cmake. 13 | 14 | # Disable implicit rules so canonical targets will work. 15 | .SUFFIXES: 16 | 17 | # Remove some rules from gmake that .SUFFIXES does not remove. 18 | SUFFIXES = 19 | 20 | .SUFFIXES: .hpux_make_needs_suffix_list 21 | 22 | # Suppress display of executed commands. 23 | $(VERBOSE).SILENT: 24 | 25 | # A target that is always out of date. 26 | cmake_force: 27 | .PHONY : cmake_force 28 | 29 | #============================================================================= 30 | # Set environment variables for the build. 31 | 32 | # The shell in which to execute make rules. 33 | SHELL = /bin/sh 34 | 35 | # The CMake executable. 36 | CMAKE_COMMAND = /usr/bin/cmake 37 | 38 | # The command to remove a file. 39 | RM = /usr/bin/cmake -E remove -f 40 | 41 | # Escaping for special characters. 42 | EQUALS = = 43 | 44 | # The top-level source directory on which CMake was run. 45 | CMAKE_SOURCE_DIR = /home/morris1028/LLVM/hw1 46 | 47 | # The top-level build directory on which CMake was run. 48 | CMAKE_BINARY_DIR = /home/morris1028/LLVM/hw1 49 | 50 | #============================================================================= 51 | # Targets provided globally by CMake. 52 | 53 | # Special rule for the target edit_cache 54 | edit_cache: 55 | @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "No interactive CMake dialog available..." 56 | /usr/bin/cmake -E echo No\ interactive\ CMake\ dialog\ available. 57 | .PHONY : edit_cache 58 | 59 | # Special rule for the target edit_cache 60 | edit_cache/fast: edit_cache 61 | .PHONY : edit_cache/fast 62 | 63 | # Special rule for the target rebuild_cache 64 | rebuild_cache: 65 | @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..." 66 | /usr/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) 67 | .PHONY : rebuild_cache 68 | 69 | # Special rule for the target rebuild_cache 70 | rebuild_cache/fast: rebuild_cache 71 | .PHONY : rebuild_cache/fast 72 | 73 | # The main all target 74 | all: cmake_check_build_system 75 | cd /home/morris1028/LLVM/hw1 && $(CMAKE_COMMAND) -E cmake_progress_start /home/morris1028/LLVM/hw1/CMakeFiles /home/morris1028/LLVM/hw1/MyDCE/CMakeFiles/progress.marks 76 | cd /home/morris1028/LLVM/hw1 && $(MAKE) -f CMakeFiles/Makefile2 MyDCE/all 77 | $(CMAKE_COMMAND) -E cmake_progress_start /home/morris1028/LLVM/hw1/CMakeFiles 0 78 | .PHONY : all 79 | 80 | # The main clean target 81 | clean: 82 | cd /home/morris1028/LLVM/hw1 && $(MAKE) -f CMakeFiles/Makefile2 MyDCE/clean 83 | .PHONY : clean 84 | 85 | # The main clean target 86 | clean/fast: clean 87 | .PHONY : clean/fast 88 | 89 | # Prepare targets for installation. 90 | preinstall: all 91 | cd /home/morris1028/LLVM/hw1 && $(MAKE) -f CMakeFiles/Makefile2 MyDCE/preinstall 92 | .PHONY : preinstall 93 | 94 | # Prepare targets for installation. 95 | preinstall/fast: 96 | cd /home/morris1028/LLVM/hw1 && $(MAKE) -f CMakeFiles/Makefile2 MyDCE/preinstall 97 | .PHONY : preinstall/fast 98 | 99 | # clear depends 100 | depend: 101 | cd /home/morris1028/LLVM/hw1 && $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1 102 | .PHONY : depend 103 | 104 | # Convenience name for target. 105 | MyDCE/CMakeFiles/MyDCE.dir/rule: 106 | cd /home/morris1028/LLVM/hw1 && $(MAKE) -f CMakeFiles/Makefile2 MyDCE/CMakeFiles/MyDCE.dir/rule 107 | .PHONY : MyDCE/CMakeFiles/MyDCE.dir/rule 108 | 109 | # Convenience name for target. 110 | MyDCE: MyDCE/CMakeFiles/MyDCE.dir/rule 111 | .PHONY : MyDCE 112 | 113 | # fast build rule for target. 114 | MyDCE/fast: 115 | cd /home/morris1028/LLVM/hw1 && $(MAKE) -f MyDCE/CMakeFiles/MyDCE.dir/build.make MyDCE/CMakeFiles/MyDCE.dir/build 116 | .PHONY : MyDCE/fast 117 | 118 | MyDCE.o: MyDCE.cpp.o 119 | .PHONY : MyDCE.o 120 | 121 | # target to build an object file 122 | MyDCE.cpp.o: 123 | cd /home/morris1028/LLVM/hw1 && $(MAKE) -f MyDCE/CMakeFiles/MyDCE.dir/build.make MyDCE/CMakeFiles/MyDCE.dir/MyDCE.cpp.o 124 | .PHONY : MyDCE.cpp.o 125 | 126 | MyDCE.i: MyDCE.cpp.i 127 | .PHONY : MyDCE.i 128 | 129 | # target to preprocess a source file 130 | MyDCE.cpp.i: 131 | cd /home/morris1028/LLVM/hw1 && $(MAKE) -f MyDCE/CMakeFiles/MyDCE.dir/build.make MyDCE/CMakeFiles/MyDCE.dir/MyDCE.cpp.i 132 | .PHONY : MyDCE.cpp.i 133 | 134 | MyDCE.s: MyDCE.cpp.s 135 | .PHONY : MyDCE.s 136 | 137 | # target to generate assembly for a file 138 | MyDCE.cpp.s: 139 | cd /home/morris1028/LLVM/hw1 && $(MAKE) -f MyDCE/CMakeFiles/MyDCE.dir/build.make MyDCE/CMakeFiles/MyDCE.dir/MyDCE.cpp.s 140 | .PHONY : MyDCE.cpp.s 141 | 142 | # Help Target 143 | help: 144 | @echo "The following are some of the valid targets for this Makefile:" 145 | @echo "... all (the default if no target is provided)" 146 | @echo "... clean" 147 | @echo "... depend" 148 | @echo "... edit_cache" 149 | @echo "... rebuild_cache" 150 | @echo "... MyDCE" 151 | @echo "... MyDCE.o" 152 | @echo "... MyDCE.i" 153 | @echo "... MyDCE.s" 154 | .PHONY : help 155 | 156 | 157 | 158 | #============================================================================= 159 | # Special targets to cleanup operation of make. 160 | 161 | # Special rule to run CMake to check the build system integrity. 162 | # No rule that depends on this can have commands that come from listfiles 163 | # because they might be regenerated. 164 | cmake_check_build_system: 165 | cd /home/morris1028/LLVM/hw1 && $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 166 | .PHONY : cmake_check_build_system 167 | 168 | -------------------------------------------------------------------------------- /Advanced/LLVM/Simple-DCE-pass/MyDCE/Makefile: -------------------------------------------------------------------------------- 1 | # CMAKE generated file: DO NOT EDIT! 2 | # Generated by "Unix Makefiles" Generator, CMake Version 3.2 3 | 4 | # Default target executed when no arguments are given to make. 5 | default_target: all 6 | .PHONY : default_target 7 | 8 | # Allow only one "make -f Makefile2" at a time, but pass parallelism. 9 | .NOTPARALLEL: 10 | 11 | #============================================================================= 12 | # Special targets provided by cmake. 13 | 14 | # Disable implicit rules so canonical targets will work. 15 | .SUFFIXES: 16 | 17 | # Remove some rules from gmake that .SUFFIXES does not remove. 18 | SUFFIXES = 19 | 20 | .SUFFIXES: .hpux_make_needs_suffix_list 21 | 22 | # Suppress display of executed commands. 23 | $(VERBOSE).SILENT: 24 | 25 | # A target that is always out of date. 26 | cmake_force: 27 | .PHONY : cmake_force 28 | 29 | #============================================================================= 30 | # Set environment variables for the build. 31 | 32 | # The shell in which to execute make rules. 33 | SHELL = /bin/sh 34 | 35 | # The CMake executable. 36 | CMAKE_COMMAND = /usr/bin/cmake 37 | 38 | # The command to remove a file. 39 | RM = /usr/bin/cmake -E remove -f 40 | 41 | # Escaping for special characters. 42 | EQUALS = = 43 | 44 | # The top-level source directory on which CMake was run. 45 | CMAKE_SOURCE_DIR = /home/morris1028/LLVM/hw1 46 | 47 | # The top-level build directory on which CMake was run. 48 | CMAKE_BINARY_DIR = /home/morris1028/LLVM/hw1 49 | 50 | #============================================================================= 51 | # Targets provided globally by CMake. 52 | 53 | # Special rule for the target edit_cache 54 | edit_cache: 55 | @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "No interactive CMake dialog available..." 56 | /usr/bin/cmake -E echo No\ interactive\ CMake\ dialog\ available. 57 | .PHONY : edit_cache 58 | 59 | # Special rule for the target edit_cache 60 | edit_cache/fast: edit_cache 61 | .PHONY : edit_cache/fast 62 | 63 | # Special rule for the target rebuild_cache 64 | rebuild_cache: 65 | @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..." 66 | /usr/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) 67 | .PHONY : rebuild_cache 68 | 69 | # Special rule for the target rebuild_cache 70 | rebuild_cache/fast: rebuild_cache 71 | .PHONY : rebuild_cache/fast 72 | 73 | # The main all target 74 | all: cmake_check_build_system 75 | cd /home/morris1028/LLVM/hw1 && $(CMAKE_COMMAND) -E cmake_progress_start /home/morris1028/LLVM/hw1/CMakeFiles /home/morris1028/LLVM/hw1/MyDCE/CMakeFiles/progress.marks 76 | cd /home/morris1028/LLVM/hw1 && $(MAKE) -f CMakeFiles/Makefile2 MyDCE/all 77 | $(CMAKE_COMMAND) -E cmake_progress_start /home/morris1028/LLVM/hw1/CMakeFiles 0 78 | .PHONY : all 79 | 80 | # The main clean target 81 | clean: 82 | cd /home/morris1028/LLVM/hw1 && $(MAKE) -f CMakeFiles/Makefile2 MyDCE/clean 83 | .PHONY : clean 84 | 85 | # The main clean target 86 | clean/fast: clean 87 | .PHONY : clean/fast 88 | 89 | # Prepare targets for installation. 90 | preinstall: all 91 | cd /home/morris1028/LLVM/hw1 && $(MAKE) -f CMakeFiles/Makefile2 MyDCE/preinstall 92 | .PHONY : preinstall 93 | 94 | # Prepare targets for installation. 95 | preinstall/fast: 96 | cd /home/morris1028/LLVM/hw1 && $(MAKE) -f CMakeFiles/Makefile2 MyDCE/preinstall 97 | .PHONY : preinstall/fast 98 | 99 | # clear depends 100 | depend: 101 | cd /home/morris1028/LLVM/hw1 && $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1 102 | .PHONY : depend 103 | 104 | # Convenience name for target. 105 | MyDCE/CMakeFiles/MyDCE.dir/rule: 106 | cd /home/morris1028/LLVM/hw1 && $(MAKE) -f CMakeFiles/Makefile2 MyDCE/CMakeFiles/MyDCE.dir/rule 107 | .PHONY : MyDCE/CMakeFiles/MyDCE.dir/rule 108 | 109 | # Convenience name for target. 110 | MyDCE: MyDCE/CMakeFiles/MyDCE.dir/rule 111 | .PHONY : MyDCE 112 | 113 | # fast build rule for target. 114 | MyDCE/fast: 115 | cd /home/morris1028/LLVM/hw1 && $(MAKE) -f MyDCE/CMakeFiles/MyDCE.dir/build.make MyDCE/CMakeFiles/MyDCE.dir/build 116 | .PHONY : MyDCE/fast 117 | 118 | MyDCE.o: MyDCE.cpp.o 119 | .PHONY : MyDCE.o 120 | 121 | # target to build an object file 122 | MyDCE.cpp.o: 123 | cd /home/morris1028/LLVM/hw1 && $(MAKE) -f MyDCE/CMakeFiles/MyDCE.dir/build.make MyDCE/CMakeFiles/MyDCE.dir/MyDCE.cpp.o 124 | .PHONY : MyDCE.cpp.o 125 | 126 | MyDCE.i: MyDCE.cpp.i 127 | .PHONY : MyDCE.i 128 | 129 | # target to preprocess a source file 130 | MyDCE.cpp.i: 131 | cd /home/morris1028/LLVM/hw1 && $(MAKE) -f MyDCE/CMakeFiles/MyDCE.dir/build.make MyDCE/CMakeFiles/MyDCE.dir/MyDCE.cpp.i 132 | .PHONY : MyDCE.cpp.i 133 | 134 | MyDCE.s: MyDCE.cpp.s 135 | .PHONY : MyDCE.s 136 | 137 | # target to generate assembly for a file 138 | MyDCE.cpp.s: 139 | cd /home/morris1028/LLVM/hw1 && $(MAKE) -f MyDCE/CMakeFiles/MyDCE.dir/build.make MyDCE/CMakeFiles/MyDCE.dir/MyDCE.cpp.s 140 | .PHONY : MyDCE.cpp.s 141 | 142 | # Help Target 143 | help: 144 | @echo "The following are some of the valid targets for this Makefile:" 145 | @echo "... all (the default if no target is provided)" 146 | @echo "... clean" 147 | @echo "... depend" 148 | @echo "... edit_cache" 149 | @echo "... rebuild_cache" 150 | @echo "... MyDCE" 151 | @echo "... MyDCE.o" 152 | @echo "... MyDCE.i" 153 | @echo "... MyDCE.s" 154 | .PHONY : help 155 | 156 | 157 | 158 | #============================================================================= 159 | # Special targets to cleanup operation of make. 160 | 161 | # Special rule to run CMake to check the build system integrity. 162 | # No rule that depends on this can have commands that come from listfiles 163 | # because they might be regenerated. 164 | cmake_check_build_system: 165 | cd /home/morris1028/LLVM/hw1 && $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 166 | .PHONY : cmake_check_build_system 167 | 168 | -------------------------------------------------------------------------------- /Advanced/Dataflow/Liveness/Liveness.cpp: -------------------------------------------------------------------------------- 1 | // #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | using namespace std; 12 | #define MAXD 32 13 | #define MAXN 512 14 | struct Inst; 15 | bitset IN[MAXD], OUT[MAXD]; 16 | bitset DEF[MAXD], USE[MAXD]; 17 | map BBname, BBvar, BBdef; 18 | map invBBname, invBBvar, invBBdef; 19 | map> BBgraph, invBBgraph; 20 | map> BBinst; 21 | struct Inst { 22 | int defId, varId; 23 | vector opargs; 24 | void print() { 25 | printf("\t\t%s : %s ,", invBBdef[defId].c_str(), invBBvar[varId].c_str()); 26 | for (auto e : opargs) 27 | printf(" %s", invBBvar[e].c_str()); 28 | puts(""); 29 | } 30 | }; 31 | static void listBB() { 32 | puts("=== Basic Block Information ==="); 33 | for (auto &e : BBinst) { 34 | int bid = e.first; 35 | printf("\t--- %s ---\n", invBBname[bid].c_str()); 36 | vector &instSet = e.second; 37 | for (auto &I : instSet) 38 | I.print(); 39 | } 40 | puts("===\n"); 41 | } 42 | static void printBBinfo(int bid) { 43 | printf("\t--- %s ---\n", invBBname[bid].c_str()); 44 | printf("\t\tDEF :"); 45 | for (int i = 0; i < BBvar.size(); i++) { 46 | if (DEF[bid][i]) 47 | printf(" %s", invBBvar[i].c_str()); 48 | } 49 | puts(""); 50 | printf("\t\tUSE :"); 51 | for (int i = 0; i < BBvar.size(); i++) { 52 | if (USE[bid][i]) 53 | printf(" %s", invBBvar[i].c_str()); 54 | } 55 | puts(""); 56 | printf("\t\tIN :"); 57 | for (int i = 0; i < BBvar.size(); i++) { 58 | if (IN[bid][i]) 59 | printf(" %s", invBBvar[i].c_str()); 60 | } 61 | puts(""); 62 | printf("\t\tOUT :"); 63 | for (int i = 0; i < BBvar.size(); i++) { 64 | if (OUT[bid][i]) 65 | printf(" %s", invBBvar[i].c_str()); 66 | } 67 | puts(""); 68 | } 69 | static string trim(string s) { 70 | if (s.empty()) 71 | return s; 72 | s.erase(0, s.find_first_not_of(" ")); 73 | s.erase(s.find_last_not_of(" ") + 1); 74 | return s; 75 | } 76 | static int BBlookup(string s) { 77 | int sz = BBname.size(); 78 | if (BBname.count(s)) 79 | return BBname[s]; 80 | invBBname[sz] = s; 81 | return BBname[s] = sz; 82 | } 83 | static int Deflookup(string s) { 84 | int sz = BBdef.size(); 85 | if (BBdef.count(s)) 86 | return BBdef[s]; 87 | invBBdef[sz] = s; 88 | return BBdef[s] = sz; 89 | } 90 | static int Varlookup(string s) { 91 | int sz = BBvar.size(); 92 | if (BBvar.count(s)) 93 | return BBvar[s]; 94 | invBBvar[sz] = s; 95 | return BBvar[s] = sz; 96 | } 97 | static void clearGraph() { 98 | BBname.clear(); 99 | BBgraph.clear(); 100 | } 101 | static void clearInst() { 102 | BBdef.clear(); 103 | BBvar.clear(); 104 | BBinst.clear(); 105 | } 106 | static void initTable() { 107 | for (int i = 0; i < BBdef.size(); i++) { 108 | IN[i] = bitset(); 109 | OUT[i] = bitset(); 110 | DEF[i] = bitset(); 111 | USE[i] = bitset(); 112 | } 113 | } 114 | static void readGraph() { 115 | clearGraph(); 116 | string line, trash; 117 | int stId = BBlookup("Entry"); 118 | int edId = BBlookup("Exit"); 119 | BBgraph[stId] = invBBgraph[stId] = vector(); 120 | BBgraph[edId] = invBBgraph[edId] = vector(); 121 | while (getline(cin, line)) { 122 | line = trim(line); 123 | if (line == "```") 124 | return ; 125 | stringstream sin(line); 126 | string u, v; 127 | sin >> u >> trash >> v; 128 | int uid, vid; 129 | uid = BBlookup(u), vid = BBlookup(v); 130 | BBgraph[uid].push_back(vid); 131 | invBBgraph[vid].push_back(uid); 132 | } 133 | } 134 | static void readInst() { 135 | clearInst(); 136 | string line, trash; 137 | getline(cin, line); 138 | line = trim(line); 139 | if (line == "```") 140 | return ; 141 | do { 142 | string bname = line; 143 | int bid = BBlookup(bname); 144 | while (getline(cin, line)) { 145 | line = trim(line); 146 | if (line[0] == 'B' || line[0] == '`') break; 147 | int did, vid, oid; 148 | string def, var; 149 | stringstream tin(line); 150 | tin >> def >> var; 151 | Inst inst; 152 | inst.defId = Deflookup(def); 153 | inst.varId = Varlookup(var); 154 | while (tin >> var) 155 | inst.opargs.push_back(Varlookup(var)); 156 | BBinst[bid].push_back(inst); 157 | } 158 | if (line == "```") 159 | break; 160 | } while (true); 161 | int stId = BBlookup("Entry"); 162 | int edId = BBlookup("Exit"); 163 | BBinst[stId], BBinst[edId]; 164 | } 165 | static void readIn() { 166 | string line; 167 | while (getline(cin, line)) { 168 | line = trim(line); 169 | if (line == "```") { 170 | readGraph(); 171 | break; 172 | } 173 | } 174 | while (getline(cin, line)) { 175 | line = trim(line); 176 | if (line == "```") { 177 | readInst(); 178 | break; 179 | } 180 | } 181 | } 182 | static bool assignAndDiff(bitset &A, bitset B) { 183 | bool test = (A != B); 184 | A = B; 185 | return test; 186 | } 187 | static void execute() { 188 | initTable(); 189 | for (auto &e : BBinst) { 190 | int bid = e.first; 191 | vector &instSet = e.second; 192 | for (auto &I : instSet) { 193 | DEF[bid].set(I.varId); 194 | for (auto &it : I.opargs) 195 | USE[bid].set(it); 196 | } 197 | } 198 | 199 | bool changed = false; 200 | do { 201 | changed = false; 202 | for (auto &e : BBinst) { 203 | int bid = e.first; 204 | changed |= assignAndDiff(IN[bid], USE[bid] | (OUT[bid]^(OUT[bid]&DEF[bid]))); 205 | for (auto &succ : BBgraph[bid]) 206 | changed |= assignAndDiff(OUT[bid], OUT[bid] | IN[succ]); 207 | } 208 | } while (changed == true); 209 | } 210 | static void writeOut() { 211 | listBB(); 212 | puts("=== Basic Block Liveness ==="); 213 | for (auto &e : BBinst) { 214 | int bid = e.first; 215 | printBBinfo(bid); 216 | } 217 | puts("===\n"); 218 | } 219 | int main() { 220 | readIn(); 221 | execute(); 222 | writeOut(); 223 | return 0; 224 | } 225 | -------------------------------------------------------------------------------- /Advanced/LLVM/Simple-DCE-pass/Hello/Makefile: -------------------------------------------------------------------------------- 1 | # CMAKE generated file: DO NOT EDIT! 2 | # Generated by "Unix Makefiles" Generator, CMake Version 3.2 3 | 4 | # Default target executed when no arguments are given to make. 5 | default_target: all 6 | .PHONY : default_target 7 | 8 | # Allow only one "make -f Makefile2" at a time, but pass parallelism. 9 | .NOTPARALLEL: 10 | 11 | #============================================================================= 12 | # Special targets provided by cmake. 13 | 14 | # Disable implicit rules so canonical targets will work. 15 | .SUFFIXES: 16 | 17 | # Remove some rules from gmake that .SUFFIXES does not remove. 18 | SUFFIXES = 19 | 20 | .SUFFIXES: .hpux_make_needs_suffix_list 21 | 22 | # Suppress display of executed commands. 23 | $(VERBOSE).SILENT: 24 | 25 | # A target that is always out of date. 26 | cmake_force: 27 | .PHONY : cmake_force 28 | 29 | #============================================================================= 30 | # Set environment variables for the build. 31 | 32 | # The shell in which to execute make rules. 33 | SHELL = /bin/sh 34 | 35 | # The CMake executable. 36 | CMAKE_COMMAND = /usr/bin/cmake 37 | 38 | # The command to remove a file. 39 | RM = /usr/bin/cmake -E remove -f 40 | 41 | # Escaping for special characters. 42 | EQUALS = = 43 | 44 | # The top-level source directory on which CMake was run. 45 | CMAKE_SOURCE_DIR = /home/morris1028/LLVM/hw1 46 | 47 | # The top-level build directory on which CMake was run. 48 | CMAKE_BINARY_DIR = /home/morris1028/LLVM/hw1 49 | 50 | #============================================================================= 51 | # Targets provided globally by CMake. 52 | 53 | # Special rule for the target edit_cache 54 | edit_cache: 55 | @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "No interactive CMake dialog available..." 56 | /usr/bin/cmake -E echo No\ interactive\ CMake\ dialog\ available. 57 | .PHONY : edit_cache 58 | 59 | # Special rule for the target edit_cache 60 | edit_cache/fast: edit_cache 61 | .PHONY : edit_cache/fast 62 | 63 | # Special rule for the target rebuild_cache 64 | rebuild_cache: 65 | @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..." 66 | /usr/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) 67 | .PHONY : rebuild_cache 68 | 69 | # Special rule for the target rebuild_cache 70 | rebuild_cache/fast: rebuild_cache 71 | .PHONY : rebuild_cache/fast 72 | 73 | # The main all target 74 | all: cmake_check_build_system 75 | cd /home/morris1028/LLVM/hw1 && $(CMAKE_COMMAND) -E cmake_progress_start /home/morris1028/LLVM/hw1/CMakeFiles /home/morris1028/LLVM/hw1/Hello/CMakeFiles/progress.marks 76 | cd /home/morris1028/LLVM/hw1 && $(MAKE) -f CMakeFiles/Makefile2 Hello/all 77 | $(CMAKE_COMMAND) -E cmake_progress_start /home/morris1028/LLVM/hw1/CMakeFiles 0 78 | .PHONY : all 79 | 80 | # The main clean target 81 | clean: 82 | cd /home/morris1028/LLVM/hw1 && $(MAKE) -f CMakeFiles/Makefile2 Hello/clean 83 | .PHONY : clean 84 | 85 | # The main clean target 86 | clean/fast: clean 87 | .PHONY : clean/fast 88 | 89 | # Prepare targets for installation. 90 | preinstall: all 91 | cd /home/morris1028/LLVM/hw1 && $(MAKE) -f CMakeFiles/Makefile2 Hello/preinstall 92 | .PHONY : preinstall 93 | 94 | # Prepare targets for installation. 95 | preinstall/fast: 96 | cd /home/morris1028/LLVM/hw1 && $(MAKE) -f CMakeFiles/Makefile2 Hello/preinstall 97 | .PHONY : preinstall/fast 98 | 99 | # clear depends 100 | depend: 101 | cd /home/morris1028/LLVM/hw1 && $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1 102 | .PHONY : depend 103 | 104 | # Convenience name for target. 105 | Hello/CMakeFiles/LLVMHello2.dir/rule: 106 | cd /home/morris1028/LLVM/hw1 && $(MAKE) -f CMakeFiles/Makefile2 Hello/CMakeFiles/LLVMHello2.dir/rule 107 | .PHONY : Hello/CMakeFiles/LLVMHello2.dir/rule 108 | 109 | # Convenience name for target. 110 | LLVMHello2: Hello/CMakeFiles/LLVMHello2.dir/rule 111 | .PHONY : LLVMHello2 112 | 113 | # fast build rule for target. 114 | LLVMHello2/fast: 115 | cd /home/morris1028/LLVM/hw1 && $(MAKE) -f Hello/CMakeFiles/LLVMHello2.dir/build.make Hello/CMakeFiles/LLVMHello2.dir/build 116 | .PHONY : LLVMHello2/fast 117 | 118 | Hello.o: Hello.cpp.o 119 | .PHONY : Hello.o 120 | 121 | # target to build an object file 122 | Hello.cpp.o: 123 | cd /home/morris1028/LLVM/hw1 && $(MAKE) -f Hello/CMakeFiles/LLVMHello2.dir/build.make Hello/CMakeFiles/LLVMHello2.dir/Hello.cpp.o 124 | .PHONY : Hello.cpp.o 125 | 126 | Hello.i: Hello.cpp.i 127 | .PHONY : Hello.i 128 | 129 | # target to preprocess a source file 130 | Hello.cpp.i: 131 | cd /home/morris1028/LLVM/hw1 && $(MAKE) -f Hello/CMakeFiles/LLVMHello2.dir/build.make Hello/CMakeFiles/LLVMHello2.dir/Hello.cpp.i 132 | .PHONY : Hello.cpp.i 133 | 134 | Hello.s: Hello.cpp.s 135 | .PHONY : Hello.s 136 | 137 | # target to generate assembly for a file 138 | Hello.cpp.s: 139 | cd /home/morris1028/LLVM/hw1 && $(MAKE) -f Hello/CMakeFiles/LLVMHello2.dir/build.make Hello/CMakeFiles/LLVMHello2.dir/Hello.cpp.s 140 | .PHONY : Hello.cpp.s 141 | 142 | # Help Target 143 | help: 144 | @echo "The following are some of the valid targets for this Makefile:" 145 | @echo "... all (the default if no target is provided)" 146 | @echo "... clean" 147 | @echo "... depend" 148 | @echo "... edit_cache" 149 | @echo "... rebuild_cache" 150 | @echo "... LLVMHello2" 151 | @echo "... Hello.o" 152 | @echo "... Hello.i" 153 | @echo "... Hello.s" 154 | .PHONY : help 155 | 156 | 157 | 158 | #============================================================================= 159 | # Special targets to cleanup operation of make. 160 | 161 | # Special rule to run CMake to check the build system integrity. 162 | # No rule that depends on this can have commands that come from listfiles 163 | # because they might be regenerated. 164 | cmake_check_build_system: 165 | cd /home/morris1028/LLVM/hw1 && $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 166 | .PHONY : cmake_check_build_system 167 | 168 | -------------------------------------------------------------------------------- /Advanced/LLVM/Simple-CSE-pass/MyCSE/MyCSE.cpp: -------------------------------------------------------------------------------- 1 | #include "llvm/ADT/SmallPtrSet.h" 2 | #include "llvm/ADT/SmallVector.h" 3 | #include "llvm/IR/InstIterator.h" // inst_range 4 | #include "llvm/IR/Instructions.h" // TerminatorInst 5 | #include "llvm/IR/IRBuilder.h" 6 | #include "llvm/Support/Debug.h" 7 | #include "llvm/Support/ErrorHandling.h" 8 | #include "llvm/Transforms/Utils/BasicBlockUtils.h" 9 | using namespace llvm; 10 | 11 | #include "MyCSE.h" 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | char MyCSE::ID = 0; 18 | static RegisterPass X("myMagicCSE", "My CSE Pass", false, false); 19 | 20 | #define MDEBUG 21 | 22 | namespace { 23 | struct Expression { 24 | uint32_t opcode; 25 | Type *type; 26 | SmallVector varargs; 27 | Expression(uint32_t o = ~2U) : opcode(o) {} 28 | bool operator==(const Expression &other) const { 29 | if (opcode != other.opcode) 30 | return false; 31 | if (opcode == ~0U || opcode == ~1U) 32 | return true; 33 | if (type != other.type) 34 | return false; 35 | if (varargs != other.varargs) 36 | return false; 37 | return true; 38 | } 39 | friend hash_code hash_value(const Expression &Value) { 40 | return hash_combine(Value.opcode, Value.type, 41 | hash_combine_range(Value.varargs.begin(), 42 | Value.varargs.end())); 43 | } 44 | 45 | }; 46 | class ValueTable { 47 | DenseMap valNumbering; 48 | DenseMap exprNumbering; 49 | std::map invExprNumbering; 50 | uint32_t nextValNumber; 51 | public: 52 | ValueTable(): nextValNumber(1) { 53 | } 54 | uint32_t lookup_or_add(Value *V); // if not found, create new one 55 | Expression create_expression(Instruction *I); 56 | void clear(); 57 | int replace(Instruction *I, BasicBlock *BB, 58 | BasicBlock::iterator BBit); 59 | }; 60 | } 61 | namespace llvm { 62 | template <> struct DenseMapInfo { 63 | static inline Expression getEmptyKey() { 64 | return ~0U; 65 | } 66 | 67 | static inline Expression getTombstoneKey() { 68 | return ~1U; 69 | } 70 | 71 | static unsigned getHashValue(const Expression e) { 72 | using llvm::hash_value; 73 | return static_cast(hash_value(e)); 74 | } 75 | static bool isEqual(const Expression &LHS, const Expression &RHS) { 76 | return LHS == RHS; 77 | } 78 | }; 79 | } 80 | void ValueTable::clear() { 81 | valNumbering.clear(); 82 | exprNumbering.clear(); 83 | nextValNumber = 1; 84 | } 85 | int ValueTable::replace(Instruction *I, BasicBlock *BB, 86 | BasicBlock::iterator BBit) { 87 | BinaryOperator *bop; 88 | Value *L, *R; 89 | 90 | bop = dyn_cast(I); 91 | L = bop->getOperand(0); 92 | R = bop->getOperand(1); 93 | 94 | Expression expr = create_expression(I); 95 | 96 | DenseMap::iterator eit = exprNumbering.find(expr); 97 | if (eit != exprNumbering.end()) { 98 | IRBuilder<> Builder(I->getParent(), ++BasicBlock::iterator(I)); 99 | Instruction *J = invExprNumbering[eit->second]; 100 | assert(dyn_cast(J) && "Insturction -> Value"); 101 | I->replaceAllUsesWith(J); 102 | return 1; 103 | } else { 104 | exprNumbering[expr] = nextValNumber; 105 | invExprNumbering[nextValNumber] = I; 106 | nextValNumber++; 107 | return 0; 108 | } 109 | } 110 | uint32_t ValueTable::lookup_or_add(Value *V) { 111 | DenseMap::iterator vit = valNumbering.find(V); 112 | if (vit != valNumbering.end()) 113 | return vit->second; 114 | if (!isa(V)) { 115 | valNumbering[V] = nextValNumber; 116 | return nextValNumber++; 117 | } 118 | Instruction* I = cast(V); 119 | Expression exp; 120 | switch (I->getOpcode()) { 121 | case Instruction::Add: 122 | case Instruction::FAdd: 123 | case Instruction::Sub: 124 | case Instruction::FSub: 125 | case Instruction::Mul: 126 | case Instruction::FMul: 127 | case Instruction::UDiv: 128 | case Instruction::SDiv: 129 | case Instruction::FDiv: 130 | case Instruction::URem: 131 | case Instruction::SRem: 132 | case Instruction::FRem: 133 | case Instruction::Shl: 134 | case Instruction::LShr: 135 | case Instruction::AShr: 136 | case Instruction::And: 137 | case Instruction::Or: 138 | case Instruction::Xor: 139 | case Instruction::ICmp: 140 | case Instruction::FCmp: 141 | case Instruction::Trunc: 142 | case Instruction::ZExt: 143 | case Instruction::SExt: 144 | case Instruction::FPToUI: 145 | case Instruction::FPToSI: 146 | case Instruction::UIToFP: 147 | case Instruction::SIToFP: 148 | case Instruction::FPTrunc: 149 | case Instruction::FPExt: 150 | case Instruction::PtrToInt: 151 | case Instruction::IntToPtr: 152 | case Instruction::BitCast: 153 | case Instruction::Select: 154 | case Instruction::ExtractElement: 155 | case Instruction::InsertElement: 156 | case Instruction::ShuffleVector: 157 | case Instruction::InsertValue: 158 | case Instruction::GetElementPtr: 159 | exp = create_expression(I); 160 | break; 161 | default: 162 | valNumbering[V] = nextValNumber; 163 | return nextValNumber++; 164 | } 165 | 166 | uint32_t& e = exprNumbering[exp]; 167 | if (!e) e = nextValNumber++; 168 | invExprNumbering[e] = I; 169 | valNumbering[V] = e; 170 | return e; 171 | } 172 | Expression ValueTable::create_expression(Instruction *I) { 173 | Expression e; 174 | e.type = I->getType(); 175 | e.opcode = I->getOpcode(); 176 | for (auto op = I->op_begin(); op != I->op_end(); op++) 177 | e.varargs.push_back(lookup_or_add(*op)); 178 | return e; 179 | } 180 | bool MyCSE::runOnBasicBlock(BasicBlock &BB) { 181 | ValueTable vtable; 182 | bool Changed = false; 183 | int ReplaceCnt = 0; 184 | for (BasicBlock::iterator it = BB.begin(); it != BB.end(); it++) { 185 | Instruction *Inst = &(*it); 186 | BinaryOperator *bop; 187 | if ((bop = dyn_cast(Inst))) { 188 | if (vtable.replace(Inst, &BB, it)) { 189 | ReplaceCnt++; 190 | Changed = true; 191 | } 192 | } 193 | } 194 | 195 | #ifdef MDEBUG 196 | printf("\033[32m\t%s, #Replace %d \033[0m\n", Changed ? "Changed" : "Unchanged", ReplaceCnt); 197 | #endif 198 | return Changed; 199 | } 200 | -------------------------------------------------------------------------------- /Advanced/Dataflow/ReachingDefinition/ReachingDefinition.cpp: -------------------------------------------------------------------------------- 1 | //#include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | using namespace std; 12 | #define MAXD 32 13 | #define MAXN 512 14 | struct Inst; 15 | bitset IN[MAXD], OUT[MAXD]; 16 | bitset GEN[MAXD], KILL[MAXD]; 17 | map BBname, BBvar, BBdef; 18 | map invBBname, invBBvar, invBBdef; 19 | map> BBgraph, invBBgraph; 20 | map> BBinst; 21 | struct Inst { 22 | int defId, varId; 23 | vector opargs; 24 | void print() { 25 | printf("\t\t%s : %s ,", invBBdef[defId].c_str(), invBBvar[varId].c_str()); 26 | for (auto e : opargs) 27 | printf(" %s", invBBvar[e].c_str()); 28 | puts(""); 29 | } 30 | }; 31 | static void listBB() { 32 | puts("=== Basic Block Information ==="); 33 | for (auto &e : BBinst) { 34 | int bid = e.first; 35 | printf("\t--- %s ---\n", invBBname[bid].c_str()); 36 | vector &instSet = e.second; 37 | for (auto &I : instSet) 38 | I.print(); 39 | } 40 | puts("===\n"); 41 | } 42 | static void printBBinfo(int bid) { 43 | printf("\t--- %s ---\n", invBBname[bid].c_str()); 44 | printf("\t\tGEN :"); 45 | for (int i = 0; i < BBdef.size(); i++) { 46 | if (GEN[bid][i]) 47 | printf(" %s", invBBdef[i].c_str()); 48 | } 49 | puts(""); 50 | printf("\t\tKILL:"); 51 | for (int i = 0; i < BBdef.size(); i++) { 52 | if (KILL[bid][i]) 53 | printf(" %s", invBBdef[i].c_str()); 54 | } 55 | puts(""); 56 | printf("\t\tIN :"); 57 | for (int i = 0; i < BBdef.size(); i++) { 58 | if (IN[bid][i]) 59 | printf(" %s", invBBdef[i].c_str()); 60 | } 61 | puts(""); 62 | printf("\t\tOUT :"); 63 | for (int i = 0; i < BBdef.size(); i++) { 64 | if (OUT[bid][i]) 65 | printf(" %s", invBBdef[i].c_str()); 66 | } 67 | puts(""); 68 | } 69 | static string trim(string s) { 70 | if (s.empty()) 71 | return s; 72 | s.erase(0, s.find_first_not_of(" ")); 73 | s.erase(s.find_last_not_of(" ") + 1); 74 | return s; 75 | } 76 | static int BBlookup(string s) { 77 | int sz = BBname.size(); 78 | if (BBname.count(s)) 79 | return BBname[s]; 80 | invBBname[sz] = s; 81 | return BBname[s] = sz; 82 | } 83 | static int Deflookup(string s) { 84 | int sz = BBdef.size(); 85 | if (BBdef.count(s)) 86 | return BBdef[s]; 87 | invBBdef[sz] = s; 88 | return BBdef[s] = sz; 89 | } 90 | static int Varlookup(string s) { 91 | int sz = BBvar.size(); 92 | if (BBvar.count(s)) 93 | return BBvar[s]; 94 | invBBvar[sz] = s; 95 | return BBvar[s] = sz; 96 | } 97 | static void clearGraph() { 98 | BBname.clear(); 99 | BBgraph.clear(); 100 | } 101 | static void clearInst() { 102 | BBdef.clear(); 103 | BBvar.clear(); 104 | BBinst.clear(); 105 | } 106 | static void initTable() { 107 | for (int i = 0; i < BBdef.size(); i++) { 108 | IN[i] = bitset(); 109 | OUT[i] = bitset(); 110 | GEN[i] = bitset(); 111 | KILL[i] = bitset(); 112 | } 113 | } 114 | static void readGraph() { 115 | clearGraph(); 116 | string line, trash; 117 | int stId = BBlookup("Entry"); 118 | int edId = BBlookup("Exit"); 119 | BBgraph[stId] = invBBgraph[stId] = vector(); 120 | BBgraph[edId] = invBBgraph[edId] = vector(); 121 | while (getline(cin, line)) { 122 | line = trim(line); 123 | if (line == "```") 124 | return ; 125 | stringstream sin(line); 126 | string u, v; 127 | sin >> u >> trash >> v; 128 | int uid, vid; 129 | uid = BBlookup(u), vid = BBlookup(v); 130 | BBgraph[uid].push_back(vid); 131 | invBBgraph[vid].push_back(uid); 132 | } 133 | } 134 | static void readInst() { 135 | clearInst(); 136 | string line, trash; 137 | getline(cin, line); 138 | line = trim(line); 139 | if (line == "```") 140 | return ; 141 | do { 142 | string bname = line; 143 | int bid = BBlookup(bname); 144 | while (getline(cin, line)) { 145 | line = trim(line); 146 | if (line[0] == 'B' || line[0] == '`') break; 147 | int did, vid, oid; 148 | string def, var; 149 | stringstream tin(line); 150 | tin >> def >> var; 151 | Inst inst; 152 | inst.defId = Deflookup(def); 153 | inst.varId = Varlookup(var); 154 | while (tin >> var) 155 | inst.opargs.push_back(Varlookup(var)); 156 | BBinst[bid].push_back(inst); 157 | } 158 | if (line == "```") 159 | break; 160 | } while (true); 161 | int stId = BBlookup("Entry"); 162 | int edId = BBlookup("Exit"); 163 | BBinst[stId], BBinst[edId]; 164 | } 165 | static void readIn() { 166 | string line; 167 | while (getline(cin, line)) { 168 | line = trim(line); 169 | if (line == "```") { 170 | readGraph(); 171 | break; 172 | } 173 | } 174 | while (getline(cin, line)) { 175 | line = trim(line); 176 | if (line == "```") { 177 | readInst(); 178 | break; 179 | } 180 | } 181 | } 182 | static bool assignAndDiff(bitset &A, bitset B) { 183 | bool test = (A != B); 184 | A = B; 185 | return test; 186 | } 187 | static void execute() { 188 | initTable(); 189 | for (auto &e : BBinst) { 190 | int bid = e.first; 191 | vector &instSet = e.second; 192 | for (auto &I : instSet) { 193 | GEN[bid].set(I.defId); 194 | for (auto &it_e : BBinst) { 195 | if (it_e.first == bid) // self 196 | continue; 197 | for (auto &it_I : it_e.second) { 198 | if (it_I.varId == I.varId) 199 | KILL[bid].set(it_I.defId); 200 | } 201 | } 202 | } 203 | } 204 | 205 | bool changed = false; 206 | do { 207 | changed = false; 208 | for (auto &e : BBinst) { 209 | int bid = e.first; 210 | changed |= assignAndDiff(OUT[bid], GEN[bid] | (IN[bid]^(IN[bid]&KILL[bid]))); 211 | for (auto &pred : invBBgraph[bid]) 212 | changed |= assignAndDiff(IN[bid], IN[bid] | OUT[pred]); 213 | } 214 | } while (changed == true); 215 | } 216 | static void writeOut() { 217 | listBB(); 218 | puts("=== Basic Block Reaching Definition ==="); 219 | for (auto &e : BBinst) { 220 | int bid = e.first; 221 | printBBinfo(bid); 222 | } 223 | puts("===\n"); 224 | } 225 | int main() { 226 | readIn(); 227 | execute(); 228 | writeOut(); 229 | return 0; 230 | } 231 | -------------------------------------------------------------------------------- /Advanced/Dataflow/AvailableExpr/AvailableExpr.cpp: -------------------------------------------------------------------------------- 1 | //#include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | using namespace std; 12 | #define MAXD 32 13 | #define MAXN 512 14 | struct Inst; 15 | bitset IN[MAXD], OUT[MAXD]; 16 | bitset GEN[MAXD], KILL[MAXD]; 17 | map BBname, BBvar, BBop; 18 | map invBBname, invBBvar, invBBop; 19 | map> BBgraph, invBBgraph; 20 | map> BBinst; 21 | vector instList; 22 | struct Inst { 23 | int expId, varId; 24 | int opcode; 25 | vector opargs; 26 | void print() { 27 | printf("\t\t[%d] %s = %s", expId, invBBvar[varId].c_str(), invBBop[opcode].c_str()); 28 | for (auto e : opargs) 29 | printf(" %s", invBBvar[e].c_str()); 30 | puts(""); 31 | } 32 | }; 33 | static void listBB() { 34 | puts("=== Basic Block Information ==="); 35 | for (auto &e : BBinst) { 36 | int bid = e.first; 37 | printf("\t--- %s ---\n", invBBname[bid].c_str()); 38 | vector &instSet = e.second; 39 | for (auto &I : instSet) 40 | I.print(); 41 | } 42 | puts("===\n"); 43 | } 44 | static void printBBinfo(int bid) { 45 | printf("\t--- %s ---\n", invBBname[bid].c_str()); 46 | printf("\t\tGEN :\n"); 47 | for (int i = 0; i < instList.size(); i++) { 48 | if (GEN[bid][i]) 49 | putchar('\t'), instList[i].print(); 50 | } 51 | printf("\t\tKILL:\n"); 52 | for (int i = 0; i < instList.size(); i++) { 53 | if (KILL[bid][i]) 54 | putchar('\t'), instList[i].print(); 55 | } 56 | printf("\t\tIN :\n"); 57 | for (int i = 0; i < instList.size(); i++) { 58 | if (IN[bid][i]) 59 | putchar('\t'), instList[i].print(); 60 | } 61 | printf("\t\tOUT :\n"); 62 | for (int i = 0; i < instList.size(); i++) { 63 | if (OUT[bid][i]) 64 | putchar('\t'), instList[i].print(); 65 | } 66 | } 67 | static string trim(string s) { 68 | if (s.empty()) 69 | return s; 70 | s.erase(0, s.find_first_not_of(" ")); 71 | s.erase(s.find_last_not_of(" ") + 1); 72 | return s; 73 | } 74 | static int BBlookup(string s) { 75 | int sz = BBname.size(); 76 | if (BBname.count(s)) 77 | return BBname[s]; 78 | invBBname[sz] = s; 79 | return BBname[s] = sz; 80 | } 81 | static int Oplookup(string s) { 82 | int sz = BBop.size(); 83 | if (BBop.count(s)) 84 | return BBop[s]; 85 | invBBop[sz] = s; 86 | return BBop[s] = sz; 87 | } 88 | static int Varlookup(string s) { 89 | int sz = BBvar.size(); 90 | if (BBvar.count(s)) 91 | return BBvar[s]; 92 | invBBvar[sz] = s; 93 | return BBvar[s] = sz; 94 | } 95 | static void clearGraph() { 96 | BBname.clear(); 97 | BBgraph.clear(); 98 | } 99 | static void clearInst() { 100 | BBop.clear(); 101 | BBvar.clear(); 102 | BBinst.clear(); 103 | } 104 | static void initTable() { 105 | for (int i = 0; i < instList.size(); i++) { 106 | IN[i] = bitset(); 107 | OUT[i] = bitset(); 108 | GEN[i] = bitset(); 109 | KILL[i] = bitset(); 110 | } 111 | } 112 | static void readGraph() { 113 | clearGraph(); 114 | string line, trash; 115 | int stId = BBlookup("Entry"); 116 | int edId = BBlookup("Exit"); 117 | BBgraph[stId] = invBBgraph[stId] = vector(); 118 | BBgraph[edId] = invBBgraph[edId] = vector(); 119 | while (getline(cin, line)) { 120 | line = trim(line); 121 | if (line == "```") 122 | return ; 123 | stringstream sin(line); 124 | string u, v; 125 | sin >> u >> trash >> v; 126 | int uid, vid; 127 | uid = BBlookup(u), vid = BBlookup(v); 128 | BBgraph[uid].push_back(vid); 129 | invBBgraph[vid].push_back(uid); 130 | } 131 | } 132 | static void readInst() { 133 | clearInst(); 134 | string line, trash; 135 | getline(cin, line); 136 | line = trim(line); 137 | if (line == "```") 138 | return ; 139 | int id = 0; 140 | do { 141 | string bname = line; 142 | int bid = BBlookup(bname); 143 | while (getline(cin, line)) { 144 | line = trim(line); 145 | if (line[0] == 'B' || line[0] == '`') break; 146 | int did, vid, oid; 147 | string var, op; 148 | stringstream tin(line); 149 | tin >> op >> var; 150 | Inst inst; 151 | inst.expId = id++; 152 | inst.opcode = Oplookup(op); 153 | inst.varId = Varlookup(var); 154 | while (tin >> var) 155 | inst.opargs.push_back(Varlookup(var)); 156 | instList.push_back(inst); 157 | BBinst[bid].push_back(inst); 158 | } 159 | if (line == "```") 160 | break; 161 | } while (true); 162 | int stId = BBlookup("Entry"); 163 | int edId = BBlookup("Exit"); 164 | BBinst[stId], BBinst[edId]; 165 | } 166 | static void readIn() { 167 | string line; 168 | while (getline(cin, line)) { 169 | line = trim(line); 170 | if (line == "```") { 171 | readGraph(); 172 | break; 173 | } 174 | } 175 | while (getline(cin, line)) { 176 | line = trim(line); 177 | if (line == "```") { 178 | readInst(); 179 | break; 180 | } 181 | } 182 | } 183 | static bool assignAndDiff(bitset &A, bitset B) { 184 | bool test = (A != B); 185 | A = B; 186 | return test; 187 | } 188 | static void execute() { 189 | initTable(); 190 | for (auto &BBu : BBinst) { 191 | vector &instSet = BBu.second; 192 | for (auto &Iu : instSet) { 193 | GEN[BBu.first].set(Iu.expId); 194 | for (auto &BBv : BBinst) { 195 | for (auto Iv : BBv.second) { 196 | bool same = false; 197 | if (BBv.first == BBu.first && (Iu.expId >= Iv.expId)) 198 | continue; 199 | for (auto t : Iv.opargs) { 200 | if (t == Iu.varId) 201 | same = true; 202 | } 203 | if (same) 204 | KILL[BBu.first].set(Iv.expId); 205 | } 206 | } 207 | } 208 | GEN[BBu.first] = GEN[BBu.first]^(GEN[BBu.first]&KILL[BBu.first]); 209 | } 210 | 211 | bool changed = false; 212 | do { 213 | changed = false; 214 | for (auto &e : BBinst) { 215 | int bid = e.first; 216 | changed |= assignAndDiff(OUT[bid], GEN[bid] | (IN[bid]^(IN[bid]&KILL[bid]))); 217 | bitset intersect; 218 | intersect.flip(); 219 | for (auto &pred : invBBgraph[bid]) 220 | intersect = intersect & OUT[pred]; 221 | if (invBBgraph[bid].size() == 0) 222 | intersect = bitset(); 223 | changed |= assignAndDiff(IN[bid], intersect); 224 | } 225 | } while (changed == true); 226 | } 227 | static void writeOut() { 228 | listBB(); 229 | puts("=== Basic Block Available Expressions ==="); 230 | for (auto &e : BBinst) { 231 | int bid = e.first; 232 | printBBinfo(bid); 233 | } 234 | puts("===\n"); 235 | } 236 | int main() { 237 | readIn(); 238 | execute(); 239 | writeOut(); 240 | return 0; 241 | } 242 | /* 243 | ``` 244 | Entry -> B1 245 | B1 -> B2 246 | B2 -> B3 247 | B3 -> B4 248 | B4 -> Exit 249 | ``` 250 | ``` 251 | B1 252 | + a b c 253 | B2 254 | - b a d 255 | B3 256 | - c b c 257 | B4 258 | - d a d 259 | ``` 260 | 261 | */ 262 | -------------------------------------------------------------------------------- /Advanced/LLVM/GlobalRegisterAllocation/source/lib/Transforms/TestPass/TestPass.cpp: -------------------------------------------------------------------------------- 1 | #include "../lib/Target/X86/X86.h" 2 | #include "../lib/Target/X86/X86InstrInfo.h" 3 | #include "../lib/Target/X86/X86Subtarget.h" 4 | #include "llvm/CodeGen/MachineFunction.h" 5 | #include "llvm/CodeGen/MachineFunctionPass.h" 6 | #include "llvm/Support/raw_ostream.h" 7 | #include "llvm/Support/Debug.h" 8 | #include "llvm/Analysis/CallGraph.h" 9 | #include "llvm/CodeGen/MachineRegisterInfo.h" 10 | #include "llvm/CodeGen/MachineInstrBuilder.h" 11 | #include "llvm/CodeGen/Passes.h" 12 | #include "llvm/IR/Function.h" 13 | #include "llvm/Target/TargetInstrInfo.h" 14 | #include 15 | #include 16 | #include 17 | #include 18 | using namespace llvm; 19 | 20 | extern FunctionPass *(*loadableFunction)(void); 21 | extern ModulePass *(*loadableFunction2)(void); 22 | // extern ModulePass *llvm::createMyTestPass2(void); 23 | 24 | std::map, std::less> MyCG; 25 | std::map, std::less> invMyCG; 26 | 27 | namespace { 28 | class X86TestPass2 : public ModulePass { 29 | public: 30 | static char ID; 31 | X86TestPass2() : ModulePass(ID) { MyCG.clear(); } 32 | 33 | void getAnalysisUsage(AnalysisUsage &AU) const override { 34 | AU.addRequired(); 35 | } 36 | 37 | bool runOnModule(Module &MF) override; 38 | const char *getPassName() const override { 39 | return "X86TestPass2"; 40 | } 41 | }; 42 | char X86TestPass2::ID = 0; 43 | } 44 | 45 | bool X86TestPass2::runOnModule(Module &MF) { 46 | dbgs() << "run on module" << "\n"; 47 | CallGraph &CG = getAnalysis().getCallGraph(); 48 | CG.dump(); 49 | Module::FunctionListType &functions = MF.getFunctionList(); 50 | for (Module::FunctionListType::iterator it = functions.begin(), 51 | it_end = functions.end(); it != it_end; it++) { 52 | Function &func = *it; 53 | // dbgs() << func.getName() << &func << "\n"; 54 | CallGraphNode *node = CG[&func]; 55 | dbgs() << func.getName() << "\t" << node->getFunction() << "\n"; 56 | for (CallGraphNode::iterator cit = node->begin(), cit_end = node->end(); 57 | cit != cit_end; cit++) { 58 | dbgs() << "\tcall\t" << cit->second->getFunction()->getName() 59 | << "\t" << cit->second->getFunction() << "\n"; 60 | MyCG[node->getFunction()].insert(cit->second->getFunction()); 61 | invMyCG[cit->second->getFunction()].insert(node->getFunction()); 62 | } 63 | func.getCallingConv(); 64 | } 65 | return false; 66 | } 67 | 68 | ModulePass *llvm::createMyTestPass2() { 69 | dbgs() << "create my test pass2" << "\n"; 70 | return new X86TestPass2(); 71 | } 72 | 73 | 74 | namespace { 75 | class X86TestPass : public MachineFunctionPass { 76 | public: 77 | static char ID; 78 | X86TestPass() : MachineFunctionPass(ID) { } 79 | 80 | bool runOnMachineFunction(MachineFunction &MF) override; 81 | 82 | const char *getPassName() const override { 83 | return "X86TestPass"; 84 | } 85 | }; 86 | // char X86Test2Pass::ID = 0; 87 | char X86TestPass::ID = 0; 88 | } 89 | 90 | int AllUsedReg[2048] = {}; 91 | static unsigned X86MapGenRegToSin(unsigned r) { 92 | switch (r) { 93 | case X86::R8 ... X86::R15: return r; 94 | case X86::R8B ... X86::R15B: return r - X86::R8B + X86::R8; 95 | case X86::R8D ... X86::R15D: return r - X86::R8D + X86::R8; 96 | case X86::R8W ... X86::R15W: return r - X86::R8W + X86::R8; 97 | } 98 | dbgs() << "Error" << "\n"; 99 | } 100 | static unsigned X86MapGenRegToSSE(unsigned u, unsigned a, unsigned b) { 101 | // register a -> b 102 | switch (u) { 103 | case X86::R8 ... X86::R15: 104 | case X86::R8B ... X86::R15B: 105 | case X86::R8D ... X86::R15D: 106 | case X86::R8W ... X86::R15W: return u + (b - a); 107 | } 108 | dbgs() << "Error" << "\n"; 109 | } 110 | 111 | bool X86TestPass::runOnMachineFunction(MachineFunction &MF) { 112 | dbgs() << "Fn: " << MF.getFunction()->getName() << "\n"; 113 | // dbgs() << "\t\t" << MF.getFunction() << "\n"; 114 | const Function* fptr = MF.getFunction(); 115 | std::vector A; 116 | int LocalUseRegU[2048] = {}; 117 | int LocalUseRegP[2048] = {}; 118 | for (auto &MBB: MF) { 119 | for (auto &MI: MBB) { 120 | bool has = false; 121 | int opcode = MI.getOpcode(); 122 | for (auto &MO: MI.operands()) { 123 | if (!MO.isReg()) 124 | continue; 125 | unsigned r = MO.getReg(); 126 | if ((r >= X86::R8 && r <= X86::R15) 127 | || (r >= X86::R8B && r <= X86::R15W)) { 128 | unsigned s = X86MapGenRegToSin(r); 129 | if ((opcode >= X86::POP16r && opcode <= X86::POPSS32) 130 | || (opcode >= X86::PUSH16i8 && opcode <= X86::PUSHi32)) { 131 | LocalUseRegP[s] = 1; 132 | } else { 133 | LocalUseRegU[s] = 1; 134 | } 135 | /* 136 | dbgs() << MI.getOpcode() << " " << MI << "\n"; 137 | dbgs() << "reg " << r << "\n"; 138 | has = true; 139 | */ 140 | } 141 | } 142 | } 143 | } 144 | 145 | int ReplaceReg[2048] = {}; 146 | for (int i = X86::R8; i <= X86::R15; i++) { 147 | if (LocalUseRegP[i] == 0) 148 | continue; 149 | if (LocalUseRegU[i] == 0) 150 | continue; 151 | int has = 0; 152 | for (int j = X86::R8; j <= X86::R15; j++) { 153 | if (AllUsedReg[j] == 0) { 154 | AllUsedReg[j] = 1; 155 | ReplaceReg[i] = j; 156 | has = 1; 157 | break; 158 | } 159 | } 160 | if (!has) 161 | AllUsedReg[i] = 1; 162 | } 163 | 164 | std::set> RemoveSet; 165 | for (int i = X86::R8; i <= X86::R15; i++) { 166 | if (ReplaceReg[i] == 0) 167 | continue; 168 | int u = i, v = ReplaceReg[i]; 169 | dbgs() << u << " -------> " << v << "\n"; 170 | for (auto &MBB: MF) { 171 | for (auto &MI: MBB) { 172 | bool has = false; 173 | int opcode = MI.getOpcode(); 174 | for (auto &MO: MI.operands()) { 175 | if (!MO.isReg()) 176 | continue; 177 | unsigned r = MO.getReg(); 178 | if (!(r >= X86::R8 && r <= X86::R15) 179 | && !(r >= X86::R8B && r <= X86::R15W)) 180 | continue; 181 | unsigned s = X86MapGenRegToSin(r); 182 | if (s == u) { 183 | dbgs() << "Modify " << MI << "\n"; 184 | MO.setReg(X86MapGenRegToSSE(r, u, v)); 185 | dbgs() << "Modify " << MI << "\n"; 186 | if ((opcode >= X86::POP16r && opcode <= X86::POPSS32) 187 | || (opcode >= X86::PUSH16i8 && opcode <= X86::PUSHi32)) { 188 | RemoveSet.insert(&MI); 189 | } 190 | } 191 | } 192 | } 193 | } 194 | } 195 | for (auto x : RemoveSet) { 196 | dbgs() << "Remove " << *x << "\n"; 197 | x->removeFromBundle(); 198 | } 199 | return true; 200 | } 201 | 202 | FunctionPass *createMyTestPass() { 203 | return new X86TestPass(); 204 | } 205 | 206 | void __attribute__((constructor)) init() { 207 | loadableFunction = createMyTestPass; 208 | loadableFunction2 = createMyTestPass2; 209 | } 210 | 211 | 212 | -------------------------------------------------------------------------------- /hw1-NFA2DFA/NFA2DFA.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | using namespace std; 11 | class State { 12 | public: 13 | State(int ac=0) { 14 | accepted = ac; 15 | } 16 | bool accepted; 17 | int nameLabel; 18 | map > trans; 19 | }; 20 | class DFA { 21 | public: 22 | State* Q0; 23 | vector Q, F; 24 | }; 25 | class NFA { 26 | public: 27 | static char lambda; 28 | State* Q0; 29 | vector Q, F; 30 | vector< vector > make_deterministic(DFA &M, vector alpha); 31 | private: 32 | vector getSetOf(vector set_of_states, char c); 33 | vector getClose(vector set_of_states); 34 | }; 35 | char NFA::lambda = 0; 36 | /* 37 | * @return delta(S, c) 38 | */ 39 | vector NFA::getSetOf(vector set_of_states, char c) { 40 | set h; 41 | vector ret; 42 | queue q; 43 | State* index; 44 | for(int i = 0; i < set_of_states.size(); i++) { 45 | index = set_of_states[i]; 46 | q.push(index); 47 | } 48 | while(!q.empty()) { 49 | index = q.front(), q.pop(); 50 | vector state_trans = index->trans[c]; 51 | for(int i = 0; i < state_trans.size(); i++) { 52 | if(h.find(state_trans[i]) == h.end()) { 53 | h.insert(state_trans[i]); 54 | ret.push_back(state_trans[i]); 55 | } 56 | } 57 | } 58 | return ret; 59 | } 60 | /* 61 | * Add to S all states reachable from it 62 | * using only lembda transitions of N 63 | * @return S union delta(S, lambda) 64 | */ 65 | vector NFA::getClose(vector set_of_states) { 66 | set h; 67 | vector ret; 68 | queue q; 69 | State* index; 70 | for(int i = 0; i < set_of_states.size(); i++) { 71 | index = set_of_states[i]; 72 | q.push(index), h.insert(index); 73 | } 74 | while(!q.empty()) { 75 | index = q.front(), q.pop(); 76 | ret.push_back(index); 77 | vector state_trans = index->trans[NFA::lambda]; 78 | for(int i = 0; i < state_trans.size(); i++) { 79 | if(h.find(state_trans[i]) == h.end()) { 80 | h.insert(state_trans[i]); 81 | q.push(state_trans[i]); 82 | } 83 | } 84 | } 85 | sort(ret.begin(), ret.end()); 86 | return ret; 87 | } 88 | /* 89 | * @return NFA to DFA 90 | */ 91 | vector< vector > NFA::make_deterministic(DFA &M, vector alpha) { 92 | vector< vector > T; 93 | vector stateSet; 94 | stateSet.push_back(Q0); 95 | vector init_state = getClose(stateSet); 96 | T.push_back(init_state); 97 | M.Q.push_back(new State()); 98 | for(int i = 0; i < T.size(); i++) { 99 | State* state = M.Q[i]; 100 | for(int j = 0; j < T[i].size(); j++) 101 | if(T[i][j]->accepted) 102 | state->accepted = 1; 103 | state->nameLabel = i; 104 | if(state->accepted) M.F.push_back(state); 105 | for(int j = 0; j < alpha.size(); j++) { 106 | if(alpha[j] == NFA::lambda) 107 | continue; 108 | vector next_state = getSetOf(T[i], alpha[j]); 109 | next_state = getClose(next_state); 110 | int existIdx = -1; 111 | for(int k = 0; k < T.size(); k++) { 112 | if(T[k] == next_state) { 113 | existIdx = k; 114 | break; 115 | } 116 | } 117 | if(existIdx < 0) { 118 | T.push_back(next_state); 119 | M.Q.push_back(new State()); 120 | existIdx = T.size()-1; 121 | } 122 | M.Q[i]->trans[alpha[j]].push_back(M.Q[existIdx]); 123 | } 124 | } 125 | M.Q0 = M.Q[0]; 126 | return T; 127 | } 128 | 129 | 130 | vector parsingAlphabetSet(char s[]) { 131 | #define isValidAlpha(x) ((x) != ',' && (x) != '(' && (x) != ')' && !((x) >= '0' && (x) <= '9')) 132 | for(int i = 0; s[i]; i++) { 133 | if(!isValidAlpha(s[i])) 134 | s[i] = ' '; 135 | } 136 | vector ret; 137 | stringstream sin(s); 138 | string token; 139 | while(sin >> token) { 140 | if(token == "l") 141 | ret.push_back(NFA::lambda); 142 | else 143 | ret.push_back(token[0]); 144 | } 145 | return ret; 146 | } 147 | int parsingStateTrans(char s[], int column, vector< vector< vector > > &table) { 148 | for(int i = 0; s[i]; i++) { 149 | if(s[i] == '(' || s[i] == ')') 150 | s[i] = ' '; 151 | } 152 | stringstream sin(s); 153 | int ac = 0; 154 | vector< vector > R; 155 | for(int i = 0; i < column; i++) { 156 | string token, state_index; 157 | sin >> token; 158 | for(int j = 0; j < token.length(); j++) 159 | if(token[j] == ',') 160 | token[j] = ' '; 161 | stringstream sin2(token); 162 | vector S; 163 | while(sin2 >> state_index) { 164 | if(state_index == "*") { 165 | ac = 1; 166 | } else { 167 | int numeric_idx; 168 | numeric_idx = atoi(state_index.c_str()); 169 | if(numeric_idx > 0) { // ignore zero. 170 | S.push_back(numeric_idx-1); 171 | } 172 | } 173 | } 174 | R.push_back(S); 175 | } 176 | table.push_back(R); 177 | return ac; 178 | } 179 | bool cmp(const State* a, const State* b) { 180 | return a->nameLabel < b->nameLabel; 181 | } 182 | void printfState(int accepted, vector mask) { 183 | printf("("); 184 | if(accepted) 185 | printf("*"); 186 | sort(mask.begin(), mask.end(), cmp); 187 | for(int j = 0; j < mask.size(); j++) { 188 | printf("%d", mask[j]->nameLabel + 1); 189 | printf("%c", j == mask.size()-1 ? ')' : ','); 190 | } 191 | if(mask.size() == 0) 192 | printf("0)"); 193 | } 194 | int main() { 195 | //freopen("NFA.txt", "r+t", stdin); 196 | //freopen("DFA.txt", "w+t", stdout); 197 | 198 | NFA nfa; 199 | DFA dfa; 200 | char s[1024]; 201 | int state_count = 0; 202 | vector< vector< vector > > table; 203 | vector hasStar; // integer state label 204 | vector alpha; 205 | // read alpha set 206 | gets(s); 207 | alpha = parsingAlphabetSet(s); 208 | 209 | // read table 210 | while(gets(s)) { 211 | int ac = parsingStateTrans(s, alpha.size(), table); 212 | hasStar.push_back(ac); 213 | state_count++; 214 | } 215 | // build basic NFA states 216 | for(int i = 0; i < state_count; i++) { 217 | nfa.Q.push_back(new State(hasStar[i])); 218 | nfa.Q[i]->nameLabel = i; 219 | if(hasStar[i]) nfa.F.push_back(nfa.Q[i]); 220 | } 221 | // init start state 222 | nfa.Q0 = nfa.Q[0]; 223 | // build translate table. 224 | int i = 0; 225 | for(vector< vector< vector > >::iterator it = table.begin(); 226 | it != table.end(); it++, i++) { 227 | int j = 0; 228 | for(vector< vector >::iterator jt = it->begin(); 229 | jt != it->end(); jt++, j++) { 230 | for(vector::iterator kt = jt->begin(); 231 | kt != jt->end(); kt++) { 232 | nfa.Q[i]->trans[alpha[j]].push_back(nfa.Q[*kt]); 233 | } 234 | } 235 | } 236 | // start process NFA to DFA 237 | vector< vector > mask = nfa.make_deterministic(dfa, alpha); 238 | 239 | // output result 240 | for(map >::iterator it = dfa.Q[0]->trans.begin(); 241 | it != dfa.Q[0]->trans.end(); it++) { 242 | printf("%c%c", it == dfa.Q[0]->trans.begin() ? '(' : ',', it->first); 243 | } 244 | puts(")"); 245 | for(int i = 0; i < dfa.Q.size(); i++) { 246 | if(mask[dfa.Q[i]->nameLabel].size() == 0) 247 | continue; 248 | printfState(dfa.Q[i]->accepted, mask[dfa.Q[i]->nameLabel]); 249 | for(map >::iterator it = dfa.Q[i]->trans.begin(); 250 | it != dfa.Q[i]->trans.end(); it++) { 251 | State *ptr = it->second[0]; 252 | printfState(ptr->accepted, mask[ptr->nameLabel]); 253 | } 254 | puts(""); 255 | } 256 | return 0; 257 | } 258 | /* 259 | void print() { 260 | printf("start[%p]\n", Q0); 261 | for(int i = 0; i < Q.size(); i++) { 262 | printf("Q[%p][%d] : ", Q[i], Q[i]->nameLabel); 263 | for(map >::iterator it = Q[i]->trans.begin(); 264 | it != Q[i]->trans.end(); it++) { 265 | printf("[%c,", it->first == 0 ? '~' : it->first); 266 | for(vector::iterator jt = it->second.begin(); 267 | jt != it->second.end(); jt++) { 268 | printf(" %d", (*jt)->nameLabel); 269 | } 270 | printf("]"); 271 | } 272 | puts(""); 273 | } 274 | }*/ 275 | /* 276 | (l,a,b,2) 277 | (2,0)(3,0)(0,0) 278 | (0,0)(4,5)(0,0) 279 | (0,0)(0,0)(4,0) 280 | (0,0)(5,0)(5,0) 281 | (*,*)(*,*)(*,*) 282 | 283 | 284 | (l,a,b,2) 285 | (3,0)(4,0)(0,0) 286 | (0,0)(3,1)(2,0) 287 | (2,0)(0,0)(4,0) 288 | (3,*)(4,*)(*,*) 289 | 290 | (l,a,b,2) 291 | (2,4,6)(0)(0) 292 | (0)(3)(0) 293 | (6)(0)(0) 294 | (0)(0)(5) 295 | (6)(0)(0) 296 | (1)(7)(0) 297 | (*)(*)(*) 298 | 299 | (l,a,b,2) 300 | (0)(1,2)(1) 301 | (0)(0)(3) 302 | (*)(0,0)(0,0) 303 | 304 | (l,a,b,2) 305 | (*,0)(2)(0) 306 | (0)(0)(3) 307 | (0)(1,4,5)(0) 308 | (0)(5)(0) 309 | (0)(1)(0) 310 | 311 | (l,a,b,2) 312 | (*,2)(0)(0) 313 | (0)(3)(4) 314 | (0)(0)(2) 315 | (1)(0)(0) 316 | 317 | (l,a,b,2) 318 | (0)(2,3)(0) 319 | (0)(1)(0) 320 | (0)(0)(4) 321 | (2)(4)(0) 322 | 323 | (l,a,b,2) 324 | (4)(0)(2) 325 | (0)(3)(0) 326 | (0)(0)(1) 327 | (0)(0)(5) 328 | (0)(4)(0) 329 | */ 330 | -------------------------------------------------------------------------------- /Advanced/LLVM/GlobalRegisterAllocation/source/lib/Target/X86/X86TargetMachine.cpp: -------------------------------------------------------------------------------- 1 | //===-- X86TargetMachine.cpp - Define TargetMachine for the X86 -----------===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // This file defines the X86 specific subclass of TargetMachine. 11 | // 12 | //===----------------------------------------------------------------------===// 13 | 14 | #include "X86TargetMachine.h" 15 | #include "X86.h" 16 | #include "X86TargetObjectFile.h" 17 | #include "X86TargetTransformInfo.h" 18 | #include "llvm/CodeGen/Passes.h" 19 | #include "llvm/IR/Function.h" 20 | #include "llvm/IR/LegacyPassManager.h" 21 | #include "llvm/Support/CommandLine.h" 22 | #include "llvm/Support/FormattedStream.h" 23 | #include "llvm/Support/TargetRegistry.h" 24 | #include "llvm/Target/TargetOptions.h" 25 | using namespace llvm; 26 | 27 | static cl::opt EnableMachineCombinerPass("x86-machine-combiner", 28 | cl::desc("Enable the machine combiner pass"), 29 | cl::init(true), cl::Hidden); 30 | 31 | namespace llvm { 32 | void initializeWinEHStatePassPass(PassRegistry &); 33 | } 34 | 35 | extern "C" void LLVMInitializeX86Target() { 36 | // Register the target. 37 | RegisterTargetMachine X(TheX86_32Target); 38 | RegisterTargetMachine Y(TheX86_64Target); 39 | 40 | PassRegistry &PR = *PassRegistry::getPassRegistry(); 41 | initializeWinEHStatePassPass(PR); 42 | } 43 | 44 | static std::unique_ptr createTLOF(const Triple &TT) { 45 | if (TT.isOSBinFormatMachO()) { 46 | if (TT.getArch() == Triple::x86_64) 47 | return make_unique(); 48 | return make_unique(); 49 | } 50 | 51 | if (TT.isOSLinux() || TT.isOSNaCl()) 52 | return make_unique(); 53 | if (TT.isOSBinFormatELF()) 54 | return make_unique(); 55 | if (TT.isKnownWindowsMSVCEnvironment() || TT.isWindowsCoreCLREnvironment()) 56 | return make_unique(); 57 | if (TT.isOSBinFormatCOFF()) 58 | return make_unique(); 59 | llvm_unreachable("unknown subtarget type"); 60 | } 61 | 62 | static std::string computeDataLayout(const Triple &TT) { 63 | // X86 is little endian 64 | std::string Ret = "e"; 65 | 66 | Ret += DataLayout::getManglingComponent(TT); 67 | // X86 and x32 have 32 bit pointers. 68 | if ((TT.isArch64Bit() && 69 | (TT.getEnvironment() == Triple::GNUX32 || TT.isOSNaCl())) || 70 | !TT.isArch64Bit()) 71 | Ret += "-p:32:32"; 72 | 73 | // Some ABIs align 64 bit integers and doubles to 64 bits, others to 32. 74 | if (TT.isArch64Bit() || TT.isOSWindows() || TT.isOSNaCl()) 75 | Ret += "-i64:64"; 76 | else 77 | Ret += "-f64:32:64"; 78 | 79 | // Some ABIs align long double to 128 bits, others to 32. 80 | if (TT.isOSNaCl()) 81 | ; // No f80 82 | else if (TT.isArch64Bit() || TT.isOSDarwin()) 83 | Ret += "-f80:128"; 84 | else 85 | Ret += "-f80:32"; 86 | 87 | // The registers can hold 8, 16, 32 or, in x86-64, 64 bits. 88 | if (TT.isArch64Bit()) 89 | Ret += "-n8:16:32:64"; 90 | else 91 | Ret += "-n8:16:32"; 92 | 93 | // The stack is aligned to 32 bits on some ABIs and 128 bits on others. 94 | if (!TT.isArch64Bit() && TT.isOSWindows()) 95 | Ret += "-a:0:32-S32"; 96 | else 97 | Ret += "-S128"; 98 | 99 | return Ret; 100 | } 101 | 102 | /// X86TargetMachine ctor - Create an X86 target. 103 | /// 104 | X86TargetMachine::X86TargetMachine(const Target &T, const Triple &TT, 105 | StringRef CPU, StringRef FS, 106 | const TargetOptions &Options, 107 | Reloc::Model RM, CodeModel::Model CM, 108 | CodeGenOpt::Level OL) 109 | : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options, RM, CM, 110 | OL), 111 | TLOF(createTLOF(getTargetTriple())), 112 | Subtarget(TT, CPU, FS, *this, Options.StackAlignmentOverride) { 113 | // Windows stack unwinder gets confused when execution flow "falls through" 114 | // after a call to 'noreturn' function. 115 | // To prevent that, we emit a trap for 'unreachable' IR instructions. 116 | // (which on X86, happens to be the 'ud2' instruction) 117 | if (Subtarget.isTargetWin64()) 118 | this->Options.TrapUnreachable = true; 119 | 120 | // By default (and when -ffast-math is on), enable estimate codegen for 121 | // everything except scalar division. By default, use 1 refinement step for 122 | // all operations. Defaults may be overridden by using command-line options. 123 | // Scalar division estimates are disabled because they break too much 124 | // real-world code. These defaults match GCC behavior. 125 | this->Options.Reciprocals.setDefaults("sqrtf", true, 1); 126 | this->Options.Reciprocals.setDefaults("divf", false, 1); 127 | this->Options.Reciprocals.setDefaults("vec-sqrtf", true, 1); 128 | this->Options.Reciprocals.setDefaults("vec-divf", true, 1); 129 | 130 | initAsmInfo(); 131 | } 132 | 133 | X86TargetMachine::~X86TargetMachine() {} 134 | 135 | const X86Subtarget * 136 | X86TargetMachine::getSubtargetImpl(const Function &F) const { 137 | Attribute CPUAttr = F.getFnAttribute("target-cpu"); 138 | Attribute FSAttr = F.getFnAttribute("target-features"); 139 | 140 | std::string CPU = !CPUAttr.hasAttribute(Attribute::None) 141 | ? CPUAttr.getValueAsString().str() 142 | : TargetCPU; 143 | std::string FS = !FSAttr.hasAttribute(Attribute::None) 144 | ? FSAttr.getValueAsString().str() 145 | : TargetFS; 146 | 147 | // FIXME: This is related to the code below to reset the target options, 148 | // we need to know whether or not the soft float flag is set on the 149 | // function before we can generate a subtarget. We also need to use 150 | // it as a key for the subtarget since that can be the only difference 151 | // between two functions. 152 | bool SoftFloat = 153 | F.hasFnAttribute("use-soft-float") && 154 | F.getFnAttribute("use-soft-float").getValueAsString() == "true"; 155 | // If the soft float attribute is set on the function turn on the soft float 156 | // subtarget feature. 157 | if (SoftFloat) 158 | FS += FS.empty() ? "+soft-float" : ",+soft-float"; 159 | 160 | auto &I = SubtargetMap[CPU + FS]; 161 | if (!I) { 162 | // This needs to be done before we create a new subtarget since any 163 | // creation will depend on the TM and the code generation flags on the 164 | // function that reside in TargetOptions. 165 | resetTargetOptions(F); 166 | I = llvm::make_unique(TargetTriple, CPU, FS, *this, 167 | Options.StackAlignmentOverride); 168 | } 169 | return I.get(); 170 | } 171 | 172 | //===----------------------------------------------------------------------===// 173 | // Command line options for x86 174 | //===----------------------------------------------------------------------===// 175 | static cl::opt 176 | UseVZeroUpper("x86-use-vzeroupper", cl::Hidden, 177 | cl::desc("Minimize AVX to SSE transition penalty"), 178 | cl::init(true)); 179 | 180 | //===----------------------------------------------------------------------===// 181 | // X86 TTI query. 182 | //===----------------------------------------------------------------------===// 183 | 184 | TargetIRAnalysis X86TargetMachine::getTargetIRAnalysis() { 185 | return TargetIRAnalysis([this](const Function &F) { 186 | return TargetTransformInfo(X86TTIImpl(this, F)); 187 | }); 188 | } 189 | 190 | 191 | //===----------------------------------------------------------------------===// 192 | // Pass Pipeline Configuration 193 | //===----------------------------------------------------------------------===// 194 | 195 | namespace { 196 | /// X86 Code Generator Pass Configuration Options. 197 | class X86PassConfig : public TargetPassConfig { 198 | public: 199 | X86PassConfig(X86TargetMachine *TM, PassManagerBase &PM) 200 | : TargetPassConfig(TM, PM) {} 201 | 202 | X86TargetMachine &getX86TargetMachine() const { 203 | return getTM(); 204 | } 205 | 206 | void addIRPasses() override; 207 | bool addInstSelector() override; 208 | bool addILPOpts() override; 209 | bool addPreISel() override; 210 | void addPreRegAlloc() override; 211 | void addPostRegAlloc() override; 212 | void addPreEmitPass() override; 213 | void addPreSched2() override; 214 | }; 215 | } // namespace 216 | 217 | TargetPassConfig *X86TargetMachine::createPassConfig(PassManagerBase &PM) { 218 | return new X86PassConfig(this, PM); 219 | } 220 | 221 | void X86PassConfig::addIRPasses() { 222 | addPass(createX86TestPass2()); 223 | addPass(createAtomicExpandPass(&getX86TargetMachine())); 224 | 225 | TargetPassConfig::addIRPasses(); 226 | } 227 | 228 | bool X86PassConfig::addInstSelector() { 229 | // Install an instruction selector. 230 | addPass(createX86ISelDag(getX86TargetMachine(), getOptLevel())); 231 | 232 | // For ELF, cleanup any local-dynamic TLS accesses. 233 | if (TM->getTargetTriple().isOSBinFormatELF() && 234 | getOptLevel() != CodeGenOpt::None) 235 | addPass(createCleanupLocalDynamicTLSPass()); 236 | 237 | addPass(createX86GlobalBaseRegPass()); 238 | 239 | return false; 240 | } 241 | 242 | bool X86PassConfig::addILPOpts() { 243 | addPass(&EarlyIfConverterID); 244 | if (EnableMachineCombinerPass) 245 | addPass(&MachineCombinerID); 246 | return true; 247 | } 248 | 249 | bool X86PassConfig::addPreISel() { 250 | // Only add this pass for 32-bit x86 Windows. 251 | const Triple &TT = TM->getTargetTriple(); 252 | if (TT.isOSWindows() && TT.getArch() == Triple::x86) 253 | addPass(createX86WinEHStatePass()); 254 | return true; 255 | } 256 | 257 | void X86PassConfig::addPreRegAlloc() { 258 | if (getOptLevel() != CodeGenOpt::None) 259 | addPass(createX86OptimizeLEAs()); 260 | 261 | addPass(createX86CallFrameOptimization()); 262 | } 263 | 264 | void X86PassConfig::addPostRegAlloc() { 265 | addPass(createX86FloatingPointStackifierPass()); 266 | } 267 | 268 | void X86PassConfig::addPreSched2() { addPass(createX86ExpandPseudoPass()); } 269 | 270 | void X86PassConfig::addPreEmitPass() { 271 | if (getOptLevel() != CodeGenOpt::None) 272 | addPass(createExecutionDependencyFixPass(&X86::VR128RegClass)); 273 | 274 | if (UseVZeroUpper) 275 | addPass(createX86IssueVZeroUpperPass()); 276 | 277 | if (getOptLevel() != CodeGenOpt::None) { 278 | addPass(createX86PadShortFunctions()); 279 | addPass(createX86FixupLEAs()); 280 | } 281 | 282 | addPass(createX86TestPass()); 283 | } 284 | -------------------------------------------------------------------------------- /LL(1)-ACMProblem/UVa134/134 - Loglan-A Logical Language.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | using namespace std; 13 | 14 | class Production { 15 | public: 16 | string LHS; 17 | vector RHS; 18 | int label; 19 | 20 | Production(string L = "", vector R = vector()) { 21 | LHS = L; 22 | RHS = R; 23 | } 24 | 25 | void print() { 26 | printf("%s -> ", LHS.c_str()); 27 | for(size_t i = 0; i < RHS.size(); i++) 28 | printf("%s", RHS[i].c_str()); 29 | } 30 | }; 31 | class Grammar { 32 | public: 33 | static const string lambda; 34 | string start_symbol; 35 | vector rules; 36 | map > first_set; 37 | map > follow_set; 38 | map derives_lambda; 39 | map > lltable; 40 | 41 | map mark_lambda(); 42 | void fill_first_set(); 43 | void fill_follow_set(); 44 | bool isNonterminal(string token); 45 | set compute_first(vector rhs); 46 | set get_predict_set(Production p); 47 | void fill_lltable(); 48 | void lldriver(queue tokens); 49 | }; 50 | const string Grammar::lambda("l"); 51 | 52 | set Grammar::compute_first(vector rhs) { 53 | set result; 54 | size_t i; 55 | 56 | if(rhs.size() == 0 || rhs[0] == Grammar::lambda) { 57 | result.insert(Grammar::lambda); 58 | } else { 59 | result = first_set[rhs[0]]; 60 | for(i = 1; i < rhs.size() && 61 | first_set[rhs[i-1]].find(Grammar::lambda) != first_set[rhs[i-1]].end(); i++) { 62 | set f = first_set[rhs[i]]; 63 | f.erase(Grammar::lambda); 64 | result.insert(f.begin(), f.end()); 65 | } 66 | if(i == rhs.size() 67 | && first_set[rhs[i-1]].find(Grammar::lambda) != first_set[rhs[i-1]].end()) { 68 | result.insert(Grammar::lambda); 69 | } else { 70 | result.erase(Grammar::lambda); 71 | } 72 | } 73 | 74 | return result; 75 | } 76 | /* 77 | * please call get_predict_set() after fill_follow_set() and fill_first_set() 78 | */ 79 | set Grammar::get_predict_set(Production p) { 80 | set result; 81 | set rfirst; 82 | 83 | rfirst = compute_first(p.RHS); 84 | if(rfirst.find(Grammar::lambda) != rfirst.end()) { 85 | rfirst.erase(Grammar::lambda); 86 | result.insert(rfirst.begin(), rfirst.end()); 87 | rfirst = follow_set[p.LHS]; 88 | result.insert(rfirst.begin(), rfirst.end()); 89 | } else { 90 | result.insert(rfirst.begin(), rfirst.end()); 91 | } 92 | 93 | return result; 94 | } 95 | /* 96 | * 97 | */ 98 | void Grammar::fill_lltable() { 99 | string A; // nonterminal 100 | Production p; 101 | 102 | for(size_t i = 0; i < rules.size(); i++) { 103 | p = rules[i]; 104 | A = p.LHS; 105 | set predict_set = get_predict_set(p); 106 | 107 | for(set::iterator it = predict_set.begin(); 108 | it != predict_set.end(); it++) { 109 | assert(lltable[A].find(*it) == lltable[A].end()); 110 | lltable[A][*it] = p; 111 | } 112 | } 113 | 114 | } 115 | bool Grammar::isNonterminal(string token) { 116 | 117 | if(token[0] == '<' && token[token.length() - 1] == '>') 118 | return true; 119 | return false; 120 | 121 | } 122 | map Grammar::mark_lambda() { 123 | bool rhs_derives_lambda; 124 | bool changes; 125 | Production p; 126 | 127 | derives_lambda.clear(); 128 | 129 | /* initially, nothing is marked. */ 130 | for(size_t i = 0; i < rules.size(); i++) { 131 | derives_lambda[rules[i].LHS] = false; 132 | } 133 | do { 134 | changes = false; 135 | for(size_t i = 0; i < rules.size(); i++) { 136 | p = rules[i]; 137 | if(!derives_lambda[p.LHS]) { 138 | if(p.RHS.size() == 0 || p.RHS[0] == Grammar::lambda) { 139 | changes = derives_lambda[p.LHS] = true; 140 | continue; 141 | } 142 | /* does each part of RHS derive lambda ? */ 143 | rhs_derives_lambda = derives_lambda[string(p.RHS[0])]; 144 | for(size_t j = 1; j < p.RHS.size(); j++) { 145 | rhs_derives_lambda &= derives_lambda[p.RHS[j]]; 146 | } 147 | if(rhs_derives_lambda) { 148 | changes = true; 149 | derives_lambda[p.LHS] = true; 150 | } 151 | } 152 | } 153 | } while(changes); 154 | return derives_lambda; 155 | } 156 | void Grammar::fill_first_set() { 157 | 158 | string A; // nonterminal 159 | string a; // terminal 160 | Production p; 161 | bool changes; 162 | 163 | mark_lambda(); 164 | first_set.clear(); 165 | 166 | for(size_t i = 0; i < rules.size(); i++) { 167 | A = rules[i].LHS; 168 | if(derives_lambda[A]) 169 | first_set[A].insert(Grammar::lambda); 170 | } 171 | 172 | for(size_t i = 0; i < rules.size(); i++) { 173 | for(size_t j = 0; j < rules[i].RHS.size(); j++) { 174 | a = rules[i].RHS[j]; 175 | if(!isNonterminal(a)) { 176 | if(a != Grammar::lambda) 177 | first_set[a].insert(a); 178 | if(j == 0) { // A -> aXX 179 | first_set[rules[i].LHS].insert(a); 180 | } 181 | } 182 | } 183 | } 184 | 185 | do { 186 | changes = false; 187 | for(size_t i = 0; i < rules.size(); i++) { 188 | p = rules[i]; 189 | set rfirst = compute_first(p.RHS); 190 | size_t oldsize = first_set[p.LHS].size(); 191 | first_set[p.LHS].insert(rfirst.begin(), rfirst.end()); 192 | size_t newsize = first_set[p.LHS].size(); 193 | if(oldsize != newsize) 194 | changes = true; 195 | } 196 | } while(changes); 197 | } 198 | 199 | void Grammar::fill_follow_set() { 200 | string A, B; // nonterminal 201 | Production p; 202 | bool changes; 203 | 204 | for(size_t i = 0; i < rules.size(); i++) { 205 | A = rules[i].LHS; 206 | follow_set[A].clear(); 207 | } 208 | 209 | follow_set[start_symbol].insert(Grammar::lambda); 210 | 211 | do { 212 | changes = false; 213 | for(size_t i = 0; i < rules.size(); i++) { 214 | /* A -> a B b 215 | * I.e. for each production and each occurrence 216 | * of a nonterminal in its right-hand side. 217 | */ 218 | p = rules[i]; 219 | A = p.LHS; 220 | for(size_t j = 0; j < p.RHS.size(); j++) { 221 | B = p.RHS[j]; 222 | if(isNonterminal(B)) { 223 | vector beta(p.RHS.begin() + j + 1, p.RHS.end()); 224 | set rfirst = compute_first(beta); 225 | size_t oldsize = follow_set[B].size(); 226 | 227 | if(rfirst.find(Grammar::lambda) == rfirst.end()) { 228 | follow_set[B].insert(rfirst.begin(), rfirst.end()); 229 | } else { 230 | rfirst.erase(Grammar::lambda); 231 | follow_set[B].insert(rfirst.begin(), rfirst.end()); 232 | rfirst = follow_set[A]; 233 | follow_set[B].insert(rfirst.begin(), rfirst.end()); 234 | } 235 | size_t newsize = follow_set[B].size(); 236 | if(oldsize != newsize) 237 | changes = true; 238 | } 239 | } 240 | } 241 | } while(changes); 242 | } 243 | 244 | void Grammar::lldriver(queue tokens) { 245 | stack stk; 246 | string X; 247 | string a; 248 | Production p; 249 | /* Push the Start Symbol onto an empty stack */ 250 | stk.push(start_symbol); 251 | 252 | while(!stk.empty() && !tokens.empty()) { 253 | X = stk.top(); 254 | a = tokens.front(); 255 | // cout << X << " " << a << endl; 256 | if(isNonterminal(X) && lltable[X].find(a) != lltable[X].end()) { 257 | p = lltable[X][a]; 258 | stk.pop(); 259 | for(int i = p.RHS.size() - 1; i >= 0; i--) { 260 | if(p.RHS[i] == Grammar::lambda) 261 | continue; 262 | stk.push(p.RHS[i]); 263 | } 264 | } else if(X == a) { 265 | stk.pop(); 266 | tokens.pop(); 267 | } else if(lltable[X].find(Grammar::lambda) != lltable[X].end()) { 268 | stk.pop(); 269 | } else { 270 | /* Process syntax error. */ 271 | puts("Bad!"); 272 | return; 273 | } 274 | } 275 | while(!stk.empty()) { 276 | X = stk.top(); 277 | if(lltable[X].find(Grammar::lambda) != lltable[X].end()) 278 | stk.pop(); 279 | else 280 | break; 281 | } 282 | if(tokens.size() == 0 && stk.size() == 0) 283 | puts("Good"); 284 | else 285 | puts("Bad!"); 286 | return; 287 | } 288 | int aVowel(char c) { 289 | switch(c) { 290 | case 'a':case 'e':case 'i':case 'o':case 'u': 291 | return 1; 292 | } 293 | return 0; 294 | } 295 | string token2symbol(const string &str) { 296 | int n = str.length(); 297 | if (!islower(str[n - 1]) || !aVowel(str[n - 1])) { 298 | return "NAM"; 299 | } 300 | switch (n) { 301 | case 1: return "A"; 302 | case 5: 303 | n = aVowel(str[4]); 304 | n |= ((aVowel(str[0]) << 4) | (aVowel(str[1]) << 3)); 305 | n |= ((aVowel(str[2]) << 2) | (aVowel(str[3]) << 1)); 306 | return (n == 5 || n == 9) ? "PREDA" : "UN"; 307 | case 2: 308 | switch (str[0]) { 309 | case 'g': return "MOD"; 310 | case 'b': return "BA"; 311 | case 'd': return "DA"; 312 | case 'l': return "LA"; 313 | } 314 | } 315 | return "UN"; 316 | } 317 | void parsingProduction(string r, Grammar &g) { 318 | static int production_label = 0; 319 | stringstream sin(r); 320 | string lhs, foo; 321 | vector tokens; 322 | sin >> lhs >> foo; 323 | while(sin >> foo) 324 | tokens.push_back(foo); 325 | Production p(lhs, tokens); 326 | p.label = ++production_label; 327 | g.rules.push_back(p); 328 | } 329 | 330 | int main() { 331 | Grammar g; 332 | parsingProduction(" -> ", g); 333 | parsingProduction(" -> DA ", g); 334 | parsingProduction(" -> ", g); 335 | parsingProduction(" -> ", g); 336 | parsingProduction(" -> ", g); 337 | parsingProduction(" -> BA ", g); 338 | parsingProduction(" -> DA ", g); 339 | parsingProduction(" -> ", g); 340 | parsingProduction(" -> ", g); 341 | parsingProduction(" -> A ", g); 342 | parsingProduction(" -> l", g); 343 | parsingProduction(" -> LA ", g); 344 | parsingProduction(" -> NAM", g); 345 | parsingProduction(" -> PREDA ", g); 346 | parsingProduction(" -> PREDA ", g); 347 | parsingProduction(" -> l", g); 348 | parsingProduction(" -> ", g); 349 | parsingProduction(" -> ", g); 350 | parsingProduction(" -> l", g); 351 | parsingProduction(" -> MOD ", g); 352 | 353 | g.start_symbol = ""; 354 | 355 | g.fill_first_set(); 356 | g.fill_follow_set(); 357 | g.fill_lltable(); 358 | 359 | queue SYMBOL; 360 | for(string token; cin >> token && token != "#";) { 361 | size_t pos = token.find('.'); 362 | if(pos == string::npos) { 363 | SYMBOL.push(token2symbol(token)); 364 | //cout << token2symbol(token) << " "; 365 | continue; 366 | } 367 | token.erase(token.length() - 1); 368 | //cout << token2symbol(token) << endl; 369 | if(token.length() > 0) 370 | SYMBOL.push(token2symbol(token)); 371 | g.lldriver(SYMBOL); 372 | 373 | while(!SYMBOL.empty()) 374 | SYMBOL.pop(); 375 | } 376 | return 0; 377 | } 378 | -------------------------------------------------------------------------------- /hw1-NFA2DFA/RegexToNFA[simple][v3].cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | using namespace std; 12 | class State { 13 | public: 14 | State(int ac=0) { 15 | accepted = ac; 16 | } 17 | bool accepted; 18 | int nameLabel; 19 | map > trans; 20 | }; 21 | class DFA { 22 | public: 23 | State* Q0; 24 | vector Q, F; 25 | }; 26 | class NFA { 27 | public: 28 | static char lambda; 29 | State* Q0; 30 | vector Q; 31 | vector F; 32 | vector< vector > make_deterministic(DFA &M, vector alpha); 33 | static NFA getNFAbyString(const char str[]); 34 | static NFA getNFA_Star(NFA nfa); 35 | static NFA getNFA_OR(NFA n1, NFA n2); 36 | static NFA getNFA_AND(NFA n1, NFA n2); 37 | void print(); 38 | void printTable(); 39 | void buildLabel(); 40 | private: 41 | vector getSetOf(vector set_of_states, char c); 42 | vector getClose(vector set_of_states); 43 | }; 44 | char NFA::lambda = 0; 45 | vector NFA::getSetOf(vector set_of_states, char c) { 46 | set h; 47 | vector ret; 48 | queue q; 49 | State* index; 50 | for(int i = 0; i < set_of_states.size(); i++) { 51 | index = set_of_states[i]; 52 | q.push(index); 53 | } 54 | while(!q.empty()) { 55 | index = q.front(), q.pop(); 56 | vector state_trans = index->trans[c]; 57 | for(int i = 0; i < state_trans.size(); i++) { 58 | if(h.find(state_trans[i]) == h.end()) { 59 | h.insert(state_trans[i]); 60 | q.push(state_trans[i]); 61 | ret.push_back(state_trans[i]); 62 | } 63 | } 64 | } 65 | return ret; 66 | } 67 | /* 68 | * Add to S all states reachable from it 69 | * using only lembda transitions of N 70 | */ 71 | vector NFA::getClose(vector set_of_states) { 72 | set h; 73 | vector ret; 74 | queue q; 75 | State* index; 76 | for(int i = 0; i < set_of_states.size(); i++) { 77 | index = set_of_states[i]; 78 | q.push(index), h.insert(index); 79 | } 80 | while(!q.empty()) { 81 | index = q.front(), q.pop(); 82 | ret.push_back(index); 83 | vector state_trans = index->trans[NFA::lambda]; 84 | for(int i = 0; i < state_trans.size(); i++) { 85 | if(h.find(state_trans[i]) == h.end()) { 86 | h.insert(state_trans[i]); 87 | q.push(state_trans[i]); 88 | } 89 | } 90 | } 91 | sort(ret.begin(), ret.end()); 92 | return ret; 93 | } 94 | vector< vector > NFA::make_deterministic(DFA &M, vector alpha) { 95 | vector< vector > T; 96 | vector stateSet; 97 | stateSet.push_back(Q0); 98 | vector init_state = getClose(stateSet); 99 | T.push_back(init_state); 100 | M.Q.push_back(new State()); 101 | for(int i = 0; i < T.size(); i++) { 102 | State* state = M.Q[i]; 103 | for(int j = 0; j < T[i].size(); j++) 104 | if(T[i][j]->accepted) 105 | state->accepted = 1; 106 | state->nameLabel = i; 107 | if(state->accepted) M.F.push_back(state); 108 | for(int j = 0; j < alpha.size(); j++) { 109 | if(alpha[j] == NFA::lambda) 110 | continue; 111 | vector next_state = getSetOf(T[i], alpha[j]); 112 | next_state = getClose(next_state); 113 | int existIdx = -1; 114 | for(int k = 0; k < T.size(); k++) { 115 | if(T[k] == next_state) { 116 | existIdx = k; 117 | break; 118 | } 119 | } 120 | if(existIdx < 0) { 121 | T.push_back(next_state); 122 | M.Q.push_back(new State()); 123 | existIdx = T.size()-1; 124 | } 125 | M.Q[i]->trans[alpha[j]].push_back(M.Q[existIdx]); 126 | } 127 | } 128 | M.Q0 = M.Q[0]; 129 | return T; 130 | } 131 | 132 | NFA NFA::getNFAbyString(const char str[]) { 133 | NFA ret; 134 | ret.Q.push_back(new State()); 135 | ret.Q0 = ret.Q[0]; 136 | for(int i = 0; str[i]; i++) { 137 | ret.Q.push_back(new State()); 138 | ret.Q[i]->trans[str[i]].push_back(ret.Q[i+1]); 139 | } 140 | ret.Q[ret.Q.size()-1]->accepted = 1; 141 | ret.F.push_back(ret.Q[ret.Q.size()-1]); 142 | return ret; 143 | } 144 | 145 | NFA NFA::getNFA_Star(NFA nfa) { 146 | State *s1, *s2; 147 | s1 = new State(); 148 | s2 = new State(true); 149 | for(int i = 0; i < nfa.F.size(); i++) { 150 | nfa.F[i]->accepted = 0; 151 | nfa.F[i]->trans[NFA::lambda].push_back(s2); 152 | nfa.F[i]->trans[NFA::lambda].push_back(nfa.Q0); 153 | } 154 | s1->trans[NFA::lambda].push_back(nfa.Q0); 155 | s1->trans[NFA::lambda].push_back(s2); 156 | nfa.F.clear(); 157 | nfa.F.push_back(s2); 158 | nfa.Q.push_back(s1); 159 | nfa.Q.push_back(s2); 160 | nfa.Q0 = s1; 161 | return nfa; 162 | } 163 | 164 | NFA NFA::getNFA_OR(NFA n1, NFA n2) { 165 | State *s1, *s2; 166 | s1 = new State(); 167 | s2 = new State(true); 168 | s1->trans[NFA::lambda].push_back(n1.Q0); 169 | s1->trans[NFA::lambda].push_back(n2.Q0); 170 | for(int i = 0; i < n1.F.size(); i++) { 171 | n1.F[i]->accepted = 0; 172 | n1.F[i]->trans[NFA::lambda].push_back(s2); 173 | } 174 | n1.F.clear(); 175 | for(int i = 0; i < n2.F.size(); i++) { 176 | n2.F[i]->accepted = 0; 177 | n2.F[i]->trans[NFA::lambda].push_back(s2); 178 | } 179 | for(int i = 0; i < n2.Q.size(); i++) 180 | n1.Q.push_back(n2.Q[i]); 181 | n1.F.push_back(s2); 182 | n1.Q.push_back(s1); 183 | n1.Q.push_back(s2); 184 | n1.Q0 = s1; 185 | return n1; 186 | } 187 | NFA NFA::getNFA_AND(NFA n1, NFA n2) { 188 | for(int i = 0; i < n1.F.size(); i++) { 189 | n1.F[i]->accepted = 0; 190 | n1.F[i]->trans[NFA::lambda].push_back(n2.Q0); 191 | } 192 | n1.F.clear(); 193 | for(int i = 0; i < n2.F.size(); i++) 194 | n1.F.push_back(n2.F[i]); 195 | for(int i = 0; i < n2.Q.size(); i++) 196 | n1.Q.push_back(n2.Q[i]); 197 | return n1; 198 | } 199 | bool cmp(const State* a, const State* b) { 200 | return a->nameLabel < b->nameLabel; 201 | } 202 | void NFA::print() { 203 | printf("start[%d]\n", Q0->nameLabel); 204 | for(int i = 0; i < F.size(); i++) { 205 | printf("F[%d]", F[i]->nameLabel); 206 | } 207 | puts(""); 208 | sort(Q.begin(), Q.end(), cmp); 209 | for(int i = 0; i < Q.size(); i++) { 210 | printf("Q[%d] : ", Q[i]->nameLabel); 211 | for(map >::iterator it = Q[i]->trans.begin(); 212 | it != Q[i]->trans.end(); it++) { 213 | printf("[%c,", it->first == 0 ? '~' : it->first); 214 | for(vector::iterator jt = it->second.begin(); 215 | jt != it->second.end(); jt++) { 216 | printf(" %d", (*jt)->nameLabel); 217 | } 218 | printf("]"); 219 | } 220 | puts(""); 221 | } 222 | } 223 | void NFA::printTable() { 224 | set alpha; 225 | sort(Q.begin(), Q.end(), cmp); 226 | for(int i = 0; i < Q.size(); i++) { 227 | for(map >::iterator it = Q[i]->trans.begin(); 228 | it != Q[i]->trans.end(); it++) { 229 | alpha.insert(it->first); 230 | } 231 | } 232 | for(set::iterator it = alpha.begin(); it != alpha.end(); it++) { 233 | putchar(it == alpha.begin() ? '(' : ','); 234 | if(*it == NFA::lambda) printf("l"); 235 | else printf("%c", *it); 236 | } 237 | puts(")"); 238 | for(int i = 0; i < Q.size(); i++) { 239 | for(set::iterator it = alpha.begin(); 240 | it != alpha.end(); it++) { 241 | vector &v = Q[i]->trans[*it]; 242 | if(v.size() == 0) 243 | printf(Q[i]->accepted ? "(*)" : "(0)"); 244 | else { 245 | printf("(%s", Q[i]->accepted ? "*" : ""); 246 | sort(v.begin(), v.end(), cmp); 247 | for(int j = 0; j < v.size(); j++) { 248 | printf("%d%c", v[j]->nameLabel+1, j == v.size()-1 ? ')' : ','); 249 | } 250 | } 251 | } 252 | puts(""); 253 | } 254 | } 255 | 256 | void NFA::buildLabel() { 257 | set R; 258 | queue Q; 259 | int labelIdx = 0; 260 | Q.push(Q0), R.insert(Q0); 261 | while(!Q.empty()) { 262 | State* node = Q.front(); 263 | Q.pop(); 264 | node->nameLabel = labelIdx++; 265 | for(map >::iterator it = node->trans.begin(); 266 | it != node->trans.end(); it++) { 267 | for(vector::iterator jt = it->second.begin(); 268 | jt != it->second.end(); jt++) { 269 | if(R.find(*jt) == R.end()) { 270 | R.insert(*jt); 271 | Q.push(*jt); 272 | } 273 | } 274 | } 275 | } 276 | } 277 | int priority_op(char c) { 278 | switch(c) { 279 | case '(':return 0; 280 | case '*':return 1; 281 | case '|':case '+':return 2; 282 | } 283 | return -1; 284 | } 285 | void trans(char infix[], char buffer[]) { 286 | int len = strlen(infix); 287 | char *ptr = buffer; 288 | stack op; 289 | stack elem; 290 | elem.push(0); 291 | *ptr = '\0'; 292 | for(int i = 0; i < len; i++) { 293 | if(infix[i] >= 'a' && infix[i] <= 'z') { 294 | while(!op.empty() && op.top() == '*') { 295 | sprintf(ptr, "* ", op.top()), op.pop(); 296 | while(*ptr) ptr++; 297 | } 298 | while(infix[i] >= 'a' && infix[i] <= 'z' && i < len) { 299 | sprintf(ptr, "%c", infix[i]); 300 | while(*ptr) ptr++; 301 | i++; 302 | } 303 | i--; 304 | sprintf(ptr, " "); 305 | while(*ptr) ptr++; 306 | elem.top()++; 307 | }else { 308 | if(infix[i] == ')') { 309 | while(!op.empty() && op.top() != '(') { 310 | if(op.top() == '|') elem.top()--; 311 | sprintf(ptr, "%c ", op.top()), op.pop(); 312 | while(*ptr) ptr++; 313 | } 314 | while(elem.top() > 1) { 315 | sprintf(ptr, "+ "); 316 | while(*ptr) ptr++; 317 | elem.top()--; 318 | } 319 | elem.pop(); 320 | elem.top()++; 321 | op.pop(); 322 | } else { 323 | if(infix[i] != '(') { 324 | while(!op.empty() && priority_op(op.top()) >= priority_op(infix[i])) { 325 | sprintf(ptr, "%c ", op.top()), op.pop(); 326 | while(*ptr) ptr++; 327 | } 328 | } else { 329 | while(!op.empty() && op.top() == '*') { 330 | sprintf(ptr, "* ", op.top()), op.pop(); 331 | while(*ptr) ptr++; 332 | } 333 | elem.push(0); 334 | } 335 | op.push(infix[i]); 336 | } 337 | } 338 | } 339 | while(!op.empty()) { 340 | sprintf(ptr, "%c ", op.top()), op.pop(); 341 | while(*ptr) ptr++; 342 | } 343 | while(elem.top() > 1) { 344 | sprintf(ptr, "+ "); 345 | while(*ptr) ptr++; 346 | elem.top()--; 347 | } 348 | elem.pop(); 349 | } 350 | NFA calcPostfix(char postfix[]) { 351 | int len = strlen(postfix); 352 | stack stk; 353 | stringstream sin(postfix); 354 | string token; 355 | while(sin >> token) { 356 | if(token[0] == '*') { 357 | NFA a; 358 | a = stk.top(), stk.pop(); 359 | stk.push(NFA::getNFA_Star(a)); 360 | } else if(token[0] == '|' || token[0] == '+') { 361 | NFA a, b; 362 | b = stk.top(), stk.pop(); 363 | a = stk.top(), stk.pop(); 364 | switch(token[0]) { 365 | case '|':stk.push(NFA::getNFA_OR(a, b));break; 366 | case '+':stk.push(NFA::getNFA_AND(a, b));break; 367 | } 368 | } else { 369 | stk.push(NFA::getNFAbyString(token.c_str())); 370 | } 371 | } 372 | return stk.top(); 373 | } 374 | int main() { 375 | char s[1024], postfix[1024]; 376 | while(scanf("%s", s) == 1) { 377 | trans(s, postfix); 378 | // puts(postfix); 379 | NFA ret = calcPostfix(postfix); 380 | ret.buildLabel(); 381 | ret.printTable(); 382 | } 383 | return 0; 384 | } 385 | /* 386 | // strings ending with a 387 | (a|b)*a 388 | // strings ending with bb 389 | (a|b)*bb 390 | // strings ending with b and not containing aa 391 | (b)*(ab(b)*)*b 392 | 393 | (aaaa|b)* 394 | 395 | a*((ba)*baa)*b* 396 | 397 | an(ba)*bn 398 | 399 | (b|bba)*a 400 | 401 | */ 402 | -------------------------------------------------------------------------------- /bonus1_100502205_v1/CFG_FollowSet.cpp: -------------------------------------------------------------------------------- 1 | // http://morris821028.github.io/2014/05/11/compiler-clg-ll%281%29/ 2 | // more ... 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | using namespace std; 16 | 17 | // #define HTMLProduction 18 | 19 | class Production { 20 | public: 21 | string LHS; 22 | vector RHS; 23 | int label; 24 | 25 | Production(string L = "", vector R = vector()) { 26 | LHS = L; 27 | RHS = R; 28 | } 29 | 30 | void print() { 31 | printf("%s->", LHS.c_str()); 32 | for(size_t i = 0; i < RHS.size(); i++) 33 | printf("%s", RHS[i].c_str()); 34 | } 35 | }; 36 | class Grammar { 37 | public: 38 | static const string lambda; 39 | string start_symbol; 40 | vector rules; 41 | map > first_set; 42 | map > follow_set; 43 | map derives_lambda; 44 | map > lltable; 45 | 46 | map mark_lambda(); 47 | void fill_first_set(); 48 | void fill_follow_set(); 49 | bool isNonterminal(string token); 50 | set compute_first(vector rhs); 51 | set get_predict_set(Production p); 52 | void fill_lltable(); 53 | void lldriver(queue tokens); 54 | }; 55 | const string Grammar::lambda("l"); 56 | 57 | set Grammar::compute_first(vector rhs) { 58 | set result; 59 | size_t i; 60 | 61 | if(rhs.size() == 0 || rhs[0] == Grammar::lambda) { 62 | result.insert(Grammar::lambda); 63 | } else { 64 | result = first_set[rhs[0]]; 65 | for(i = 1; i < rhs.size() && 66 | first_set[rhs[i-1]].find(Grammar::lambda) != first_set[rhs[i-1]].end(); i++) { 67 | set f = first_set[rhs[i]]; 68 | f.erase(Grammar::lambda); 69 | result.insert(f.begin(), f.end()); 70 | } 71 | if(i == rhs.size() 72 | && first_set[rhs[i-1]].find(Grammar::lambda) != first_set[rhs[i-1]].end()) { 73 | result.insert(Grammar::lambda); 74 | } else { 75 | result.erase(Grammar::lambda); 76 | } 77 | } 78 | 79 | return result; 80 | } 81 | /* 82 | * please call get_predict_set() after fill_follow_set() and fill_first_set() 83 | */ 84 | set Grammar::get_predict_set(Production p) { 85 | set result; 86 | set rfirst; 87 | 88 | rfirst = compute_first(p.RHS); 89 | if(rfirst.find(Grammar::lambda) != rfirst.end()) { 90 | rfirst.erase(Grammar::lambda); 91 | result.insert(rfirst.begin(), rfirst.end()); 92 | rfirst = follow_set[p.LHS]; 93 | result.insert(rfirst.begin(), rfirst.end()); 94 | } else { 95 | result.insert(rfirst.begin(), rfirst.end()); 96 | } 97 | 98 | return result; 99 | } 100 | /* 101 | * 102 | */ 103 | void Grammar::fill_lltable() { 104 | string A; // nonterminal 105 | Production p; 106 | 107 | for(size_t i = 0; i < rules.size(); i++) { 108 | p = rules[i]; 109 | A = p.LHS; 110 | set predict_set = get_predict_set(p); 111 | 112 | for(set::iterator it = predict_set.begin(); 113 | it != predict_set.end(); it++) { 114 | assert(lltable[A].find(*it) == lltable[A].end()); 115 | lltable[A][*it] = p; 116 | } 117 | } 118 | 119 | } 120 | bool Grammar::isNonterminal(string token) { 121 | 122 | #ifdef HTMLProduction 123 | if(token == Grammar::lambda) 124 | return false; 125 | if(token[0] == '<' && token[token.length() - 1] == '>') 126 | return true; 127 | return false; 128 | #else 129 | if(token == Grammar::lambda) 130 | return false; 131 | for(size_t i = 0; i < token.length(); i++) { 132 | if(isupper(token[i])) 133 | return true; 134 | } 135 | return false; 136 | #endif 137 | } 138 | map Grammar::mark_lambda() { 139 | bool rhs_derives_lambda; 140 | bool changes; 141 | Production p; 142 | 143 | derives_lambda.clear(); 144 | 145 | /* initially, nothing is marked. */ 146 | for(size_t i = 0; i < rules.size(); i++) { 147 | derives_lambda[rules[i].LHS] = false; 148 | } 149 | do { 150 | changes = false; 151 | for(size_t i = 0; i < rules.size(); i++) { 152 | p = rules[i]; 153 | if(!derives_lambda[p.LHS]) { 154 | if(p.RHS.size() == 0 || p.RHS[0] == Grammar::lambda) { 155 | changes = derives_lambda[p.LHS] = true; 156 | continue; 157 | } 158 | /* does each part of RHS derive lambda ? */ 159 | rhs_derives_lambda = derives_lambda[string(p.RHS[0])]; 160 | for(size_t j = 1; j < p.RHS.size(); j++) { 161 | rhs_derives_lambda &= derives_lambda[p.RHS[j]]; 162 | } 163 | if(rhs_derives_lambda) { 164 | changes = true; 165 | derives_lambda[p.LHS] = true; 166 | } 167 | } 168 | } 169 | } while(changes); 170 | return derives_lambda; 171 | } 172 | void Grammar::fill_first_set() { 173 | 174 | string A; // nonterminal 175 | string a; // terminal 176 | Production p; 177 | bool changes; 178 | 179 | mark_lambda(); 180 | first_set.clear(); 181 | 182 | for(size_t i = 0; i < rules.size(); i++) { 183 | A = rules[i].LHS; 184 | if(derives_lambda[A]) 185 | first_set[A].insert(Grammar::lambda); 186 | } 187 | 188 | for(size_t i = 0; i < rules.size(); i++) { 189 | for(size_t j = 0; j < rules[i].RHS.size(); j++) { 190 | a = rules[i].RHS[j]; 191 | if(!isNonterminal(a)) { 192 | if(a != Grammar::lambda) 193 | first_set[a].insert(a); 194 | if(j == 0) { // A -> aXX 195 | first_set[rules[i].LHS].insert(a); 196 | } 197 | } 198 | } 199 | } 200 | 201 | do { 202 | changes = false; 203 | for(size_t i = 0; i < rules.size(); i++) { 204 | p = rules[i]; 205 | set rfirst = compute_first(p.RHS); 206 | size_t oldsize = first_set[p.LHS].size(); 207 | first_set[p.LHS].insert(rfirst.begin(), rfirst.end()); 208 | size_t newsize = first_set[p.LHS].size(); 209 | if(oldsize != newsize) 210 | changes = true; 211 | } 212 | } while(changes); 213 | } 214 | 215 | void Grammar::fill_follow_set() { 216 | string A, B; // nonterminal 217 | Production p; 218 | bool changes; 219 | 220 | for(size_t i = 0; i < rules.size(); i++) { 221 | A = rules[i].LHS; 222 | follow_set[A].clear(); 223 | } 224 | 225 | follow_set[start_symbol].insert(Grammar::lambda); 226 | 227 | do { 228 | changes = false; 229 | for(size_t i = 0; i < rules.size(); i++) { 230 | /* A -> a B b 231 | * I.e. for each production and each occurrence 232 | * of a nonterminal in its right-hand side. 233 | */ 234 | p = rules[i]; 235 | A = p.LHS; 236 | for(size_t j = 0; j < p.RHS.size(); j++) { 237 | B = p.RHS[j]; 238 | if(isNonterminal(B)) { 239 | vector beta(p.RHS.begin() + j + 1, p.RHS.end()); 240 | set rfirst = compute_first(beta); 241 | size_t oldsize = follow_set[B].size(); 242 | 243 | if(rfirst.find(Grammar::lambda) == rfirst.end()) { 244 | follow_set[B].insert(rfirst.begin(), rfirst.end()); 245 | } else { 246 | rfirst.erase(Grammar::lambda); 247 | follow_set[B].insert(rfirst.begin(), rfirst.end()); 248 | rfirst = follow_set[A]; 249 | follow_set[B].insert(rfirst.begin(), rfirst.end()); 250 | } 251 | size_t newsize = follow_set[B].size(); 252 | if(oldsize != newsize) 253 | changes = true; 254 | } 255 | } 256 | } 257 | } while(changes); 258 | } 259 | 260 | void Grammar::lldriver(queue tokens) { 261 | stack stk; 262 | string X; 263 | string a; 264 | Production p; 265 | /* Push the Start Symbol onto an empty stack */ 266 | stk.push(start_symbol); 267 | 268 | while(!stk.empty()) { 269 | X = stk.top(); 270 | a = tokens.front(); 271 | if(isNonterminal(X) && lltable[X].find(a) != lltable[X].end()) { 272 | p = lltable[X][a]; 273 | stk.pop(); 274 | for(int i = p.RHS.size() - 1; i >= 0; i--) { 275 | if(p.RHS[i] == Grammar::lambda) 276 | continue; 277 | stk.push(p.RHS[i]); 278 | } 279 | } else if(X == a) { 280 | stk.pop(); 281 | tokens.pop(); 282 | } else { 283 | /* Process syntax error. */ 284 | puts("Process syntax error"); 285 | return; 286 | } 287 | } 288 | if(tokens.size() == 0) 289 | puts("Process syntax accept"); 290 | else 291 | puts("Process syntax error"); 292 | return; 293 | } 294 | 295 | queue getTokens(char s[]) { 296 | stringstream sin(s); 297 | queue tokens; 298 | string token; 299 | while(sin >> token) 300 | tokens.push(token); 301 | return tokens; 302 | } 303 | 304 | void parsingProduction(string r, Grammar &g) { 305 | #ifdef HTMLProduction 306 | static int production_label = 0; 307 | stringstream sin(r); 308 | string lhs, foo; 309 | vector tokens; 310 | sin >> lhs >> foo; 311 | while(sin >> foo) 312 | tokens.push_back(foo); 313 | Production p(lhs, tokens); 314 | p.label = ++production_label; 315 | g.rules.push_back(p); 316 | #else 317 | string div("->"); 318 | size_t found = r.find(div); 319 | if(found != std::string::npos) { 320 | string rhs = r.substr(found + div.length()); 321 | vector tokens; 322 | for(size_t i = 0; i < rhs.size(); i++) 323 | tokens.push_back(rhs.substr(i, 1)); 324 | Production p(r.substr(0, found), tokens); 325 | g.rules.push_back(p); 326 | } 327 | #endif 328 | } 329 | void readFirstSet(Grammar &g) { 330 | char in[1024]; 331 | while(gets(in) && in[0] != '\0') { 332 | 333 | string r(in); 334 | string div(":"); 335 | string token; 336 | size_t found = r.find(div); 337 | 338 | if(found != std::string::npos) { 339 | string lhs = r.substr(0, found); 340 | string rhs = r.substr(found + div.length()); 341 | std::replace(rhs.begin(), rhs.end(), ',', ' '); 342 | stringstream sin(rhs); 343 | while(sin >> token) { 344 | g.first_set[lhs].insert(token); 345 | } 346 | } 347 | } 348 | } 349 | 350 | void readFollowSet(Grammar &g) { 351 | char in[1024]; 352 | while(gets(in) && in[0] != '\0') { 353 | 354 | string r(in); 355 | string div(":"); 356 | string token; 357 | size_t found = r.find(div); 358 | 359 | if(found != std::string::npos) { 360 | string lhs = r.substr(0, found); 361 | string rhs = r.substr(found + div.length()); 362 | std::replace(rhs.begin(), rhs.end(), ',', ' '); 363 | stringstream sin(rhs); 364 | while(sin >> token) { 365 | g.follow_set[lhs].insert(token); 366 | } 367 | } 368 | } 369 | } 370 | int main() { 371 | 372 | freopen("input.txt", "r+t", stdin); 373 | freopen("output.txt", "w+t", stdout); 374 | 375 | char in[1024]; 376 | while(gets(in)) { 377 | Grammar g; 378 | parsingProduction(in, g); 379 | while(gets(in) && in[0] != '\0') { 380 | parsingProduction(in, g); 381 | } 382 | 383 | #ifdef HTMLProduction 384 | g.start_symbol = ""; 385 | #else 386 | g.start_symbol = g.rules[0].LHS; 387 | #endif 388 | 389 | g.fill_first_set(); 390 | g.fill_follow_set(); 391 | // g.fill_lltable(); 392 | #ifdef debug 393 | puts("+----------------+----- First set -----+"); 394 | for(map >::iterator it = g.first_set.begin(); 395 | it != g.first_set.end(); it++) { 396 | printf("|%-16s| {", it->first.c_str()); 397 | for(set::iterator jt = it->second.begin(); 398 | jt != it->second.end(); jt++) { 399 | cout << " " << *jt; 400 | } 401 | puts(" }"); 402 | } 403 | puts("+----------------+---------------------+\n"); 404 | puts("+----------------+----- Follow set -----+"); 405 | for(map >::iterator it = g.follow_set.begin(); 406 | it != g.follow_set.end(); it++) { 407 | printf("|%-16s| {", it->first.c_str()); 408 | for(set::iterator jt = it->second.begin(); 409 | jt != it->second.end(); jt++) { 410 | cout << " " << *jt; 411 | } 412 | puts(" }"); 413 | } 414 | #endif 415 | for(map >::iterator it = g.follow_set.begin(); 416 | it != g.follow_set.end(); it++) { 417 | printf("%s:", it->first.c_str()); 418 | int f = 0; 419 | for(set::iterator jt = it->second.begin(); 420 | jt != it->second.end(); jt++) { 421 | if(f) putchar(','); 422 | f = 1; 423 | cout << *jt; 424 | } 425 | puts(""); 426 | } 427 | } 428 | return 0; 429 | } 430 | /* 431 | A->aAe 432 | A->B 433 | B->bBe 434 | B->C 435 | C->cCe 436 | C->d 437 | 438 | A->BaAb 439 | A->cC 440 | B->d 441 | B->l 442 | C->eA 443 | C->l 444 | 445 | */ 446 | -------------------------------------------------------------------------------- /hw3-CFG-PredicSet/CFG_PredicSet.cpp: -------------------------------------------------------------------------------- 1 | // http://morris821028.github.io/2014/05/11/compiler-clg-ll%281%29/ 2 | // more ... 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | using namespace std; 16 | 17 | // #define HTMLProduction 18 | 19 | class Production { 20 | public: 21 | string LHS; 22 | vector RHS; 23 | int label; 24 | 25 | Production(string L = "", vector R = vector()) { 26 | LHS = L; 27 | RHS = R; 28 | } 29 | 30 | void print() { 31 | printf("%s->", LHS.c_str()); 32 | for(size_t i = 0; i < RHS.size(); i++) 33 | printf("%s", RHS[i].c_str()); 34 | } 35 | }; 36 | class Grammar { 37 | public: 38 | static const string lambda; 39 | string start_symbol; 40 | vector rules; 41 | map > first_set; 42 | map > follow_set; 43 | map derives_lambda; 44 | map > lltable; 45 | 46 | map mark_lambda(); 47 | void fill_first_set(); 48 | void fill_follow_set(); 49 | bool isNonterminal(string token); 50 | set compute_first(vector rhs); 51 | set get_predict_set(Production p); 52 | void fill_lltable(); 53 | void lldriver(queue tokens); 54 | }; 55 | const string Grammar::lambda("l"); 56 | 57 | set Grammar::compute_first(vector rhs) { 58 | set result; 59 | size_t i; 60 | 61 | if(rhs.size() == 0 || rhs[0] == Grammar::lambda) { 62 | result.insert(Grammar::lambda); 63 | } else { 64 | result = first_set[rhs[0]]; 65 | for(i = 1; i < rhs.size() && 66 | first_set[rhs[i-1]].find(Grammar::lambda) != first_set[rhs[i-1]].end(); i++) { 67 | set f = first_set[rhs[i]]; 68 | f.erase(Grammar::lambda); 69 | result.insert(f.begin(), f.end()); 70 | } 71 | if(i == rhs.size() 72 | && first_set[rhs[i-1]].find(Grammar::lambda) != first_set[rhs[i-1]].end()) { 73 | result.insert(Grammar::lambda); 74 | } else { 75 | result.erase(Grammar::lambda); 76 | } 77 | } 78 | 79 | return result; 80 | } 81 | /* 82 | * please call get_predict_set() after fill_follow_set() and fill_first_set() 83 | */ 84 | set Grammar::get_predict_set(Production p) { 85 | set result; 86 | set rfirst; 87 | 88 | rfirst = compute_first(p.RHS); 89 | if(rfirst.find(Grammar::lambda) != rfirst.end()) { 90 | rfirst.erase(Grammar::lambda); 91 | result.insert(rfirst.begin(), rfirst.end()); 92 | rfirst = follow_set[p.LHS]; 93 | result.insert(rfirst.begin(), rfirst.end()); 94 | } else { 95 | result.insert(rfirst.begin(), rfirst.end()); 96 | } 97 | 98 | return result; 99 | } 100 | /* 101 | * 102 | */ 103 | void Grammar::fill_lltable() { 104 | string A; // nonterminal 105 | Production p; 106 | 107 | for(size_t i = 0; i < rules.size(); i++) { 108 | p = rules[i]; 109 | A = p.LHS; 110 | set predict_set = get_predict_set(p); 111 | 112 | for(set::iterator it = predict_set.begin(); 113 | it != predict_set.end(); it++) { 114 | assert(lltable[A].find(*it) == lltable[A].end()); 115 | lltable[A][*it] = p; 116 | } 117 | } 118 | 119 | } 120 | bool Grammar::isNonterminal(string token) { 121 | 122 | #ifdef HTMLProduction 123 | if(token == Grammar::lambda) 124 | return false; 125 | if(token[0] == '<' && token[token.length() - 1] == '>') 126 | return true; 127 | return false; 128 | #else 129 | if(token == Grammar::lambda) 130 | return false; 131 | for(size_t i = 0; i < token.length(); i++) { 132 | if(isupper(token[i])) 133 | return true; 134 | } 135 | return false; 136 | #endif 137 | } 138 | map Grammar::mark_lambda() { 139 | bool rhs_derives_lambda; 140 | bool changes; 141 | Production p; 142 | 143 | derives_lambda.clear(); 144 | 145 | /* initially, nothing is marked. */ 146 | for(size_t i = 0; i < rules.size(); i++) { 147 | derives_lambda[rules[i].LHS] = false; 148 | } 149 | do { 150 | changes = false; 151 | for(size_t i = 0; i < rules.size(); i++) { 152 | p = rules[i]; 153 | if(!derives_lambda[p.LHS]) { 154 | if(p.RHS.size() == 0 || p.RHS[0] == Grammar::lambda) { 155 | changes = derives_lambda[p.LHS] = true; 156 | continue; 157 | } 158 | /* does each part of RHS derive lambda ? */ 159 | rhs_derives_lambda = derives_lambda[string(p.RHS[0])]; 160 | for(size_t j = 1; j < p.RHS.size(); j++) { 161 | rhs_derives_lambda &= derives_lambda[p.RHS[j]]; 162 | } 163 | if(rhs_derives_lambda) { 164 | changes = true; 165 | derives_lambda[p.LHS] = true; 166 | } 167 | } 168 | } 169 | } while(changes); 170 | return derives_lambda; 171 | } 172 | void Grammar::fill_first_set() { 173 | 174 | string A; // nonterminal 175 | string a; // terminal 176 | Production p; 177 | bool changes; 178 | 179 | mark_lambda(); 180 | first_set.clear(); 181 | 182 | for(size_t i = 0; i < rules.size(); i++) { 183 | A = rules[i].LHS; 184 | if(derives_lambda[A]) 185 | first_set[A].insert(Grammar::lambda); 186 | } 187 | 188 | for(size_t i = 0; i < rules.size(); i++) { 189 | for(size_t j = 0; j < rules[i].RHS.size(); j++) { 190 | a = rules[i].RHS[j]; 191 | if(!isNonterminal(a)) { 192 | if(a != Grammar::lambda) 193 | first_set[a].insert(a); 194 | if(j == 0) { // A -> aXX 195 | first_set[rules[i].LHS].insert(a); 196 | } 197 | } 198 | } 199 | } 200 | 201 | do { 202 | changes = false; 203 | for(size_t i = 0; i < rules.size(); i++) { 204 | p = rules[i]; 205 | set rfirst = compute_first(p.RHS); 206 | size_t oldsize = first_set[p.LHS].size(); 207 | first_set[p.LHS].insert(rfirst.begin(), rfirst.end()); 208 | size_t newsize = first_set[p.LHS].size(); 209 | if(oldsize != newsize) 210 | changes = true; 211 | } 212 | } while(changes); 213 | } 214 | 215 | void Grammar::fill_follow_set() { 216 | string A, B; // nonterminal 217 | Production p; 218 | bool changes; 219 | 220 | for(size_t i = 0; i < rules.size(); i++) { 221 | A = rules[i].LHS; 222 | follow_set[A].clear(); 223 | } 224 | 225 | follow_set[start_symbol].insert(Grammar::lambda); 226 | 227 | do { 228 | changes = false; 229 | for(size_t i = 0; i < rules.size(); i++) { 230 | /* A -> a B b 231 | * I.e. for each production and each occurrence 232 | * of a nonterminal in its right-hand side. 233 | */ 234 | p = rules[i]; 235 | A = p.LHS; 236 | for(size_t j = 0; j < p.RHS.size(); j++) { 237 | B = p.RHS[j]; 238 | if(isNonterminal(B)) { 239 | vector beta(p.RHS.begin() + j + 1, p.RHS.end()); 240 | set rfirst = compute_first(beta); 241 | size_t oldsize = follow_set[B].size(); 242 | 243 | if(rfirst.find(Grammar::lambda) == rfirst.end()) { 244 | follow_set[B].insert(rfirst.begin(), rfirst.end()); 245 | } else { 246 | rfirst.erase(Grammar::lambda); 247 | follow_set[B].insert(rfirst.begin(), rfirst.end()); 248 | rfirst = follow_set[A]; 249 | follow_set[B].insert(rfirst.begin(), rfirst.end()); 250 | } 251 | size_t newsize = follow_set[B].size(); 252 | if(oldsize != newsize) 253 | changes = true; 254 | } 255 | } 256 | } 257 | } while(changes); 258 | } 259 | 260 | void Grammar::lldriver(queue tokens) { 261 | stack stk; 262 | string X; 263 | string a; 264 | Production p; 265 | /* Push the Start Symbol onto an empty stack */ 266 | stk.push(start_symbol); 267 | 268 | while(!stk.empty()) { 269 | X = stk.top(); 270 | a = tokens.front(); 271 | if(isNonterminal(X) && lltable[X].find(a) != lltable[X].end()) { 272 | p = lltable[X][a]; 273 | stk.pop(); 274 | for(int i = p.RHS.size() - 1; i >= 0; i--) { 275 | if(p.RHS[i] == Grammar::lambda) 276 | continue; 277 | stk.push(p.RHS[i]); 278 | } 279 | } else if(X == a) { 280 | stk.pop(); 281 | tokens.pop(); 282 | } else { 283 | /* Process syntax error. */ 284 | puts("Process syntax error"); 285 | return; 286 | } 287 | } 288 | if(tokens.size() == 0) 289 | puts("Process syntax accept"); 290 | else 291 | puts("Process syntax error"); 292 | return; 293 | } 294 | 295 | queue getTokens(char s[]) { 296 | stringstream sin(s); 297 | queue tokens; 298 | string token; 299 | while(sin >> token) 300 | tokens.push(token); 301 | return tokens; 302 | } 303 | 304 | void parsingProduction(string r, Grammar &g) { 305 | #ifdef HTMLProduction 306 | static int production_label = 0; 307 | stringstream sin(r); 308 | string lhs, foo; 309 | vector tokens; 310 | sin >> lhs >> foo; 311 | while(sin >> foo) 312 | tokens.push_back(foo); 313 | Production p(lhs, tokens); 314 | p.label = ++production_label; 315 | g.rules.push_back(p); 316 | #else 317 | string div("->"); 318 | size_t found = r.find(div); 319 | if(found != std::string::npos) { 320 | string rhs = r.substr(found + div.length()); 321 | vector tokens; 322 | for(size_t i = 0; i < rhs.size(); i++) 323 | tokens.push_back(rhs.substr(i, 1)); 324 | Production p(r.substr(0, found), tokens); 325 | g.rules.push_back(p); 326 | } 327 | #endif 328 | } 329 | void readFirstSet(Grammar &g) { 330 | char in[1024]; 331 | while(gets(in) && in[0] != '\0') { 332 | 333 | string r(in); 334 | string div(":"); 335 | string token; 336 | size_t found = r.find(div); 337 | 338 | if(found != std::string::npos) { 339 | string lhs = r.substr(0, found); 340 | string rhs = r.substr(found + div.length()); 341 | std::replace(rhs.begin(), rhs.end(), ',', ' '); 342 | stringstream sin(rhs); 343 | while(sin >> token) { 344 | g.first_set[lhs].insert(token); 345 | } 346 | } 347 | } 348 | } 349 | 350 | void readFollowSet(Grammar &g) { 351 | char in[1024]; 352 | while(gets(in) && in[0] != '\0') { 353 | 354 | string r(in); 355 | string div(":"); 356 | string token; 357 | size_t found = r.find(div); 358 | 359 | if(found != std::string::npos) { 360 | string lhs = r.substr(0, found); 361 | string rhs = r.substr(found + div.length()); 362 | std::replace(rhs.begin(), rhs.end(), ',', ' '); 363 | stringstream sin(rhs); 364 | while(sin >> token) { 365 | g.follow_set[lhs].insert(token); 366 | } 367 | } 368 | } 369 | } 370 | int main() { 371 | 372 | freopen("input.txt", "r+t", stdin); 373 | freopen("output.txt", "w+t", stdout); 374 | 375 | char in[1024]; 376 | while(gets(in)) { 377 | Grammar g; 378 | parsingProduction(in, g); 379 | while(gets(in) && in[0] != '\0') { 380 | parsingProduction(in, g); 381 | } 382 | 383 | #ifdef HTMLProduction 384 | g.start_symbol = ""; 385 | #else 386 | g.start_symbol = "S"; 387 | #endif 388 | 389 | // g.fill_first_set(); 390 | 391 | readFirstSet(g); 392 | readFollowSet(g); 393 | 394 | // g.fill_follow_set(); 395 | // g.fill_lltable(); 396 | #ifdef debug 397 | puts("+----------------+----- First set -----+"); 398 | for(map >::iterator it = g.first_set.begin(); 399 | it != g.first_set.end(); it++) { 400 | printf("|%-16s| {", it->first.c_str()); 401 | for(set::iterator jt = it->second.begin(); 402 | jt != it->second.end(); jt++) { 403 | cout << " " << *jt; 404 | } 405 | puts(" }"); 406 | } 407 | puts("+----------------+---------------------+\n"); 408 | puts("+----------------+----- Follow set -----+"); 409 | for(map >::iterator it = g.follow_set.begin(); 410 | it != g.follow_set.end(); it++) { 411 | printf("|%-16s| {", it->first.c_str()); 412 | for(set::iterator jt = it->second.begin(); 413 | jt != it->second.end(); jt++) { 414 | cout << " " << *jt; 415 | } 416 | puts(" }"); 417 | } 418 | #endif 419 | for(int i = 0; i < g.rules.size(); i++) { 420 | set ps = g.get_predict_set(g.rules[i]); 421 | 422 | g.rules[i].print(), putchar(':'); 423 | int f = 0; 424 | for(set::iterator it = ps.begin(); 425 | it != ps.end(); it++) { 426 | if(f) putchar(','); 427 | f = 1; 428 | cout << *it; 429 | } 430 | cout << endl; 431 | } 432 | } 433 | return 0; 434 | } 435 | /* 436 | S->aAb 437 | A->B 438 | A->l 439 | B->c 440 | 441 | S:a 442 | A:c,l 443 | B:c 444 | a:a 445 | b:b 446 | c:c 447 | 448 | S:l 449 | A:b 450 | B:b 451 | 452 | 453 | 454 | 455 | S->Aa 456 | S->Bc 457 | A->D 458 | A->CA 459 | B->bA 460 | B->l 461 | C->dC 462 | C->e 463 | D->a 464 | D->b 465 | 466 | S:a,b,c,d,e,l 467 | A:a,b,d,e 468 | B:b,l 469 | C:d,e 470 | D:a,b 471 | a:a 472 | b:b 473 | c:c 474 | d:d 475 | e:e 476 | 477 | S:l 478 | A:a,c 479 | B:c 480 | C:a,b,d,e 481 | D:a,c 482 | 483 | */ 484 | -------------------------------------------------------------------------------- /hwA-CFG-LR(0)/CFG_LR.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | using namespace std; 13 | 14 | //#define HTMLProduction 15 | #define DEBUG 16 | 17 | class Production { 18 | public: 19 | int label; 20 | string LHS; 21 | vector RHS; 22 | 23 | Production(string L = "", vector R = vector(), int l=0) { 24 | LHS = L; 25 | RHS = R; 26 | label = l; 27 | } 28 | 29 | bool operator<(const Production &p) const { 30 | if(LHS != p.LHS) 31 | return LHS < p.LHS; 32 | for(size_t i = 0, j = 0; i < RHS.size() && j < p.RHS.size(); i++, j++) { 33 | if(RHS[i] != p.RHS[i]) 34 | return RHS[i] < p.RHS[i]; 35 | } 36 | return RHS.size() < p.RHS.size(); 37 | } 38 | 39 | bool operator==(const Production &p) const { 40 | if(LHS != p.LHS || RHS.size() != p.RHS.size()) 41 | return false; 42 | for(size_t i = 0, j = 0; i < RHS.size(); i++, j++) { 43 | if(RHS[i] != p.RHS[i]) 44 | return false; 45 | } 46 | return true; 47 | } 48 | 49 | bool operator!=(const Production &p) const { 50 | return !(*this == p); 51 | } 52 | 53 | void print() { 54 | printf("%s -> ", LHS.c_str()); 55 | for(size_t i = 0; i < RHS.size(); i++) 56 | printf("%s", RHS[i].c_str()); 57 | } 58 | }; 59 | 60 | class Grammar { 61 | public: 62 | /* LR parsing */ 63 | class ConfigurationSet { 64 | public: 65 | class State { 66 | public: 67 | int dot; 68 | vector lookahead; 69 | 70 | State(int d=0, vector l=vector()): 71 | dot(d), lookahead(l) {} 72 | bool operator<(const State &x) const { 73 | return dot < x.dot; 74 | } 75 | bool operator!=(const State &x) const { 76 | return dot != x.dot; 77 | } 78 | }; 79 | 80 | set< pair > configs; 81 | int label; 82 | ConfigurationSet() { 83 | label = 0; 84 | } 85 | /* method */ 86 | static ConfigurationSet closure0(ConfigurationSet& s, Grammar& g); 87 | static ConfigurationSet go_to0(ConfigurationSet& s, string X, Grammar& g); 88 | void print() { 89 | set< pair >::iterator it; 90 | Production p; 91 | for(it = configs.begin(); it != configs.end(); it++) { 92 | p = it->first; 93 | printf("%s -> ", p.LHS.c_str()); 94 | for(size_t i = 0; i < p.RHS.size(); i++) { 95 | if(i == it->second.dot) 96 | printf("@"); 97 | printf("%s", p.RHS[i].c_str()); 98 | } 99 | if(it->second.dot == p.RHS.size()) 100 | printf("@"); 101 | puts(""); 102 | } 103 | puts(""); 104 | } 105 | bool operator<(const ConfigurationSet &x) const { 106 | if(configs.size() != x.configs.size()) 107 | return configs.size() < x.configs.size(); 108 | for(set< pair >::iterator it = configs.begin(), jt = x.configs.begin(); 109 | it != configs.end(); it++, jt++) { 110 | if(it->first != jt->first) 111 | return it->first < jt->first; 112 | if(it->second != jt->second) 113 | return it->second < jt->second; 114 | } 115 | return false; 116 | // return label < x.label; 117 | } 118 | }; 119 | 120 | static const string lambda; 121 | set symbols; 122 | string start_symbol; 123 | vector rules; 124 | /* LL(1) attribute */ 125 | map > first_set; 126 | map > follow_set; 127 | map derives_lambda; 128 | map > lltable; 129 | /* LR attribute */ 130 | vector LRstates; 131 | map > go_to_table; 132 | map action_table; 133 | 134 | /* common method */ 135 | static bool isNonterminal(string token); 136 | void buildSymbols(); 137 | /* LL(1) method */ 138 | map mark_lambda(); 139 | void fill_first_set(); 140 | void fill_follow_set(); 141 | set compute_first(vector rhs); 142 | set get_predict_set(Production p); 143 | void fill_lltable(); 144 | void lldriver(queue tokens); 145 | /* LR method*/ 146 | void build_CFSM(); 147 | void build_action(); 148 | void lr0driver(queue tokens); 149 | void slr1driver(queue tokens); 150 | void lalr1driver(queue tokens); 151 | }; 152 | /* ------------------------ 153 | ConfigurationSet method 154 | -------------------------- */ 155 | Grammar::ConfigurationSet Grammar::ConfigurationSet::closure0(ConfigurationSet& s, Grammar& g) { 156 | ConfigurationSet r = s; 157 | bool changes; 158 | string A; 159 | Production P; 160 | int dotPos; 161 | 162 | set< pair >::iterator it; 163 | do { 164 | changes = false; 165 | for(it = r.configs.begin(); it != r.configs.end(); it++) { 166 | P = it->first; 167 | dotPos = it->second.dot; 168 | if(dotPos >= P.RHS.size() || P.RHS[dotPos] == Grammar::lambda) 169 | continue; 170 | A = P.RHS[dotPos]; 171 | if(Grammar::isNonterminal(A)) { 172 | /* B -> x.Ay */ 173 | /* Predict productions with A as the left-hand side */ 174 | for(size_t i = 0; i < g.rules.size(); i++) { 175 | if(g.rules[i].LHS == A) { 176 | if(r.configs.find(make_pair(g.rules[i], State(0))) == r.configs.end()) { 177 | r.configs.insert(make_pair(g.rules[i], State(0))); 178 | changes = true; 179 | } 180 | } 181 | } 182 | } 183 | } 184 | } while(changes); 185 | return r; 186 | } 187 | Grammar::ConfigurationSet Grammar::ConfigurationSet::go_to0(ConfigurationSet& s, string X, Grammar& g) { 188 | ConfigurationSet sb; 189 | set< pair >::iterator it; 190 | Production P; 191 | int dotPos; 192 | 193 | for(it = s.configs.begin(); it != s.configs.end(); it++) { 194 | P = it->first; 195 | dotPos = it->second.dot; 196 | if(dotPos >= P.RHS.size() || P.RHS[dotPos] == Grammar::lambda) 197 | continue; 198 | if(P.RHS[dotPos] == X) { 199 | State state(dotPos + 1, it->second.lookahead); 200 | sb.configs.insert(make_pair(P, state)); 201 | } 202 | } 203 | return closure0(sb, g); 204 | } 205 | /* ------------------------ 206 | Grammar method 207 | -------------------------- */ 208 | const string Grammar::lambda("l"); 209 | 210 | set Grammar::compute_first(vector rhs) { 211 | set result; 212 | size_t i; 213 | 214 | if(rhs.size() == 0 || rhs[0] == Grammar::lambda) { 215 | result.insert(Grammar::lambda); 216 | } else { 217 | result = first_set[rhs[0]]; 218 | for(i = 1; i < rhs.size() && 219 | first_set[rhs[i-1]].find(Grammar::lambda) != first_set[rhs[i-1]].end(); i++) { 220 | set f = first_set[rhs[i]]; 221 | f.erase(Grammar::lambda); 222 | result.insert(f.begin(), f.end()); 223 | } 224 | if(i == rhs.size() 225 | && first_set[rhs[i-1]].find(Grammar::lambda) != first_set[rhs[i-1]].end()) { 226 | result.insert(Grammar::lambda); 227 | } else { 228 | result.erase(Grammar::lambda); 229 | } 230 | } 231 | 232 | return result; 233 | } 234 | /* 235 | * please call get_predict_set() after fill_follow_set() and fill_first_set() 236 | */ 237 | set Grammar::get_predict_set(Production p) { 238 | set result; 239 | set rfirst; 240 | 241 | rfirst = compute_first(p.RHS); 242 | if(rfirst.find(Grammar::lambda) != rfirst.end()) { 243 | rfirst.erase(Grammar::lambda); 244 | result.insert(rfirst.begin(), rfirst.end()); 245 | rfirst = follow_set[p.LHS]; 246 | result.insert(rfirst.begin(), rfirst.end()); 247 | } else { 248 | result.insert(rfirst.begin(), rfirst.end()); 249 | } 250 | 251 | return result; 252 | } 253 | /* 254 | * 255 | */ 256 | void Grammar::fill_lltable() { 257 | string A; // nonterminal 258 | Production p; 259 | 260 | for(size_t i = 0; i < rules.size(); i++) { 261 | p = rules[i]; 262 | A = p.LHS; 263 | set predict_set = get_predict_set(p); 264 | 265 | for(set::iterator it = predict_set.begin(); 266 | it != predict_set.end(); it++) { 267 | assert(lltable[A].find(*it) == lltable[A].end()); 268 | lltable[A][*it] = p; 269 | } 270 | } 271 | 272 | } 273 | void Grammar::buildSymbols() { 274 | symbols.clear(); 275 | for(size_t i = 0; i < rules.size(); i++) { 276 | symbols.insert(rules[i].LHS); 277 | for(size_t j = 0; j < rules[i].RHS.size(); j++) { 278 | symbols.insert(rules[i].RHS[j]); 279 | } 280 | } 281 | } 282 | bool Grammar::isNonterminal(string token) { 283 | 284 | #ifdef HTMLProduction 285 | if(token == Grammar::lambda) 286 | return false; 287 | if(token[0] == '<' && token[token.length() - 1] == '>') 288 | return true; 289 | return false; 290 | #else 291 | if(token == Grammar::lambda) 292 | return false; 293 | for(size_t i = 0; i < token.length(); i++) { 294 | if(isupper(token[i])) 295 | return true; 296 | } 297 | return false; 298 | #endif 299 | } 300 | /* ------------------------ 301 | Grammar LL method 302 | -------------------------- */ 303 | map Grammar::mark_lambda() { 304 | bool rhs_derives_lambda; 305 | bool changes; 306 | Production p; 307 | 308 | derives_lambda.clear(); 309 | 310 | /* initially, nothing is marked. */ 311 | for(size_t i = 0; i < rules.size(); i++) { 312 | derives_lambda[rules[i].LHS] = false; 313 | } 314 | do { 315 | changes = false; 316 | for(size_t i = 0; i < rules.size(); i++) { 317 | p = rules[i]; 318 | if(!derives_lambda[p.LHS]) { 319 | if(p.RHS.size() == 0 || p.RHS[0] == Grammar::lambda) { 320 | changes = derives_lambda[p.LHS] = true; 321 | continue; 322 | } 323 | /* does each part of RHS derive lambda ? */ 324 | rhs_derives_lambda = derives_lambda[string(p.RHS[0])]; 325 | for(size_t j = 1; j < p.RHS.size(); j++) { 326 | rhs_derives_lambda &= derives_lambda[p.RHS[j]]; 327 | } 328 | if(rhs_derives_lambda) { 329 | changes = true; 330 | derives_lambda[p.LHS] = true; 331 | } 332 | } 333 | } 334 | } while(changes); 335 | return derives_lambda; 336 | } 337 | void Grammar::fill_first_set() { 338 | 339 | string A; // nonterminal 340 | string a; // terminal 341 | Production p; 342 | bool changes; 343 | 344 | mark_lambda(); 345 | first_set.clear(); 346 | 347 | for(size_t i = 0; i < rules.size(); i++) { 348 | A = rules[i].LHS; 349 | if(derives_lambda[A]) 350 | first_set[A].insert(Grammar::lambda); 351 | } 352 | 353 | for(size_t i = 0; i < rules.size(); i++) { 354 | for(size_t j = 0; j < rules[i].RHS.size(); j++) { 355 | a = rules[i].RHS[j]; 356 | if(!isNonterminal(a)) { 357 | if(a != Grammar::lambda) 358 | first_set[a].insert(a); 359 | if(j == 0) { // A -> aXX 360 | first_set[rules[i].LHS].insert(a); 361 | } 362 | } 363 | } 364 | } 365 | 366 | do { 367 | changes = false; 368 | for(size_t i = 0; i < rules.size(); i++) { 369 | p = rules[i]; 370 | set rfirst = compute_first(p.RHS); 371 | size_t oldsize = first_set[p.LHS].size(); 372 | first_set[p.LHS].insert(rfirst.begin(), rfirst.end()); 373 | size_t newsize = first_set[p.LHS].size(); 374 | if(oldsize != newsize) 375 | changes = true; 376 | } 377 | } while(changes); 378 | } 379 | 380 | void Grammar::fill_follow_set() { 381 | string A, B; // nonterminal 382 | Production p; 383 | bool changes; 384 | 385 | for(size_t i = 0; i < rules.size(); i++) { 386 | A = rules[i].LHS; 387 | follow_set[A].clear(); 388 | } 389 | 390 | follow_set[start_symbol].insert(Grammar::lambda); 391 | 392 | do { 393 | changes = false; 394 | for(size_t i = 0; i < rules.size(); i++) { 395 | /* A -> a B b 396 | * I.e. for each production and each occurrence 397 | * of a nonterminal in its right-hand side. 398 | */ 399 | p = rules[i]; 400 | A = p.LHS; 401 | for(size_t j = 0; j < p.RHS.size(); j++) { 402 | B = p.RHS[j]; 403 | if(isNonterminal(B)) { 404 | vector beta(p.RHS.begin() + j + 1, p.RHS.end()); 405 | set rfirst = compute_first(beta); 406 | size_t oldsize = follow_set[B].size(); 407 | 408 | if(rfirst.find(Grammar::lambda) == rfirst.end()) { 409 | follow_set[B].insert(rfirst.begin(), rfirst.end()); 410 | } else { 411 | rfirst.erase(Grammar::lambda); 412 | follow_set[B].insert(rfirst.begin(), rfirst.end()); 413 | rfirst = follow_set[A]; 414 | follow_set[B].insert(rfirst.begin(), rfirst.end()); 415 | } 416 | size_t newsize = follow_set[B].size(); 417 | if(oldsize != newsize) 418 | changes = true; 419 | } 420 | } 421 | } 422 | } while(changes); 423 | } 424 | 425 | void Grammar::lldriver(queue tokens) { 426 | stack stk; 427 | string X; 428 | string a; 429 | Production p; 430 | /* Push the Start Symbol onto an empty stack */ 431 | stk.push(start_symbol); 432 | 433 | while(!stk.empty() && !tokens.empty()) { 434 | X = stk.top(); 435 | a = tokens.front(); 436 | // cout << X << " " << a << endl; 437 | if(isNonterminal(X) && lltable[X].find(a) != lltable[X].end()) { 438 | p = lltable[X][a]; 439 | stk.pop(); 440 | for(int i = p.RHS.size() - 1; i >= 0; i--) { 441 | if(p.RHS[i] == Grammar::lambda) 442 | continue; 443 | stk.push(p.RHS[i]); 444 | } 445 | } else if(X == a) { 446 | stk.pop(); 447 | tokens.pop(); 448 | } else if(lltable[X].find(Grammar::lambda) != lltable[X].end()) { 449 | stk.pop(); 450 | } else { 451 | /* Process syntax error. */ 452 | puts("Bad!"); 453 | return; 454 | } 455 | } 456 | while(!stk.empty()) { 457 | X = stk.top(); 458 | if(lltable[X].find(Grammar::lambda) != lltable[X].end()) 459 | stk.pop(); 460 | else 461 | break; 462 | } 463 | if(tokens.size() == 0 && stk.size() == 0) 464 | puts("Good"); 465 | else 466 | puts("Bad!"); 467 | return; 468 | } 469 | /* ------------------------ 470 | Grammar LR method 471 | -------------------------- */ 472 | void Grammar::build_action() { 473 | ConfigurationSet s; 474 | Production P; 475 | int dotPos; 476 | set< pair >::iterator it; 477 | 478 | for(size_t i = 0; i < LRstates.size(); i++) { 479 | s = LRstates[i]; 480 | int reduce = 0, rule = 0, accept = 1; 481 | for(it = s.configs.begin(); it != s.configs.end(); it++) { 482 | P = it->first, dotPos = it->second.dot; 483 | if(dotPos == P.RHS.size()) 484 | reduce++, rule = P.label; 485 | accept &= P.LHS == Grammar::start_symbol; 486 | } 487 | if(accept == 1) 488 | action_table[i] = 0; 489 | else if(reduce == 1) 490 | action_table[i] = -1; 491 | else 492 | action_table[i] = 1; 493 | } 494 | #ifdef DEBUG 495 | printf("State |"); 496 | for(size_t i = 0; i < LRstates.size(); i++) 497 | printf("%5d|", i); 498 | puts(""); 499 | printf("Action|"); 500 | for(size_t i = 0; i < action_table.size(); i++) { 501 | printf("%5d|", action_table[i]); 502 | } 503 | puts(""); 504 | #endif 505 | } 506 | void Grammar::build_CFSM() { 507 | set S; 508 | queue Q; 509 | ConfigurationSet s0, sb; 510 | int label = 0; 511 | for(size_t i = 0; i < rules.size(); i++) { 512 | if(rules[i].LHS == this->start_symbol) { 513 | s0.configs.insert(make_pair(rules[i], ConfigurationSet::State(0))); 514 | } 515 | } 516 | s0 = ConfigurationSet::closure0(s0, *this); 517 | s0.label = label++; 518 | 519 | S.insert(s0); 520 | Q.push(s0); 521 | 522 | buildSymbols(); 523 | 524 | while(!Q.empty()) { 525 | s0 = Q.front(), Q.pop(); 526 | LRstates.push_back(s0); 527 | #ifdef DEBUG 528 | printf("------------- State %d -------------\n", s0.label); 529 | s0.print(); 530 | #endif 531 | for(set::iterator it = symbols.begin(); 532 | it != symbols.end(); it++) { 533 | sb = ConfigurationSet::go_to0(s0, *it, *this); 534 | if(sb.configs.size() > 0) { 535 | if(S.find(sb) == S.end()) { 536 | sb.label = label++; 537 | S.insert(sb); 538 | Q.push(sb); 539 | } 540 | go_to_table[s0.label][*it] = (* S.find(sb)).label; 541 | } 542 | } 543 | } 544 | build_action(); 545 | #ifdef DEBUG 546 | printf("State|"); 547 | for(set::iterator it = symbols.begin(); 548 | it != symbols.end(); it++) { 549 | printf("%5s|", (*it).c_str()); 550 | } 551 | puts(""); 552 | for(int i = 0; i < label; i++) { 553 | printf("%5d|", i); 554 | for(set::iterator it = symbols.begin(); 555 | it != symbols.end(); it++) { 556 | if(go_to_table[i].find(*it) != go_to_table[i].end()) 557 | printf("%5d|", go_to_table[i][*it]); 558 | else 559 | printf("%5s|", ""); 560 | } 561 | puts(""); 562 | } 563 | #endif 564 | } 565 | void Grammar::lr0driver(queue tokens) { 566 | stack stateStk; 567 | stack tokenStk; 568 | int state; 569 | string X; 570 | 571 | stateStk.push(0); 572 | while(!tokens.empty()) { 573 | state = stateStk.top(); 574 | X = tokens.front(); 575 | #ifdef DEBUG 576 | printf("state %d front %s\n", state, X.c_str()); 577 | LRstates[state].print(); 578 | for (std::stack dump = stateStk; !dump.empty(); dump.pop()) 579 | std::cout << "state stack "<< dump.top() << '\n'; 580 | for (std::stack dump = tokenStk; !dump.empty(); dump.pop()) 581 | std::cout << "token stack "<< dump.top() << '\n'; 582 | #endif 583 | if(LRstates[state].configs.size() == 1) { // Reduce 584 | Production P = LRstates[state].configs.begin()->first; 585 | for(size_t i = 0; i < P.RHS.size(); i++) { 586 | tokenStk.pop(); 587 | } 588 | for(size_t i = 0; i < P.RHS.size(); i++) { 589 | stateStk.pop(); 590 | } 591 | tokenStk.push(P.LHS); 592 | state = stateStk.top(); 593 | if(go_to_table[state].find(P.LHS) == go_to_table[state].end()) { 594 | puts("Syntax Error"); 595 | return; 596 | } 597 | state = go_to_table[state][P.LHS]; 598 | stateStk.push(state); 599 | } else if(LRstates[state].configs.size() > 1) { 600 | if(action_table[state] == 1) { // Shift 601 | if(go_to_table[state].find(X) == go_to_table[state].end()) { 602 | puts("Syntax Error"); 603 | return; 604 | } 605 | state = go_to_table[state][X]; 606 | stateStk.push(state); 607 | tokenStk.push(X); 608 | tokens.pop(); 609 | } else if(action_table[state] == 0) { // Accept 610 | break; 611 | } else { 612 | puts("Syntax Error"); 613 | return; 614 | } 615 | } 616 | } 617 | state = stateStk.top(); 618 | LRstates[state].print(); 619 | if(LRstates[state].configs.size() == 1) { // Reduce 620 | Production P = LRstates[state].configs.begin()->first; 621 | for(size_t i = 0; i < P.RHS.size(); i++) { 622 | tokenStk.pop(); 623 | stateStk.pop(); 624 | } 625 | tokenStk.push(P.LHS); 626 | } 627 | 628 | if(tokens.size() == 0 && tokenStk.size() == 1 && stateStk.size() == 1 629 | && tokenStk.top() == Grammar::start_symbol && stateStk.top() == 0) { 630 | puts("Syntax Accept"); 631 | return; 632 | } 633 | puts("Syntax Error"); 634 | return; 635 | } 636 | 637 | queue getTokens(char s[]) { 638 | stringstream sin(s); 639 | queue tokens; 640 | string token; 641 | while(sin >> token) 642 | tokens.push(token); 643 | return tokens; 644 | } 645 | 646 | void parsingProduction(string r, Grammar &g) { 647 | #ifdef HTMLProduction 648 | static int production_label = 0; 649 | stringstream sin(r); 650 | string lhs, foo; 651 | vector tokens; 652 | sin >> lhs >> foo; 653 | while(sin >> foo) 654 | tokens.push_back(foo); 655 | Production p(lhs, tokens); 656 | p.label = ++production_label; 657 | g.rules.push_back(p); 658 | #else 659 | string div("->"); 660 | size_t found = r.find(div); 661 | if(found != std::string::npos) { 662 | string rhs = r.substr(found + div.length()); 663 | vector tokens; 664 | for(size_t i = 0; i < rhs.size(); i++) 665 | tokens.push_back(rhs.substr(i, 1)); 666 | Production p(r.substr(0, found), tokens); 667 | g.rules.push_back(p); 668 | } 669 | #endif 670 | } 671 | 672 | int main() { 673 | 674 | char in[1024]; 675 | while(gets(in)) { 676 | Grammar g; 677 | parsingProduction(in, g); 678 | while(gets(in) && in[0] != '\0') { 679 | parsingProduction(in, g); 680 | } 681 | 682 | #ifdef HTMLProduction 683 | g.start_symbol = ""; 684 | #else 685 | g.start_symbol = "S"; 686 | #endif 687 | g.build_CFSM(); 688 | 689 | gets(in); 690 | g.lr0driver(getTokens(in)); 691 | } 692 | return 0; 693 | } 694 | /* 695 | S->E$ 696 | E->E+T 697 | E->T 698 | T->T*P 699 | T->P 700 | P-># 701 | P->(E) 702 | 703 | S->E$ 704 | E->E+T 705 | E->T 706 | T-># 707 | T->(E) 708 | 709 | # + # $ 710 | 711 | S->E$ 712 | E->E+T 713 | E->T 714 | T-># 715 | T->(E) 716 | 717 | # + ( # ) $ 718 | 719 | S->E$ 720 | E->E+T 721 | E->T 722 | T-># 723 | T->(E) 724 | 725 | # + ( ( # ) ) $ 726 | 727 | HTML format 728 | 729 | -> begin end 730 | -> 731 | -> 732 | -> l 733 | -> ID := ; 734 | -> read ( ) ; 735 | -> write ( ) ; 736 | -> ID 737 | -> , ID 738 | -> l 739 | -> 740 | -> , 741 | -> l 742 | -> 743 | -> 744 | -> l 745 | -> ( ) 746 | -> ID 747 | -> INTLIT 748 | -> + 749 | -> - 750 | -> $ 751 | 752 | */ 753 | --------------------------------------------------------------------------------