├── .gitattributes ├── .gitignore ├── Assembly ├── Project.sln ├── Project.vcxproj └── lib │ ├── kernel32.inc │ ├── kernel32.lib │ ├── msvcrt.inc │ ├── msvcrt.lib │ ├── user32.inc │ └── user32.lib ├── README.md ├── compiler.sln ├── compiler ├── 2018-12-29.txt ├── AsmGenerator.cpp ├── AsmGenerator.h ├── CalculationAction.cpp ├── ContextFreeGrammar.cpp ├── ContextFreeGrammar.hpp ├── ControlAction.cpp ├── DeclarationAction.cpp ├── ExpressionAction.cpp ├── FunctionAction.cpp ├── GrammerAnalyzer.cpp ├── GrammerAnalyzer.h ├── LR.cpp ├── LR.hpp ├── LR1.cpp ├── LR1.h ├── Min_DFA.cpp ├── Nfa.cpp ├── Nfa.h ├── Nfa_to_dfa.cpp ├── Nfa_to_dfa.h ├── RegExp.cpp ├── RegExp.h ├── StatementAction.cpp ├── SwitchToFunction.cpp ├── SymbolTable.cpp ├── SymbolTable.hpp ├── action.txt ├── ans.txt ├── compile_asm.bat ├── compiler.vcxproj ├── compiler.vcxproj.filters ├── hlhNFA.cpp ├── hlhNFA.h ├── input_and_output.cpp ├── intput_and_output.hpp ├── item.txt ├── kernel item.txt ├── lalr.txt ├── lexical analyzer.txt ├── main.cpp ├── python.py ├── test.c ├── test1.c └── test2.c ├── grammar.jpg ├── images ├── grammar_reduce_shift.jpg └── lexical_min_DFA_amount.jpg ├── productions.txt ├── wordlist.cpp └── 三地址代码.txt /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | project.fragment.lock.json 46 | artifacts/ 47 | 48 | *_i.c 49 | *_p.c 50 | *_i.h 51 | *.ilk 52 | *.meta 53 | *.obj 54 | *.pch 55 | *.pdb 56 | *.pgc 57 | *.pgd 58 | *.rsp 59 | *.sbr 60 | *.tlb 61 | *.tli 62 | *.tlh 63 | *.tmp 64 | *.tmp_proj 65 | *.log 66 | *.vspscc 67 | *.vssscc 68 | .builds 69 | *.pidb 70 | *.svclog 71 | *.scc 72 | 73 | # Chutzpah Test files 74 | _Chutzpah* 75 | 76 | # Visual C++ cache files 77 | ipch/ 78 | *.aps 79 | *.ncb 80 | *.opendb 81 | *.opensdf 82 | *.sdf 83 | *.cachefile 84 | *.VC.db 85 | *.VC.VC.opendb 86 | 87 | # Visual Studio profiler 88 | *.psess 89 | *.vsp 90 | *.vspx 91 | *.sap 92 | 93 | # TFS 2012 Local Workspace 94 | $tf/ 95 | 96 | # Guidance Automation Toolkit 97 | *.gpState 98 | 99 | # ReSharper is a .NET coding add-in 100 | _ReSharper*/ 101 | *.[Rr]e[Ss]harper 102 | *.DotSettings.user 103 | 104 | # JustCode is a .NET coding add-in 105 | .JustCode 106 | 107 | # TeamCity is a build add-in 108 | _TeamCity* 109 | 110 | # DotCover is a Code Coverage Tool 111 | *.dotCover 112 | 113 | # NCrunch 114 | _NCrunch_* 115 | .*crunch*.local.xml 116 | nCrunchTemp_* 117 | 118 | # MightyMoose 119 | *.mm.* 120 | AutoTest.Net/ 121 | 122 | # Web workbench (sass) 123 | .sass-cache/ 124 | 125 | # Installshield output folder 126 | [Ee]xpress/ 127 | 128 | # DocProject is a documentation generator add-in 129 | DocProject/buildhelp/ 130 | DocProject/Help/*.HxT 131 | DocProject/Help/*.HxC 132 | DocProject/Help/*.hhc 133 | DocProject/Help/*.hhk 134 | DocProject/Help/*.hhp 135 | DocProject/Help/Html2 136 | DocProject/Help/html 137 | 138 | # Click-Once directory 139 | publish/ 140 | 141 | # Publish Web Output 142 | *.[Pp]ublish.xml 143 | *.azurePubxml 144 | # TODO: Comment the next line if you want to checkin your web deploy settings 145 | # but database connection strings (with potential passwords) will be unencrypted 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 150 | # checkin your Azure Web App publish settings, but sensitive information contained 151 | # in these scripts will be unencrypted 152 | PublishScripts/ 153 | 154 | # NuGet Packages 155 | *.nupkg 156 | # The packages folder can be ignored because of Package Restore 157 | **/packages/* 158 | # except build/, which is used as an MSBuild target. 159 | !**/packages/build/ 160 | # Uncomment if necessary however generally it will be regenerated when needed 161 | #!**/packages/repositories.config 162 | # NuGet v3's project.json files produces more ignoreable files 163 | *.nuget.props 164 | *.nuget.targets 165 | 166 | # Microsoft Azure Build Output 167 | csx/ 168 | *.build.csdef 169 | 170 | # Microsoft Azure Emulator 171 | ecf/ 172 | rcf/ 173 | 174 | # Windows Store app package directories and files 175 | AppPackages/ 176 | BundleArtifacts/ 177 | Package.StoreAssociation.xml 178 | _pkginfo.txt 179 | 180 | # Visual Studio cache files 181 | # files ending in .cache can be ignored 182 | *.[Cc]ache 183 | # but keep track of directories ending in .cache 184 | !*.[Cc]ache/ 185 | 186 | # Others 187 | ClientBin/ 188 | ~$* 189 | *~ 190 | *.dbmdl 191 | *.dbproj.schemaview 192 | *.jfm 193 | *.pfx 194 | *.publishsettings 195 | node_modules/ 196 | orleans.codegen.cs 197 | 198 | # Since there are multiple workflows, uncomment next line to ignore bower_components 199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 200 | #bower_components/ 201 | 202 | # RIA/Silverlight projects 203 | Generated_Code/ 204 | 205 | # Backup & report files from converting an old project file 206 | # to a newer Visual Studio version. Backup files are not needed, 207 | # because we have git ;-) 208 | _UpgradeReport_Files/ 209 | Backup*/ 210 | UpgradeLog*.XML 211 | UpgradeLog*.htm 212 | 213 | # SQL Server files 214 | *.mdf 215 | *.ldf 216 | 217 | # Business Intelligence projects 218 | *.rdl.data 219 | *.bim.layout 220 | *.bim_*.settings 221 | 222 | # Microsoft Fakes 223 | FakesAssemblies/ 224 | 225 | # GhostDoc plugin setting file 226 | *.GhostDoc.xml 227 | 228 | # Node.js Tools for Visual Studio 229 | .ntvs_analysis.dat 230 | 231 | # Visual Studio 6 build log 232 | *.plg 233 | 234 | # Visual Studio 6 workspace options file 235 | *.opt 236 | 237 | # Visual Studio LightSwitch build output 238 | **/*.HTMLClient/GeneratedArtifacts 239 | **/*.DesktopClient/GeneratedArtifacts 240 | **/*.DesktopClient/ModelManifest.xml 241 | **/*.Server/GeneratedArtifacts 242 | **/*.Server/ModelManifest.xml 243 | _Pvt_Extensions 244 | 245 | # Paket dependency manager 246 | .paket/paket.exe 247 | paket-files/ 248 | 249 | # FAKE - F# Make 250 | .fake/ 251 | 252 | # JetBrains Rider 253 | .idea/ 254 | *.sln.iml 255 | 256 | # CodeRush 257 | .cr/ 258 | 259 | # Python Tools for Visual Studio (PTVS) 260 | __pycache__/ 261 | *.pyc 262 | # My 263 | README.html 264 | README.pdf 265 | temp.html 266 | Assembly/Project.lst 267 | Assembly/Assembly.asm 268 | -------------------------------------------------------------------------------- /Assembly/Project.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Project", "Project.vcxproj", "{4164AA65-1EF9-4E69-899B-D1BED776070B}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{1A9A10CA-CB73-42A9-8530-5B9AC4C98180}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Win32 = Debug|Win32 13 | Release|Win32 = Release|Win32 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {4164AA65-1EF9-4E69-899B-D1BED776070B}.Debug|Win32.ActiveCfg = Debug|Win32 17 | {4164AA65-1EF9-4E69-899B-D1BED776070B}.Debug|Win32.Build.0 = Debug|Win32 18 | {4164AA65-1EF9-4E69-899B-D1BED776070B}.Release|Win32.ActiveCfg = Release|Win32 19 | {4164AA65-1EF9-4E69-899B-D1BED776070B}.Release|Win32.Build.0 = Release|Win32 20 | EndGlobalSection 21 | GlobalSection(SolutionProperties) = preSolution 22 | HideSolutionNode = FALSE 23 | EndGlobalSection 24 | EndGlobal 25 | -------------------------------------------------------------------------------- /Assembly/Project.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | 15 | 16 | 17 | {4164AA65-1EF9-4E69-899B-D1BED776070B} 18 | 10.0.16299.0 19 | 20 | 21 | 22 | Application 23 | v141 24 | 25 | 26 | Application 27 | v141 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | <_ProjectFileVersion>10.0.30319.1 42 | $(SolutionDir)$(Configuration)\ 43 | $(Configuration)\ 44 | $(Configuration)\ 45 | 46 | 47 | 48 | $(ProjectName).lst 49 | $(SolutionDir)\lib\ 50 | false 51 | 3 52 | true 53 | true 54 | false 55 | 56 | 57 | user32.lib;%(AdditionalDependencies) 58 | $(SolutionDir)\lib\;%(AdditionalLibraryDirectories) 59 | true 60 | Console 61 | false 62 | 63 | 64 | false 65 | 66 | 67 | 68 | 69 | false 70 | 71 | 72 | 73 | 74 | false 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /Assembly/lib/kernel32.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hlh981029/c-compiler/b7a3afe0b050d92f7b946f64f5a28d8e5e49183c/Assembly/lib/kernel32.lib -------------------------------------------------------------------------------- /Assembly/lib/msvcrt.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hlh981029/c-compiler/b7a3afe0b050d92f7b946f64f5a28d8e5e49183c/Assembly/lib/msvcrt.lib -------------------------------------------------------------------------------- /Assembly/lib/user32.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hlh981029/c-compiler/b7a3afe0b050d92f7b946f64f5a28d8e5e49183c/Assembly/lib/user32.lib -------------------------------------------------------------------------------- /compiler.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26228.4 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "compiler", "compiler\compiler.vcxproj", "{26511C81-B83A-4A1D-A915-75EA90A893D5}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {26511C81-B83A-4A1D-A915-75EA90A893D5}.Debug|x64.ActiveCfg = Debug|x64 17 | {26511C81-B83A-4A1D-A915-75EA90A893D5}.Debug|x64.Build.0 = Debug|x64 18 | {26511C81-B83A-4A1D-A915-75EA90A893D5}.Debug|x86.ActiveCfg = Debug|Win32 19 | {26511C81-B83A-4A1D-A915-75EA90A893D5}.Debug|x86.Build.0 = Debug|Win32 20 | {26511C81-B83A-4A1D-A915-75EA90A893D5}.Release|x64.ActiveCfg = Release|x64 21 | {26511C81-B83A-4A1D-A915-75EA90A893D5}.Release|x64.Build.0 = Release|x64 22 | {26511C81-B83A-4A1D-A915-75EA90A893D5}.Release|x86.ActiveCfg = Release|Win32 23 | {26511C81-B83A-4A1D-A915-75EA90A893D5}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /compiler/AsmGenerator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "SymbolTable.hpp" 8 | #include "GrammerAnalyzer.h" 9 | using namespace hbst; 10 | 11 | class AssemblyGenerator { 12 | public: 13 | // 汇编代码文件输出流 14 | std::ofstream asm_out; 15 | // 全局符号表 16 | SymbolTable *global_symbol_table; 17 | // 函数表 18 | FunctionTable *function_table; 19 | // 结构体表 20 | StructTable *struct_table; 21 | // 三地址指令表 22 | std::vector *final_instruction; 23 | // 构造函数与析构函数 24 | AssemblyGenerator(); 25 | ~AssemblyGenerator(); 26 | // 生成汇编代码总函数 27 | void generate_asm(); 28 | // 生成翻译三地址指令前print、input函数定义等必需的汇编代码 29 | void generate_header(); 30 | // 生成函数声明的汇编代码 31 | void generate_proto(); 32 | // 生成翻译三地址指令后的一些必需的汇编代码 33 | void generate_footer(); 34 | // 生成全局变量声明的汇编代码 35 | void generate_global_var(); 36 | // 生成三地址指令翻译成的汇编代码 37 | void generate_code(); 38 | // 关闭汇编输出文件 39 | void close_file(); 40 | // 获取函数的符号表 41 | SymbolTable* get_function_symbol_table(std::string name); 42 | // 生成测试样例(测试用) 43 | void generate_example(); 44 | // 输出三地址指令列表(测试用) 45 | void output_instructions(); 46 | // 向符号表、结构体表、函数表、三地址指令列表中添加项目(测试用) 47 | void add_symbol(SymbolItem i, SymbolTable* t = NULL); 48 | void add_struct(StructItem* i); 49 | void add_function(FunctionItem* i); 50 | void add_instruction(GrammerAnalyzer::three_address_instruction *i); 51 | }; -------------------------------------------------------------------------------- /compiler/ContextFreeGrammar.cpp: -------------------------------------------------------------------------------- 1 | #include"ContextFreeGrammar.hpp" 2 | namespace cfg 3 | { 4 | 5 | ostream& operator<<(ostream& out, const Symbol& symbol) 6 | { 7 | return out << symbol.value; 8 | } 9 | 10 | ostream& operator<<(ostream& out, Production production) 11 | { 12 | out << production.left->value << " -> "; 13 | for each (auto sybom_pointer in production.right) 14 | { 15 | out << sybom_pointer->value << ' '; 16 | } 17 | return out; 18 | } 19 | 20 | template 21 | ostream& operator<<(ostream& out, const unordered_set& vec) 22 | { 23 | for each (auto x in vec) 24 | { 25 | out << *x << "\n"; 26 | } 27 | return out; 28 | } 29 | 30 | template 31 | ostream& operator<<(ostream& out, const vector& vec) 32 | { 33 | 34 | for each (auto x in vec) 35 | { 36 | out << *x << "\t"; 37 | } 38 | return out; 39 | } 40 | 41 | Symbol::Symbol() 42 | { 43 | 44 | } 45 | 46 | Symbol::Symbol(string input) : value(input) 47 | { 48 | 49 | } 50 | 51 | bool Symbol::operator==(const Symbol & a) 52 | { 53 | return value == a.value; 54 | } 55 | 56 | int Symbol::get_id() const 57 | { 58 | return Identify::Symbol; 59 | } 60 | 61 | Terminal::Terminal() :Symbol() 62 | { 63 | start_as_epsilon = false; 64 | } 65 | 66 | Terminal::Terminal(string input) : Symbol(input) 67 | { 68 | start_as_epsilon = false; 69 | } 70 | 71 | int Terminal::get_id() const 72 | { 73 | return Identify::Terminal; 74 | } 75 | 76 | Nonterminal::Nonterminal() :Symbol() 77 | { 78 | start_as_epsilon = false; 79 | } 80 | 81 | Nonterminal::Nonterminal(string input) : Symbol(input) 82 | { 83 | start_as_epsilon = false; 84 | } 85 | 86 | int Nonterminal::get_id() const 87 | { 88 | return Identify::Nonterminal; 89 | } 90 | 91 | Production::Production() 92 | { 93 | 94 | } 95 | Production::Production(Nonterminal* start, const vector& symbol) :left(start), right(symbol) 96 | { 97 | 98 | } 99 | void Production::init(Nonterminal* start, const vector& symbol) 100 | { 101 | left = start; 102 | right = symbol; 103 | } 104 | 105 | ContextFreeGrammar::ContextFreeGrammar() :start_symbol(nullptr) { 106 | Terminal* end = new Terminal("$"); 107 | this->end_symbol = end; 108 | terminal_set.insert(end); 109 | } 110 | 111 | void ContextFreeGrammar::test_function() 112 | { 113 | Symbol S; 114 | 115 | Terminal* a = new Terminal("a"); 116 | Terminal* b = new Terminal("b"); 117 | Terminal* c = new Terminal("c"); 118 | Terminal* d = new Terminal("d"); 119 | 120 | Nonterminal* A = new Nonterminal("A"); 121 | Nonterminal* B = new Nonterminal("B"); 122 | Nonterminal* C = new Nonterminal("C"); 123 | 124 | vector vec; 125 | vec.push_back(a); 126 | vec.push_back(B); 127 | vec.push_back(C); 128 | Production* p1 = new Production(C, vec); 129 | vec.push_back(c); 130 | Production* p2 = new Production(B, vec); 131 | a->first_set.insert(a); 132 | b->first_set.insert(b); 133 | c->first_set.insert(c); 134 | d->first_set.insert(d); 135 | 136 | A->first_set.insert(a); 137 | A->first_set.insert(b); 138 | B->first_set.insert(a); 139 | B->first_set.insert(c); 140 | C->first_set.insert(d); 141 | 142 | A->follow_set.insert(b); 143 | B->follow_set.insert(b); 144 | C->follow_set.insert(d); 145 | 146 | 147 | 148 | cout << *p1 << endl; 149 | cout << *p2 << endl; 150 | 151 | 152 | cout << *a << "\nfirst_set:\n" << a->first_set << endl; 153 | cout << *b << "\nfirst_set:\n" << b->first_set << endl; 154 | cout << *c << "\nfirst_set:\n" << c->first_set << endl; 155 | cout << *d << "\nfirst_set:\n" << d->first_set << endl; 156 | 157 | cout 158 | << *A 159 | << "\nfirst_set:\n" << A->first_set << endl 160 | << "\nfollow_set:\n" << A->follow_set << endl; 161 | cout 162 | << *B 163 | << "\nfirst_set:\n" << B->first_set << endl 164 | << "\nfollow_set:\n" << B->follow_set << endl; 165 | cout 166 | << *C 167 | << "\nfirst_set:\n" << C->first_set << endl 168 | << "\nfollow_set:\n" << C->follow_set << endl; 169 | 170 | a->value = "aaa"; 171 | b->value = "bbbb"; 172 | c->value = "cccc"; 173 | d->value = "ddddddd"; 174 | A->value = "AAAA"; 175 | B->value = "BB"; 176 | C->value = "CCC"; 177 | 178 | 179 | cout << *p1 << endl; 180 | cout << *p2 << endl; 181 | 182 | 183 | cout << *a << "\nfirst_set:\n" << a->first_set << endl; 184 | cout << *b << "\nfirst_set:\n" << b->first_set << endl; 185 | cout << *c << "\nfirst_set:\n" << c->first_set << endl; 186 | cout << *d << "\nfirst_set:\n" << d->first_set << endl; 187 | 188 | cout 189 | << *A 190 | << "\nfirst_set:\n" << A->first_set << endl 191 | << "\nfollow_set:\n" << A->follow_set << endl; 192 | cout 193 | << *B 194 | << "\nfirst_set:\n" << B->first_set << endl 195 | << "\nfollow_set:\n" << B->follow_set << endl; 196 | cout 197 | << *C 198 | << "\nfirst_set:\n" << C->first_set << endl 199 | << "\nfollow_set:\n" << C->follow_set << endl; 200 | 201 | cout << (p1->left == C) << endl; 202 | 203 | system("pause"); 204 | } 205 | 206 | void ContextFreeGrammar::set_first() { 207 | // first set for terminal symbols 208 | unordered_set::iterator it = terminal_set.begin(); 209 | for (; it != terminal_set.end(); it++) { 210 | (*it)->first_set.insert((*it)); 211 | } 212 | // first set for nonterminal symbols 213 | bool if_more = true; 214 | while (if_more) { 215 | if_more = false; 216 | unordered_set::iterator ip = production_set.begin(); 217 | // traverse all the productions 218 | for (; ip != production_set.end(); ip++) { 219 | // right is empty 220 | if ((*ip)->right.size() == 0) { 221 | (*ip)->left->start_as_epsilon = true; 222 | } 223 | else { 224 | vector::iterator is = (*ip)->right.begin(); 225 | // traverse all the symbols at the right side 226 | for (; is != (*ip)->right.end(); is++) { 227 | unordered_set::iterator iff = (*is)->first_set.begin(); 228 | // traverse all the symbols in first set of is 229 | for (; iff != (*is)->first_set.end(); iff++) { 230 | bool success = (*ip)->left->first_set.insert(*iff).second; 231 | if (success) { 232 | if_more = true; 233 | } 234 | } 235 | if (!(*is)->start_as_epsilon) { 236 | break; 237 | } 238 | if (is == (*ip)->right.end() - 1) { 239 | (*ip)->left->start_as_epsilon = true; 240 | } 241 | } 242 | } 243 | } 244 | } 245 | } 246 | 247 | void ContextFreeGrammar::set_follow() { 248 | //add $ to the follow set of S 249 | unordered_set::iterator e = terminal_set.begin(); 250 | for (; e != terminal_set.end(); e++) { 251 | if ((*e)->value == "$") { 252 | start_symbol->follow_set.insert(*e); 253 | } 254 | } 255 | bool flag = true; //if there's any other elements to add to the follow sets 256 | while (flag) { 257 | flag = false; 258 | //traverse the productions 259 | unordered_set::iterator ip = production_set.begin(); 260 | for (; ip != production_set.end(); ip++) { 261 | vector::iterator is = (*ip)->right.begin(); 262 | //traverse the right part of a production 263 | for (; is != (*ip)->right.end(); is++) { 264 | //find a nonterminal symbol 265 | if ((*is)->get_id() == Identify::Nonterminal) { 266 | //at the end 267 | if (is == (*ip)->right.end() - 1) { 268 | unordered_set::iterator itf = (*ip)->left->follow_set.begin(); 269 | for (; itf != (*ip)->left->follow_set.end(); itf++) { 270 | bool b = ((Nonterminal*)*is)->follow_set.insert(*itf).second; 271 | if (b == true) { 272 | flag = true; 273 | } 274 | } 275 | } 276 | //not at the end 277 | else { 278 | vector::iterator isn = is + 1; 279 | unordered_set::iterator itf = (*isn)->first_set.begin(); 280 | //add elements in first set of the next symbol to this follow set 281 | for (; itf != (*isn)->first_set.end(); itf++) { 282 | bool b = ((Nonterminal*)*is)->follow_set.insert(*itf).second; 283 | if (b == true) { 284 | flag = true; 285 | } 286 | } 287 | //if ep in first set of the next symbol, add its next to this next set 288 | if ((*isn)->start_as_epsilon) { 289 | if ((*isn)->get_id() != Identify::Nonterminal) { 290 | cout << "error: the next symble is not a nonterminal symble" << endl; 291 | } 292 | unordered_set::iterator iitf = ((Nonterminal*)*isn)->follow_set.begin(); 293 | for (; iitf != ((Nonterminal*)*isn)->follow_set.end(); iitf++) { 294 | bool b = ((Nonterminal*)*is)->follow_set.insert(*iitf).second; 295 | if (b == true) { 296 | flag = true; 297 | } 298 | } 299 | } 300 | } 301 | } 302 | } 303 | } 304 | } 305 | } 306 | 307 | void ContextFreeGrammar::input_productions(string filename) { 308 | fstream file; 309 | file.open(filename, std::ios::in); 310 | while (!file.eof()) { 311 | string left, right; 312 | while (getline(file, left)) { 313 | if (left != "") { 314 | break; 315 | } 316 | } 317 | while (getline(file, right)) { 318 | if (right == ";;") { 319 | break; 320 | } 321 | else { 322 | add_production(left, right); 323 | } 324 | } 325 | } 326 | file.close(); 327 | } 328 | 329 | void ContextFreeGrammar::add_production(string left, string right) { 330 | Production* p = new Production(); 331 | 332 | Nonterminal* le = new Nonterminal(left); 333 | std::pair::iterator, bool> pp; 334 | pp = nonterminal_set.insert(le); 335 | if (!pp.second) { 336 | delete le; 337 | } 338 | Nonterminal* l = *(pp.first); 339 | 340 | vector ri; 341 | if (right == "") { 342 | p->init(l, ri); 343 | } 344 | else { 345 | char * buf; 346 | char* t = strtok_s((char*)right.data(), " ", &buf); 347 | while (t) { 348 | string tstr = t; 349 | if (islower(tstr[0])) { 350 | Nonterminal* new_nonter = new Nonterminal(tstr); 351 | std::pair::iterator, bool> ppn; 352 | ppn = nonterminal_set.insert(new_nonter); 353 | if (!ppn.second) { 354 | delete new_nonter; 355 | } 356 | ri.push_back(*(ppn.first)); 357 | } 358 | else { 359 | Terminal* new_ter = new Terminal(tstr); 360 | std::pair::iterator, bool> ppt; 361 | ppt = terminal_set.insert(new_ter); 362 | if (!ppt.second) { 363 | delete new_ter; 364 | } 365 | ri.push_back(*(ppt.first)); 366 | } 367 | t = strtok_s(buf, " ", &buf); 368 | } 369 | p->init(l, ri); 370 | } 371 | cout << "production:" << *p << endl; 372 | production_set.insert(p); 373 | } 374 | 375 | void ContextFreeGrammar::set_start(string s) 376 | { 377 | for each (Nonterminal* t in nonterminal_set) { 378 | if ((*t).value == s) { 379 | start_symbol = t; 380 | } 381 | } 382 | } 383 | } -------------------------------------------------------------------------------- /compiler/ContextFreeGrammar.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace cfg 10 | { 11 | namespace Identify 12 | { 13 | enum SymbolIdentify 14 | { 15 | Symbol, Nonterminal, Terminal 16 | }; 17 | } 18 | 19 | using std::cin; 20 | using std::cout; 21 | using std::endl; 22 | 23 | using std::string; 24 | using std::vector; 25 | using std::unordered_set; 26 | 27 | using std::ostream; 28 | using std::istream; 29 | 30 | using std::fstream; 31 | using std::ofstream; 32 | using std::ifstream; 33 | 34 | template 35 | ostream& operator<<(ostream& out, const vector& vec); 36 | 37 | template 38 | ostream& operator<<(ostream& out, const unordered_set& vec); 39 | 40 | class Symbol; 41 | class Production; 42 | class Terminal; 43 | class Nonterminal; 44 | 45 | class Symbol 46 | { 47 | public: 48 | string value; 49 | unordered_set first_set; 50 | bool start_as_epsilon; 51 | 52 | Symbol(); 53 | Symbol(string input); 54 | bool operator==(const Symbol & a); 55 | virtual int get_id() const; 56 | friend ostream& operator<<(ostream& out, const Symbol& symbol); 57 | 58 | private: 59 | 60 | }; 61 | 62 | class Terminal : public Symbol 63 | { 64 | public: 65 | Terminal(); 66 | Terminal(string input); 67 | int get_id() const; 68 | private: 69 | 70 | }; 71 | 72 | class Nonterminal : public Symbol 73 | { 74 | public: 75 | unordered_set follow_set; 76 | 77 | Nonterminal(); 78 | Nonterminal(string input); 79 | int get_id() const; 80 | 81 | private: 82 | }; 83 | 84 | class Production 85 | { 86 | public: 87 | Nonterminal* left; 88 | vector right; 89 | 90 | Production(); 91 | Production(Nonterminal* start, const vector& symbol); 92 | void init(Nonterminal* start, const vector& symbol); 93 | friend ostream& operator<<(ostream& out, Production production); 94 | 95 | private: 96 | }; 97 | 98 | class ContextFreeGrammar 99 | { 100 | public: 101 | struct Ter_pointer_hash 102 | { 103 | size_t operator()(Terminal* input) const { 104 | std::hash hash_fn; 105 | return hash_fn(input->value); 106 | } 107 | }; 108 | struct Ter_pointer_hash_compare 109 | { 110 | bool operator()(Terminal* input1, Terminal* input2) const { 111 | return input1->value == input2->value; 112 | } 113 | }; 114 | struct Non_pointer_hash 115 | { 116 | size_t operator()(Nonterminal* input) const { 117 | std::hash hash_fn; 118 | return hash_fn(input->value); 119 | } 120 | }; 121 | struct Non_pointer_hash_compare 122 | { 123 | bool operator()(Nonterminal* input1, Nonterminal* input2) const { 124 | return input1->value == input2->value; 125 | } 126 | }; 127 | unordered_set terminal_set; 128 | unordered_set nonterminal_set; 129 | unordered_set production_set; 130 | Nonterminal* start_symbol; 131 | Terminal* end_symbol; 132 | 133 | ContextFreeGrammar(); 134 | 135 | void set_first(); 136 | void set_follow(); 137 | void input_productions(string file); 138 | void add_production(string left, string right); 139 | void set_start(string s); 140 | 141 | void test_function(); 142 | 143 | // deal with the context-free grammar 144 | // supposed to use dynamic binding 145 | }; 146 | 147 | } -------------------------------------------------------------------------------- /compiler/ControlAction.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hlh981029/c-compiler/b7a3afe0b050d92f7b946f64f5a28d8e5e49183c/compiler/ControlAction.cpp -------------------------------------------------------------------------------- /compiler/DeclarationAction.cpp: -------------------------------------------------------------------------------- 1 | #include "GrammerAnalyzer.h" 2 | using namespace hbst; 3 | 4 | void GrammerAnalyzer::action201(hebo::LexicalUnit* root) { 5 | root->father->attribute.type = "void"; 6 | root->father->attribute.width = 0; 7 | root->father->attribute.if_struct = false; 8 | return; 9 | } 10 | 11 | void GrammerAnalyzer::action202(hebo::LexicalUnit* root) { 12 | root->father->attribute.type = "char"; 13 | root->father->attribute.width = 1; 14 | root->father->attribute.if_struct = false; 15 | return; 16 | } 17 | 18 | void GrammerAnalyzer::action203(hebo::LexicalUnit* root) { 19 | root->father->attribute.type = "int"; 20 | root->father->attribute.width = 4; 21 | root->father->attribute.if_struct = false; 22 | return; 23 | } 24 | 25 | void GrammerAnalyzer::action204(hebo::LexicalUnit* root) { 26 | hebo::LexicalUnit* to = root->father; 27 | hebo::LexicalUnit* from = root->father->child_node_list[0]; 28 | to->attribute.type = from->attribute.type; 29 | to->attribute.width = from->attribute.width; 30 | to->attribute.if_struct = true; 31 | to->attribute.struct_info = from->attribute.struct_info; 32 | return; 33 | } 34 | 35 | void GrammerAnalyzer::action211(hebo::LexicalUnit* root) { 36 | root->father->morpheme = root->father->child_node_list[0]->morpheme; 37 | root->father->attribute.type = root->father->attribute.type; 38 | root->father->attribute.width = root->father->attribute.width; 39 | return; 40 | } 41 | 42 | void GrammerAnalyzer::action212(hebo::LexicalUnit* root) { 43 | root->father->morpheme = root->father->child_node_list[0]->morpheme; 44 | root->father->attribute.type = root->father->attribute.type + "[" + std::to_string(constant_map[root->father->child_node_list[2]->attribute.addr]) + "]"; 45 | root->father->attribute.width = root->father->attribute.width * constant_map[root->father->child_node_list[2]->attribute.addr]; 46 | return; 47 | } 48 | 49 | void GrammerAnalyzer::action213(hebo::LexicalUnit* root) { 50 | root->father->attribute.addr = root->father->child_node_list[1]->attribute.addr; 51 | root->father->attribute.type = root->father->child_node_list[1]->attribute.type; 52 | root->father->attribute.width = root->father->child_node_list[1]->attribute.width; 53 | return; 54 | } 55 | 56 | void GrammerAnalyzer::action214(hebo::LexicalUnit* root) { 57 | root->father->child_node_list[1]->attribute.type = root->father->attribute.type; 58 | root->father->child_node_list[1]->attribute.width = root->father->attribute.width; 59 | return; 60 | } 61 | 62 | void GrammerAnalyzer::action215(hebo::LexicalUnit* root) { 63 | root->father->morpheme = root->father->child_node_list[1]->morpheme; 64 | root->father->attribute.type = root->father->child_node_list[1]->attribute.type; 65 | root->father->attribute.width = root->father->child_node_list[1]->attribute.width; 66 | return; 67 | } 68 | 69 | void GrammerAnalyzer::action216(hebo::LexicalUnit* root) { 70 | hebo::LexicalUnit* to = root->father->child_node_list[1]; 71 | hebo::LexicalUnit* from = root->father; 72 | if (from->attribute.if_struct == true) { 73 | to->attribute.struct_info = from->attribute.struct_info; 74 | } 75 | to->attribute.if_struct = from->attribute.if_struct; 76 | to->attribute.type = from->attribute.type; 77 | to->attribute.width = from->attribute.width; 78 | return; 79 | } 80 | 81 | void GrammerAnalyzer::action217(hebo::LexicalUnit* root) { 82 | hebo::LexicalUnit* child = root->father->child_node_list[1]; 83 | hebo::LexicalUnit* parent = root->father; 84 | if (child->attribute.if_struct == true) { 85 | this->out_table->put_symbol(hbst::SymbolItem(child->morpheme, child->attribute.type, 0, child->attribute.width)); 86 | } 87 | else { 88 | this->out_table->put_symbol(hbst::SymbolItem(child->morpheme, child->attribute.type, 0, child->attribute.width)); 89 | } 90 | return; 91 | } 92 | 93 | void GrammerAnalyzer::action218(hebo::LexicalUnit* root) { 94 | hebo::LexicalUnit* child1 = root->father->child_node_list[0]; 95 | hebo::LexicalUnit* child2 = root->father->child_node_list[2]; 96 | if (child1->attribute.if_struct == true) { 97 | child2->attribute.struct_info = child1->attribute.struct_info; 98 | } 99 | child2->attribute.if_struct = child1->attribute.if_struct; 100 | child2->attribute.type = child1->attribute.type; 101 | child2->attribute.width = child1->attribute.width; 102 | return; 103 | } 104 | 105 | void GrammerAnalyzer::action219(hebo::LexicalUnit* root) { 106 | hebo::LexicalUnit* parent = root->father; 107 | hebo::LexicalUnit* child = root->father->child_node_list[1]; 108 | if (parent->attribute.if_struct == true) { 109 | child->attribute.struct_info = parent->attribute.struct_info; 110 | } 111 | child->attribute.width = parent->attribute.width; 112 | child->attribute.type = parent->attribute.type; 113 | child->attribute.if_struct = parent->attribute.if_struct; 114 | return; 115 | } 116 | 117 | 118 | void GrammerAnalyzer::action220(hebo::LexicalUnit* root) { 119 | hebo::LexicalUnit* parent = root->father; 120 | hebo::LexicalUnit* child_list = root->father->child_node_list[1]; 121 | if (parent->attribute.if_struct == true) { 122 | child_list->attribute.struct_info = parent->attribute.struct_info; 123 | } 124 | child_list->attribute.width = parent->attribute.width; 125 | child_list->attribute.type = parent->attribute.type; 126 | child_list->attribute.if_struct = parent->attribute.if_struct; 127 | return; 128 | } 129 | 130 | void GrammerAnalyzer::action221(hebo::LexicalUnit* root) { 131 | hebo::LexicalUnit* parent = root->father; 132 | hebo::LexicalUnit* child = root->father->child_node_list[4]; 133 | if (parent->attribute.if_struct == true) { 134 | child->attribute.struct_info = parent->attribute.struct_info; 135 | } 136 | child->attribute.width = parent->attribute.width; 137 | child->attribute.type = parent->attribute.type; 138 | child->attribute.if_struct = parent->attribute.if_struct; 139 | return; 140 | } 141 | 142 | void GrammerAnalyzer::action222(hebo::LexicalUnit* root) { 143 | root->father->attribute.type = root->father->child_node_list[0]->attribute.type; 144 | return; 145 | } 146 | 147 | void GrammerAnalyzer::action223(hebo::LexicalUnit* root) { 148 | hebo::LexicalUnit* init_declarator = root->father; 149 | hebo::LexicalUnit* declarator = root->father->child_node_list[1]; 150 | hebo::LexicalUnit* initializer = root->father->child_node_list[3]; 151 | if (init_declarator->attribute.if_struct == true) { 152 | declarator->attribute.struct_info = init_declarator->attribute.struct_info; 153 | } 154 | declarator->attribute.if_struct = init_declarator->attribute.if_struct; 155 | declarator->attribute.type = init_declarator->attribute.type; 156 | declarator->attribute.width = init_declarator->attribute.width; 157 | return; 158 | } 159 | 160 | void GrammerAnalyzer::action224(hebo::LexicalUnit* root) { 161 | hebo::LexicalUnit* declarator = root->father->child_node_list[1]; 162 | hebo::LexicalUnit* initializer = root->father->child_node_list[3]; 163 | hbst::SymbolItem temp_item = hbst::SymbolItem(declarator->morpheme, declarator->attribute.type, 0, declarator->attribute.width); 164 | this->out_table->put_symbol(temp_item); 165 | declarator->attribute.addr = temp_item.address; 166 | if (initializer->attribute.type == "") { 167 | initializer->attribute.type = this->out_table->get_symbol_from_address(initializer->attribute.addr).type; 168 | } 169 | if (declarator->attribute.type != initializer->attribute.type) { 170 | this->say_error(1, initializer->attribute.type, declarator->attribute.type); 171 | } 172 | else { 173 | std::string type = root->father->child_node_list[1]->attribute.type; 174 | if (type.substr(0, 6) == "struct" && type[type.size() - 1] != ']') { 175 | three_address_instruction* assign = new three_address_instruction(); 176 | assign->index = this->final_instruction.size(); 177 | assign->op = "="; 178 | assign->arg1 = initializer->attribute.addr; 179 | assign->arg2 = "-"; 180 | assign->result = declarator->attribute.addr; 181 | this->final_instruction.push_back(assign); 182 | } 183 | else if (type.substr(0, 6) == "struct" && type[type.size() - 1] == ']') { 184 | this->say_error(1, "struct[]", "struct"); 185 | } 186 | else if (type.substr(0, 4) == "int[") { 187 | int temp_size = initializer->attribute.array_info.element_addr.size(); 188 | if (temp_size == 0) { 189 | this->say_error(1, "Array Is Empty", "Array Is Empty"); 190 | } 191 | else { 192 | if (declarator->attribute.width / 4 != temp_size) { 193 | this->say_error(1, "Array Out Of Bounds!", "Array Out Of Bounds!"); 194 | } 195 | else { 196 | for (int tt = 0; tt < temp_size; tt++) { 197 | three_address_instruction* copy = new three_address_instruction(); 198 | copy->index = this->final_instruction.size(); 199 | copy->op = "[]="; 200 | copy->arg1 = declarator->attribute.addr; 201 | copy->arg2 = std::to_string(tt*4); 202 | copy->result = initializer->attribute.array_info.element_addr[tt]; 203 | this->final_instruction.push_back(copy); 204 | } 205 | } 206 | } 207 | } 208 | else if (type == "int") 209 | { 210 | if (initializer->attribute.array_info.name != "") { 211 | three_address_instruction* copy = new three_address_instruction(); 212 | copy->index = this->final_instruction.size(); 213 | copy->op = "=[]"; 214 | copy->arg1 = initializer->attribute.array_info.name; 215 | copy->arg2 = initializer->attribute.array_info.pos; 216 | copy->result = declarator->attribute.addr; 217 | this->final_instruction.push_back(copy); 218 | } 219 | else { 220 | three_address_instruction* copy = new three_address_instruction(); 221 | copy->index = this->final_instruction.size(); 222 | copy->op = "="; 223 | copy->arg1 = initializer->attribute.addr; 224 | copy->result = declarator->attribute.addr; 225 | this->final_instruction.push_back(copy); 226 | } 227 | } 228 | else { 229 | this->say_error(1, type, "NOWAY"); 230 | } 231 | } 232 | return; 233 | } 234 | 235 | void GrammerAnalyzer::action225(hebo::LexicalUnit* root) { 236 | root->father->attribute.addr = root->father->child_node_list[0]->attribute.addr; 237 | root->father->attribute.type = root->father->child_node_list[0]->attribute.type; 238 | root->father->attribute.array_info.name = root->father->child_node_list[0]->attribute.array_info.name; 239 | root->father->attribute.array_info.pos = root->father->child_node_list[0]->attribute.array_info.pos; 240 | return; 241 | } 242 | 243 | void GrammerAnalyzer::action226(hebo::LexicalUnit* root) { 244 | root->father->attribute.array_info.element_addr = root->father->child_node_list[1]->attribute.array_info.element_addr; 245 | root->father->attribute.type = "int[" + std::to_string(root->father->child_node_list[1]->attribute.array_info.element_addr.size()) + "]"; 246 | return; 247 | } 248 | 249 | void GrammerAnalyzer::action227(hebo::LexicalUnit* root) { 250 | root->father->attribute.array_info.element_addr = root->father->child_node_list[1]->attribute.array_info.element_addr; 251 | return; 252 | } 253 | 254 | void GrammerAnalyzer::action228(hebo::LexicalUnit* root) { 255 | hebo::LexicalUnit* assignment = root->father->child_node_list[0]; 256 | root->father->attribute.array_info.element_addr.push_back(assignment->attribute.addr); 257 | assignment->attribute.type = this->out_table->get_symbol_from_address(assignment->attribute.addr).type; 258 | if (assignment->attribute.type != "int") { 259 | this->say_error(1, assignment->attribute.type, "int"); 260 | } 261 | return; 262 | } 263 | 264 | void GrammerAnalyzer::action229(hebo::LexicalUnit* root) { 265 | hebo::LexicalUnit* assignment = root->father->child_node_list[2]; 266 | assignment->attribute.type = this->out_table->get_symbol_from_address(assignment->attribute.addr).type; 267 | root->father->attribute.array_info.element_addr = root->father->child_node_list[0]->attribute.array_info.element_addr; 268 | root->father->attribute.array_info.element_addr.push_back(assignment->attribute.addr); 269 | if (assignment->attribute.type != "int") { 270 | this->say_error(1, assignment->attribute.type, "int"); 271 | } 272 | return; 273 | } 274 | 275 | void GrammerAnalyzer::action230(hebo::LexicalUnit* root) { 276 | SymbolTable *temp_table = this->out_table; 277 | this->out_table = temp_table->father; 278 | temp_table->father = nullptr; 279 | this->out_table->son_vector.pop_back(); 280 | root->father->attribute.width = root->father->child_node_list[4]->attribute.width; 281 | root->father->attribute.if_struct = true; 282 | hbst::SymbolItem temp_item(root->father->child_node_list[1]->morpheme, "struct", 0, root->father->attribute.width); 283 | this->out_table->put_symbol(temp_item); 284 | std::string temp_address = this->out_table->get_symbol(root->father->child_node_list[1]->morpheme).address; 285 | this->struct_table->put_struct(hbst::StructItem(temp_address, *temp_table)); 286 | root->father->attribute.type = "struct " + temp_address; 287 | root->father->attribute.struct_info = struct_table->get_struct(temp_address); 288 | return; 289 | } 290 | 291 | void GrammerAnalyzer::action231(hebo::LexicalUnit* root) { 292 | SymbolTable *temp_table = new SymbolTable("", this->out_table); 293 | this->out_table = temp_table; 294 | } 295 | 296 | void GrammerAnalyzer::action232(hebo::LexicalUnit* root) { 297 | SymbolTable *temp_table = new SymbolTable("", this->out_table); 298 | this->out_table = temp_table; 299 | } 300 | 301 | void GrammerAnalyzer::action233(hebo::LexicalUnit* root) { 302 | SymbolTable *temp_table = this->out_table; 303 | this->out_table = temp_table->father; 304 | temp_table->father = nullptr; 305 | this->out_table->son_vector.pop_back(); 306 | root->father->attribute.width = root->father->child_node_list[3]->attribute.width; 307 | root->father->attribute.if_struct = true; 308 | hbst::SymbolItem temp_item("", "struct", 0, root->father->attribute.width); 309 | this->out_table->put_symbol(temp_item); 310 | std::string temp_address = temp_item.address; 311 | this->struct_table->put_struct(hbst::StructItem(temp_address, *temp_table)); 312 | root->father->attribute.type = "struct " + temp_address; 313 | root->father->attribute.struct_info = struct_table->get_struct(temp_address); 314 | return; 315 | } 316 | 317 | void GrammerAnalyzer::action234(hebo::LexicalUnit* root) { 318 | root->father->attribute.if_struct = true; 319 | std::string temp = this->out_table->get_symbol(root->father->child_node_list[1]->morpheme).address; 320 | root->father->attribute.struct_info = struct_table->get_struct(temp); 321 | root->father->attribute.type = "struct " + root->father->attribute.struct_info.name; 322 | root->father->attribute.width = this->out_table->get_symbol(root->father->child_node_list[1]->morpheme).width; 323 | return; 324 | } 325 | 326 | void GrammerAnalyzer::action235(hebo::LexicalUnit* root) { 327 | root->father->attribute.width = root->father->child_node_list[0]->attribute.width; 328 | return; 329 | } 330 | 331 | void GrammerAnalyzer::action236(hebo::LexicalUnit* root) { 332 | root->father->attribute.width = root->father->child_node_list[0]->attribute.width + root->father->child_node_list[1]->attribute.width; 333 | return; 334 | } 335 | 336 | void GrammerAnalyzer::action237(hebo::LexicalUnit* root) { 337 | root->father->child_node_list[2]->attribute.type = root->father->child_node_list[0]->attribute.type; 338 | root->father->child_node_list[2]->attribute.width = root->father->child_node_list[0]->attribute.width; 339 | return; 340 | } 341 | 342 | void GrammerAnalyzer::action238(hebo::LexicalUnit* root) { 343 | root->father->attribute.width = root->father->child_node_list[2]->attribute.width; 344 | root->father->attribute.type = root->father->child_node_list[0]->attribute.type; 345 | return; 346 | } 347 | 348 | void GrammerAnalyzer::action239(hebo::LexicalUnit* root) { 349 | root->father->child_node_list[1]->attribute.type = root->father->attribute.type; 350 | root->father->child_node_list[1]->attribute.width = root->father->attribute.width; 351 | return; 352 | } 353 | 354 | void GrammerAnalyzer::action240(hebo::LexicalUnit* root) { 355 | root->father->attribute.width = root->father->child_node_list[1]->attribute.width; 356 | this->out_table->put_symbol(SymbolItem(root->father->child_node_list[1]->morpheme, root->father->child_node_list[1]->attribute.type, 0, root->father->child_node_list[1]->attribute.width)); 357 | return; 358 | } 359 | 360 | void GrammerAnalyzer::action241(hebo::LexicalUnit* root) { 361 | root->father->child_node_list[1]->attribute.type = root->father->attribute.type; 362 | root->father->child_node_list[1]->attribute.width = root->father->attribute.width; 363 | root->father->child_node_list[3]->attribute.type = root->father->attribute.type; 364 | root->father->child_node_list[3]->attribute.width = root->father->attribute.width; 365 | return; 366 | } 367 | 368 | void GrammerAnalyzer::action242(hebo::LexicalUnit* root) { 369 | root->father->attribute.width = root->father->child_node_list[1]->attribute.width + root->father->child_node_list[3]->attribute.width; 370 | this->out_table->put_symbol(SymbolItem(root->father->child_node_list[3]->morpheme, root->father->child_node_list[3]->attribute.type, 0, root->father->child_node_list[3]->attribute.width)); 371 | return; 372 | } -------------------------------------------------------------------------------- /compiler/ExpressionAction.cpp: -------------------------------------------------------------------------------- 1 | #include "GrammerAnalyzer.h" 2 | 3 | void GrammerAnalyzer::action1(hebo::LexicalUnit* root) { 4 | root->father->attribute.addr = this->out_table->get_symbol(root->father->child_node_list[0]->morpheme).address; 5 | root->father->attribute.type = this->out_table->get_symbol(root->father->child_node_list[0]->morpheme).type; 6 | three_address_instruction* no_use = new three_address_instruction(); 7 | no_use->index = this->final_instruction.size(); 8 | no_use->op = "JZ"; 9 | no_use->arg1 = "1"; 10 | no_use->arg2 = "-"; 11 | no_use->result = std::to_string(no_use->index); 12 | this->final_instruction.push_back(no_use); 13 | return; 14 | } 15 | 16 | void GrammerAnalyzer::action2(hebo::LexicalUnit* root) { 17 | hbst::SymbolItem temp = hbst::SymbolItem("", "int", 0, 4); 18 | this->out_table->put_symbol(temp); 19 | root->father->attribute.addr = temp.address; 20 | root->father->attribute.type = "int"; 21 | constant_map.insert(std::make_pair(temp.address, std::atoi(root->father->child_node_list[0]->morpheme.c_str()))); 22 | three_address_instruction* assignment = new three_address_instruction(); 23 | assignment->index = this->final_instruction.size(); 24 | assignment->op = "="; 25 | assignment->arg1 = root->father->child_node_list[0]->morpheme; 26 | assignment->arg2 = "-"; 27 | assignment->result = root->father->attribute.addr; 28 | this->final_instruction.push_back(assignment); 29 | return; 30 | } 31 | 32 | void GrammerAnalyzer::action3(hebo::LexicalUnit* root) { 33 | return; 34 | } 35 | 36 | void GrammerAnalyzer::action4(hebo::LexicalUnit* root) { 37 | root->father->attribute.addr = root->father->child_node_list[1]->attribute.addr; 38 | root->father->attribute.type = root->father->child_node_list[1]->attribute.type; 39 | root->father->attribute.array_info.name = root->father->child_node_list[1]->attribute.array_info.name; 40 | root->father->attribute.array_info.pos = root->father->child_node_list[1]->attribute.array_info.pos; 41 | root->father->attribute.array_info.element_width = root->father->child_node_list[1]->attribute.array_info.element_width; 42 | root->father->attribute.array_info.element_type = root->father->child_node_list[1]->attribute.array_info.element_type; 43 | root->father->attribute.array_info.element_addr = root->father->child_node_list[1]->attribute.array_info.element_addr; 44 | return; 45 | } 46 | 47 | void GrammerAnalyzer::action5(hebo::LexicalUnit* root) { 48 | root->father->attribute.addr = root->father->child_node_list[0]->attribute.addr; 49 | root->father->attribute.type = root->father->child_node_list[0]->attribute.type; 50 | root->father->attribute.array_info.name = root->father->child_node_list[0]->attribute.array_info.name; 51 | root->father->attribute.array_info.pos = root->father->child_node_list[0]->attribute.array_info.pos; 52 | root->father->attribute.array_info.element_width = root->father->child_node_list[0]->attribute.array_info.element_width; 53 | root->father->attribute.array_info.element_type = root->father->child_node_list[0]->attribute.array_info.element_type; 54 | root->father->attribute.array_info.element_addr = root->father->child_node_list[0]->attribute.array_info.element_addr; 55 | 56 | return; 57 | } 58 | 59 | void GrammerAnalyzer::action6(hebo::LexicalUnit* root) { 60 | std::string type = this->out_table->get_symbol(root->father->child_node_list[0]->morpheme).type; 61 | if (type[type.size() - 1] != ']') { 62 | this->say_error(1, type, type+"[]"); 63 | } 64 | if (this->out_table->get_symbol_from_address(root->father->child_node_list[2]->attribute.addr).type != "int") { 65 | this->say_error(1, this->out_table->get_symbol_from_address(root->father->child_node_list[2]->attribute.addr).type, "int"); 66 | } 67 | if (type.substr(0, 3) == "int") { 68 | hbst::SymbolItem temp = hbst::SymbolItem("", "int", 0, 4); 69 | hbst::SymbolItem offset = hbst::SymbolItem("", "int", 0, 4); 70 | this->out_table->put_symbol(offset); 71 | this->out_table->put_symbol(temp); 72 | root->father->attribute.addr = temp.address; 73 | root->father->attribute.array_info.name = this->out_table->get_symbol(root->father->child_node_list[0]->morpheme).address; 74 | three_address_instruction* assignment = new three_address_instruction(); 75 | assignment->index = this->final_instruction.size(); 76 | assignment->op = "*"; 77 | assignment->arg1 = std::to_string(4); 78 | assignment->arg2 = root->father->child_node_list[2]->attribute.addr; 79 | assignment->result = offset.name; 80 | this->final_instruction.push_back(assignment); 81 | three_address_instruction* get_addr = new three_address_instruction(); 82 | get_addr->index = this->final_instruction.size(); 83 | get_addr->op = "=[]"; 84 | get_addr->arg1 = root->father->attribute.array_info.name; 85 | get_addr->arg2 = offset.name; 86 | get_addr->result = root->father->attribute.addr; 87 | this->final_instruction.push_back(get_addr); 88 | root->father->attribute.array_info.pos = offset.name; 89 | root->father->attribute.type = "int"; 90 | } 91 | else if (type.substr(0, 6) == "struct" && type[type.size() - 1] == ']') { 92 | std::string name = root->father->child_node_list[0]->morpheme + "$" + std::to_string(constant_map[root->father->child_node_list[2]->attribute.addr]); 93 | root->father->attribute.addr = this->out_table->get_symbol(name).address; 94 | root->father->attribute.type = type.substr(0, type.rfind('[')); 95 | } 96 | return; 97 | } 98 | 99 | void GrammerAnalyzer::action7(hebo::LexicalUnit* root) { 100 | std::string temp_type = function_table->get_function(root->father->child_node_list[0]->attribute.addr).return_type; 101 | hbst::SymbolItem temp; 102 | if (temp_type == "void") { 103 | three_address_instruction* call = new three_address_instruction(); 104 | call->index = this->final_instruction.size(); 105 | call->op = "CALL"; 106 | call->arg1 = root->father->child_node_list[0]->attribute.addr; 107 | call->arg2 = "-"; 108 | call->result = "-"; 109 | this->final_instruction.push_back(call); 110 | root->father->attribute.type = temp_type; 111 | return; 112 | } 113 | else if (temp_type == "int") { 114 | temp = hbst::SymbolItem("", "int", 0, 4); 115 | } 116 | else { 117 | temp = hbst::SymbolItem("", temp_type, 0, out_table->get_symbol(temp_type.substr(0, temp_type.find("$"))).width); 118 | } 119 | this->out_table->put_symbol(temp); 120 | three_address_instruction* call = new three_address_instruction(); 121 | call->index = this->final_instruction.size(); 122 | call->op = "CALL"; 123 | call->arg1 = root->father->child_node_list[0]->attribute.addr; 124 | call->arg2 = "-"; 125 | call->result = temp.address; 126 | this->final_instruction.push_back(call); 127 | root->father->attribute.addr = temp.address; 128 | root->father->attribute.type = temp.type; 129 | return; 130 | } 131 | 132 | void GrammerAnalyzer::action8(hebo::LexicalUnit* root) { 133 | std::string temp_type = function_table->get_function(root->father->child_node_list[0]->attribute.addr).return_type; 134 | if (this->check_type(root->father->child_node_list[0]->attribute.addr, this->parameter_list) == false) { 135 | say_error(1, "parameter type not matched", "parameter type not matched"); 136 | return; 137 | } 138 | this->clean_param_list(); 139 | hbst::SymbolItem temp; 140 | if (temp_type == "void") { 141 | three_address_instruction* call = new three_address_instruction(); 142 | call->index = this->final_instruction.size(); 143 | call->op = "CALL"; 144 | call->arg1 = root->father->child_node_list[0]->attribute.addr; 145 | call->arg2 = "-"; 146 | call->result = "-"; 147 | this->final_instruction.push_back(call); 148 | root->father->attribute.type = temp_type; 149 | return; 150 | } 151 | else if (temp_type == "int") { 152 | temp = hbst::SymbolItem("", "int", 0, 4); 153 | } 154 | else { 155 | temp = hbst::SymbolItem("", temp_type, 0, out_table->get_symbol(temp_type.substr(0, temp_type.find("$"))).width); 156 | } 157 | this->out_table->put_symbol(temp); 158 | three_address_instruction* call = new three_address_instruction(); 159 | call->index = this->final_instruction.size(); 160 | call->op = "CALL"; 161 | call->arg1 = root->father->child_node_list[0]->attribute.addr; 162 | call->arg2 = "-"; 163 | call->result = temp.address; 164 | this->final_instruction.push_back(call); 165 | root->father->attribute.addr = temp.address; 166 | root->father->attribute.type = temp.type; 167 | return; 168 | } 169 | 170 | void GrammerAnalyzer::action9(hebo::LexicalUnit* root) { 171 | std::string temp_address = this->out_table->get_symbol(root->father->child_node_list[0]->morpheme).address; 172 | std::string type = this->out_table->get_symbol(root->father->child_node_list[0]->morpheme).type; 173 | if ((type.rfind("struct") >= type.size()) || (type.find('[') < type.size())) { 174 | this->say_error(1, type, "struct[]"); 175 | } 176 | std::string target = root->father->child_node_list[0]->morpheme + "$" + root->father->child_node_list[2]->morpheme; 177 | root->father->attribute.addr = this->out_table->get_symbol(target).address; 178 | root->father->attribute.type = this->struct_table->get_struct(type.substr(7)).symbol_table.get_symbol(root->father->child_node_list[2]->morpheme).type; 179 | return; 180 | } 181 | 182 | void GrammerAnalyzer::action10(hebo::LexicalUnit* root) { 183 | if (root->father->child_node_list[0]->attribute.type != "int") { 184 | this->say_error(1, root->father->child_node_list[0]->attribute.type, "int"); 185 | return; 186 | } 187 | hbst::SymbolItem temp = hbst::SymbolItem("", "int", 0, 4); 188 | this->out_table->put_symbol(temp); 189 | root->father->attribute.addr = temp.address; 190 | three_address_instruction* assignment = new three_address_instruction(); 191 | assignment->index = this->final_instruction.size(); 192 | assignment->op = "="; 193 | assignment->arg1 = root->father->child_node_list[0]->attribute.addr; 194 | assignment->arg2 = "-"; 195 | assignment->result = root->father->attribute.addr; 196 | this->final_instruction.push_back(assignment); 197 | three_address_instruction* add = new three_address_instruction(); 198 | add->index = this->final_instruction.size(); 199 | add->op = "++"; 200 | add->arg1 = root->father->child_node_list[0]->attribute.addr; 201 | add->arg2 = "-"; 202 | add->result = root->father->child_node_list[0]->attribute.addr; 203 | this->final_instruction.push_back(add); 204 | root->father->attribute.type = "int"; 205 | return; 206 | } 207 | 208 | void GrammerAnalyzer::action11(hebo::LexicalUnit* root) { 209 | if (root->father->child_node_list[0]->attribute.type != "int") { 210 | this->say_error(1, root->father->child_node_list[0]->attribute.type, "int"); 211 | return; 212 | } 213 | hbst::SymbolItem temp = hbst::SymbolItem("", "int", 0, 4); 214 | this->out_table->put_symbol(temp); 215 | root->father->attribute.addr = temp.address; 216 | three_address_instruction* assignment = new three_address_instruction(); 217 | assignment->index = this->final_instruction.size(); 218 | assignment->op = "="; 219 | assignment->arg1 = root->father->child_node_list[0]->attribute.addr; 220 | assignment->arg2 = "-"; 221 | assignment->result = root->father->attribute.addr; 222 | this->final_instruction.push_back(assignment); 223 | three_address_instruction* subtract = new three_address_instruction(); 224 | subtract->index = this->final_instruction.size(); 225 | subtract->op = "--"; 226 | subtract->arg1 = root->father->child_node_list[0]->attribute.addr; 227 | subtract->arg2 = "-"; 228 | subtract->result = root->father->child_node_list[0]->attribute.addr; 229 | this->final_instruction.push_back(subtract); 230 | root->father->attribute.type = "int"; 231 | return; 232 | } 233 | 234 | void GrammerAnalyzer::action12(hebo::LexicalUnit* root) { 235 | root->father->attribute.addr = root->father->child_node_list[0]->attribute.addr; 236 | root->father->attribute.type = root->father->child_node_list[0]->attribute.type; 237 | root->father->attribute.array_info.name = root->father->child_node_list[0]->attribute.array_info.name; 238 | root->father->attribute.array_info.pos = root->father->child_node_list[0]->attribute.array_info.pos; 239 | return; 240 | } 241 | 242 | void GrammerAnalyzer::action13(hebo::LexicalUnit* root) { 243 | if (root->father->child_node_list[1]->attribute.type != "int") { 244 | this->say_error(1, root->father->child_node_list[1]->attribute.type, "int"); 245 | return; 246 | } 247 | hbst::SymbolItem temp = hbst::SymbolItem("", "int", 0, 4); 248 | this->out_table->put_symbol(temp); 249 | root->father->attribute.addr = temp.address; 250 | three_address_instruction* add = new three_address_instruction(); 251 | add->index = this->final_instruction.size(); 252 | add->op = "++"; 253 | add->arg1 = root->father->child_node_list[1]->attribute.addr; 254 | add->arg2 = "-"; 255 | add->result = root->father->child_node_list[1]->attribute.addr; 256 | this->final_instruction.push_back(add); 257 | three_address_instruction* assignment = new three_address_instruction(); 258 | assignment->index = this->final_instruction.size(); 259 | assignment->op = "="; 260 | assignment->arg1 = root->father->child_node_list[1]->attribute.addr; 261 | assignment->arg2 = "-"; 262 | assignment->result = root->father->attribute.addr; 263 | this->final_instruction.push_back(assignment); 264 | root->father->attribute.type = "int"; 265 | return; 266 | } 267 | 268 | void GrammerAnalyzer::action14(hebo::LexicalUnit* root) { 269 | if (root->father->child_node_list[1]->attribute.type != "int") { 270 | this->say_error(1, root->father->child_node_list[1]->attribute.type, "int"); 271 | return; 272 | } 273 | hbst::SymbolItem temp = hbst::SymbolItem("", "int", 0, 4); 274 | this->out_table->put_symbol(temp); 275 | root->father->attribute.addr = temp.address; 276 | three_address_instruction* add = new three_address_instruction(); 277 | add->index = this->final_instruction.size(); 278 | add->op = "--"; 279 | add->arg1 = root->father->child_node_list[1]->attribute.addr; 280 | add->arg2 = "-"; 281 | add->result = root->father->child_node_list[1]->attribute.addr; 282 | this->final_instruction.push_back(add); 283 | three_address_instruction* assignment = new three_address_instruction(); 284 | assignment->index = this->final_instruction.size(); 285 | assignment->op = "="; 286 | assignment->arg1 = root->father->child_node_list[1]->attribute.addr; 287 | assignment->arg2 = "-"; 288 | assignment->result = root->father->attribute.addr; 289 | this->final_instruction.push_back(assignment); 290 | root->father->attribute.type = "int"; 291 | return; 292 | } 293 | 294 | void GrammerAnalyzer::action15(hebo::LexicalUnit* root) { 295 | if (root->father->child_node_list[1]->attribute.type != "int") { 296 | this->say_error(1, root->father->child_node_list[1]->attribute.type, "int"); 297 | return; 298 | } 299 | hbst::SymbolItem temp = hbst::SymbolItem("", "int", 0, 4); 300 | this->out_table->put_symbol(temp); 301 | root->father->attribute.addr = temp.address; 302 | if (root->father->child_node_list[0]->attribute.op_value == "-") { 303 | three_address_instruction* minus = new three_address_instruction(); 304 | minus->index = this->final_instruction.size(); 305 | minus->op = "MINUS"; 306 | minus->arg1 = root->father->child_node_list[1]->attribute.addr; 307 | minus->arg2 = "-"; 308 | minus->result = root->father->attribute.addr; 309 | this->final_instruction.push_back(minus); 310 | } 311 | else if (root->father->child_node_list[0]->attribute.op_value == "!") { 312 | three_address_instruction* fei = new three_address_instruction(); 313 | fei->index = this->final_instruction.size(); 314 | fei->op = "!"; 315 | fei->arg1 = root->father->child_node_list[2]->attribute.addr; 316 | fei->arg2 = "-"; 317 | fei->result = root->father->attribute.addr; 318 | this->final_instruction.push_back(fei); 319 | } 320 | else { 321 | this->say_error(1, "OP VALUE ERROR", "OP VALUE ERROR"); 322 | } 323 | root->father->attribute.type = "int"; 324 | return; 325 | } 326 | 327 | void GrammerAnalyzer::action16(hebo::LexicalUnit* root) { 328 | hbst::SymbolItem temp = hbst::SymbolItem("", "int", 0, 4); 329 | this->out_table->put_symbol(temp); 330 | root->father->attribute.addr = temp.address; 331 | three_address_instruction* assignment = new three_address_instruction(); 332 | assignment->index = this->final_instruction.size(); 333 | assignment->op = "="; 334 | assignment->arg1 = root->father->child_node_list[1]->attribute.width; 335 | assignment->arg2 = "-"; 336 | assignment->result = root->father->attribute.addr; 337 | this->final_instruction.push_back(assignment); 338 | return; 339 | } 340 | 341 | void GrammerAnalyzer::action17(hebo::LexicalUnit* root) { 342 | hbst::SymbolItem temp = hbst::SymbolItem("", "int", 0, 4); 343 | this->out_table->put_symbol(temp); 344 | root->father->attribute.addr = temp.address; 345 | three_address_instruction* assignment = new three_address_instruction(); 346 | assignment->index = this->final_instruction.size(); 347 | assignment->op = "="; 348 | assignment->arg1 = root->father->child_node_list[2]->attribute.width; 349 | assignment->arg2 = "-"; 350 | assignment->result = root->father->attribute.addr; 351 | this->final_instruction.push_back(assignment); 352 | return; 353 | } 354 | 355 | void GrammerAnalyzer::action18(hebo::LexicalUnit* root) { 356 | root->father->attribute.op_value = "&"; 357 | return; 358 | } 359 | 360 | void GrammerAnalyzer::action19(hebo::LexicalUnit* root) { 361 | root->father->attribute.op_value = "*"; 362 | return; 363 | } 364 | 365 | void GrammerAnalyzer::action20(hebo::LexicalUnit* root) { 366 | root->father->attribute.op_value = "+"; 367 | return; 368 | } 369 | 370 | void GrammerAnalyzer::action21(hebo::LexicalUnit* root) { 371 | root->father->attribute.op_value = "-"; 372 | return; 373 | } 374 | 375 | void GrammerAnalyzer::action22(hebo::LexicalUnit* root) { 376 | root->father->attribute.op_value = "~"; 377 | return; 378 | } 379 | 380 | void GrammerAnalyzer::action23(hebo::LexicalUnit* root) { 381 | root->father->attribute.op_value = "!"; 382 | return; 383 | } 384 | 385 | void GrammerAnalyzer::action24(hebo::LexicalUnit* root) { 386 | root->father->attribute.addr = root->father->child_node_list[0]->attribute.addr; 387 | root->father->attribute.type = root->father->child_node_list[0]->attribute.type; 388 | root->father->attribute.array_info.name = root->father->child_node_list[0]->attribute.array_info.name; 389 | root->father->attribute.array_info.pos = root->father->child_node_list[0]->attribute.array_info.pos; 390 | return; 391 | } 392 | 393 | void GrammerAnalyzer::action25(hebo::LexicalUnit* root) { 394 | hbst::SymbolItem temp = hbst::SymbolItem("", root->father->child_node_list[1]->attribute.type, 0, 4); 395 | this->out_table->put_symbol(temp); 396 | root->father->attribute.addr = temp.address; 397 | three_address_instruction* assignment = new three_address_instruction(); 398 | assignment->index = this->final_instruction.size(); 399 | assignment->op = "="; 400 | assignment->arg1 = root->father->child_node_list[0]->attribute.addr; 401 | assignment->arg2 = "-"; 402 | assignment->result = root->father->attribute.addr; 403 | this->final_instruction.push_back(assignment); 404 | return; 405 | } 406 | 407 | void GrammerAnalyzer::action26(hebo::LexicalUnit* root) { 408 | three_address_instruction* param = new three_address_instruction(); 409 | param->index = this->final_instruction.size(); 410 | param->op = "PARAM"; 411 | param->arg1 = root->father->child_node_list[0]->attribute.addr; 412 | param->arg2 = "-"; 413 | param->result = "-"; 414 | this->final_instruction.push_back(param); 415 | this->parameter_list.push_back(this->out_table->get_symbol_from_address(root->father->child_node_list[0]->attribute.addr).type); 416 | root->father->attribute.param_number = 1; 417 | return; 418 | } 419 | 420 | void GrammerAnalyzer::action27(hebo::LexicalUnit* root) { 421 | three_address_instruction* param = new three_address_instruction(); 422 | param->index = this->final_instruction.size(); 423 | param->op = "PARAM"; 424 | param->arg1 = root->father->child_node_list[2]->attribute.addr; 425 | param->arg2 = "-"; 426 | param->result = "-"; 427 | this->final_instruction.push_back(param); 428 | this->parameter_list.push_back(this->out_table->get_symbol_from_address(root->father->child_node_list[2]->attribute.addr).type); 429 | root->father->attribute.param_number += 1; 430 | return; 431 | } -------------------------------------------------------------------------------- /compiler/FunctionAction.cpp: -------------------------------------------------------------------------------- 1 | #include "GrammerAnalyzer.h" 2 | using namespace hbst; 3 | void GrammerAnalyzer::action101(hebo::LexicalUnit* root) { 4 | return; 5 | } 6 | 7 | void GrammerAnalyzer::action102(hebo::LexicalUnit* root) { 8 | root->father->child_node_list[2]->attribute.con_instr = root->father->attribute.con_instr; 9 | root->father->child_node_list[2]->attribute.break_instr = root->father->attribute.break_instr; 10 | SymbolTable* temptable = new SymbolTable("", this->out_table); 11 | this->out_table = temptable; 12 | return; 13 | } 14 | 15 | void GrammerAnalyzer::action103(hebo::LexicalUnit* root) { 16 | SymbolTable* temptable = new SymbolTable("", this->out_table); 17 | this->out_table = temptable; 18 | return; 19 | } 20 | 21 | void GrammerAnalyzer::action104(hebo::LexicalUnit* root) { 22 | root->father->child_node_list[3]->attribute.con_instr = root->father->attribute.con_instr; 23 | root->father->child_node_list[3]->attribute.break_instr = root->father->attribute.break_instr; 24 | SymbolTable* temptable = new SymbolTable("", this->out_table); 25 | this->out_table = temptable; 26 | return; 27 | } 28 | 29 | void GrammerAnalyzer::action109(hebo::LexicalUnit* root) { 30 | return; 31 | } 32 | 33 | void GrammerAnalyzer::action110(hebo::LexicalUnit* root) { 34 | return; 35 | } 36 | 37 | void GrammerAnalyzer::action111(hebo::LexicalUnit* root) { 38 | return; 39 | } 40 | 41 | void GrammerAnalyzer::action112(hebo::LexicalUnit* root) { 42 | return; 43 | } 44 | 45 | void GrammerAnalyzer::action113(hebo::LexicalUnit* root) { 46 | this->out_table = &global_symbol_table; 47 | this->struct_table = &global_struct_table; 48 | this->function_table = &global_function_table; 49 | return; 50 | } 51 | 52 | void GrammerAnalyzer::action114(hebo::LexicalUnit* root) { 53 | this->out_table = out_table->father; 54 | return; 55 | } 56 | 57 | void GrammerAnalyzer::action115(hebo::LexicalUnit* root) { 58 | this->out_table = out_table->father; 59 | return; 60 | } 61 | 62 | void GrammerAnalyzer::action116(hebo::LexicalUnit* root) { 63 | this->out_table = out_table->father; 64 | return; 65 | } 66 | 67 | void GrammerAnalyzer::action601(hebo::LexicalUnit* root) { 68 | root->father->child_node_list[1]->attribute.type = root->father->attribute.type; 69 | return; 70 | } 71 | 72 | void GrammerAnalyzer::action602(hebo::LexicalUnit* root) { 73 | SymbolItem temp_item; 74 | try { 75 | temp_item = this->out_table->get_symbol_from_address(root->father->child_node_list[1]->attribute.addr); 76 | } 77 | catch (std::string &s) { 78 | SymbolItem new_symbol_item(root->father->child_node_list[1]->morpheme, "function", 0, 0); 79 | this->out_table->put_symbol(new_symbol_item); 80 | temp_item = new_symbol_item; 81 | } 82 | FunctionItem func_item(temp_item.name, root->father->child_node_list[1]->attribute.type); 83 | function_table->put_function(func_item); 84 | root->father->child_node_list[4]->morpheme = temp_item.name; 85 | root->father->morpheme = root->father->child_node_list[1]->morpheme; 86 | 87 | return; 88 | } 89 | 90 | void GrammerAnalyzer::action603(hebo::LexicalUnit* root) { 91 | root->father->child_node_list[1]->attribute.type = root->father->attribute.type; 92 | return; 93 | } 94 | 95 | void GrammerAnalyzer::action604(hebo::LexicalUnit* root) { 96 | SymbolItem temp_item; 97 | try { 98 | temp_item = this->out_table->get_symbol_from_address(root->father->child_node_list[1]->attribute.addr); 99 | } 100 | catch (std::string &s) { 101 | SymbolItem new_symbol_item(root->father->child_node_list[1]->morpheme, "function", 0, 0); 102 | this->out_table->put_symbol(new_symbol_item); 103 | temp_item = new_symbol_item; 104 | } 105 | FunctionItem func_item(temp_item.name, root->father->child_node_list[1]->attribute.type); 106 | function_table->put_function(func_item); 107 | root->father->morpheme = root->father->child_node_list[1]->morpheme; 108 | 109 | return; 110 | } 111 | 112 | void GrammerAnalyzer::action605(hebo::LexicalUnit* root) { 113 | this->function_table->get_function(root->father->morpheme).add_parameter(root->father->child_node_list[0]->attribute.type); 114 | var_width_list.push_back(root->father->child_node_list[0]->attribute.width); 115 | var_name_list.push_back(root->father->child_node_list[0]->morpheme); 116 | return; 117 | } 118 | 119 | void GrammerAnalyzer::action618(hebo::LexicalUnit* root) { 120 | root->father->child_node_list[1]->morpheme = root->father->morpheme; 121 | return; 122 | } 123 | 124 | void GrammerAnalyzer::action606(hebo::LexicalUnit* root) { 125 | this->function_table->get_function(root->father->morpheme).add_parameter(root->father->child_node_list[3]->attribute.type); 126 | var_width_list.push_back(root->father->child_node_list[3]->attribute.width); 127 | var_name_list.push_back(root->father->child_node_list[3]->morpheme); 128 | return; 129 | } 130 | 131 | void GrammerAnalyzer::action607(hebo::LexicalUnit* root) { 132 | root->father->attribute.type = root->father->child_node_list[0]->attribute.type; 133 | root->father->attribute.width = root->father->child_node_list[0]->attribute.width; 134 | root->father->morpheme = root->father->child_node_list[1]->morpheme; 135 | return; 136 | } 137 | 138 | void GrammerAnalyzer::action608(hebo::LexicalUnit* root) { 139 | root->father->attribute.type = root->father->child_node_list[0]->attribute.type; 140 | root->father->attribute.width = root->father->child_node_list[0]->attribute.width; 141 | root->father->morpheme = ""; 142 | return; 143 | } 144 | 145 | void GrammerAnalyzer::action609(hebo::LexicalUnit* root) { 146 | return; 147 | } 148 | 149 | void GrammerAnalyzer::action610(hebo::LexicalUnit* root) { 150 | curr_func_name = root->father->morpheme; 151 | three_address_instruction* temp_instruction = new three_address_instruction(); 152 | temp_instruction->index = this->final_instruction.size(); 153 | temp_instruction->op = "FUNC"; 154 | temp_instruction->arg1 = curr_func_name; 155 | temp_instruction->arg2 = "-"; 156 | temp_instruction->result = "-"; 157 | this->final_instruction.push_back(temp_instruction); 158 | SymbolTable * temp_table = new SymbolTable(curr_func_name, this->out_table); 159 | FunctionItem func_item = function_table->get_function(curr_func_name); 160 | this->out_table = temp_table; 161 | for (int count = 0; count < var_name_list.size(); count++) { 162 | out_table->put_symbol(SymbolItem(var_name_list[count], func_item.parameter_vector[count], 0, var_width_list[count])); 163 | } 164 | var_name_list.clear(); 165 | var_width_list.clear(); 166 | return; 167 | } 168 | 169 | void GrammerAnalyzer::action611(hebo::LexicalUnit* root) { 170 | three_address_instruction* temp_instruction = new three_address_instruction(); 171 | temp_instruction->index = this->final_instruction.size(); 172 | temp_instruction->op = "ENDF"; 173 | temp_instruction->arg1 = curr_func_name; 174 | temp_instruction->arg2 = "-"; 175 | temp_instruction->result = "-"; 176 | this->final_instruction.push_back(temp_instruction); 177 | out_table = out_table->father; 178 | return; 179 | } 180 | 181 | void GrammerAnalyzer::action612(hebo::LexicalUnit* root) { 182 | curr_func_name = root->father->morpheme; 183 | three_address_instruction* temp_instruction = new three_address_instruction(); 184 | temp_instruction->index = this->final_instruction.size(); 185 | temp_instruction->op = "FUNC"; 186 | temp_instruction->arg1 = curr_func_name; 187 | temp_instruction->arg2 = "-"; 188 | temp_instruction->result = "-"; 189 | this->final_instruction.push_back(temp_instruction); 190 | SymbolTable * temp_table = new SymbolTable(curr_func_name, this->out_table); 191 | FunctionItem func_item = function_table->get_function(curr_func_name); 192 | this->out_table = temp_table; 193 | for (int count = 0; count < var_name_list.size(); count++) { 194 | out_table->put_symbol(SymbolItem(var_name_list[count], func_item.parameter_vector[count], 0, var_width_list[count])); 195 | } 196 | var_name_list.clear(); 197 | var_width_list.clear(); 198 | return; 199 | } 200 | 201 | void GrammerAnalyzer::action613(hebo::LexicalUnit* root) { 202 | three_address_instruction* temp_instruction = new three_address_instruction(); 203 | temp_instruction->index = this->final_instruction.size(); 204 | temp_instruction->op = "ENDF"; 205 | temp_instruction->arg1 = curr_func_name; 206 | temp_instruction->arg2 = "-"; 207 | temp_instruction->result = "-"; 208 | this->final_instruction.push_back(temp_instruction); 209 | out_table = out_table->father; 210 | return; 211 | } 212 | 213 | void GrammerAnalyzer::action614(hebo::LexicalUnit* root) { 214 | curr_func_name = root->father->morpheme; 215 | three_address_instruction* temp_instruction = new three_address_instruction(); 216 | temp_instruction->index = this->final_instruction.size(); 217 | temp_instruction->op = "FUNC"; 218 | temp_instruction->arg1 = curr_func_name; 219 | temp_instruction->arg2 = "-"; 220 | temp_instruction->result = "-"; 221 | this->final_instruction.push_back(temp_instruction); 222 | SymbolTable * temp_table = new SymbolTable(curr_func_name, this->out_table); 223 | FunctionItem func_item = function_table->get_function(curr_func_name); 224 | this->out_table = temp_table; 225 | for (int count = 0; count < var_name_list.size(); count++) { 226 | out_table->put_symbol(SymbolItem(var_name_list[count], func_item.parameter_vector[count], 0, var_width_list[count])); 227 | } 228 | var_name_list.clear(); 229 | var_width_list.clear(); 230 | return; 231 | } 232 | 233 | void GrammerAnalyzer::action615(hebo::LexicalUnit* root) { 234 | three_address_instruction* temp_instruction = new three_address_instruction(); 235 | temp_instruction->index = this->final_instruction.size(); 236 | temp_instruction->op = "ENDF"; 237 | temp_instruction->arg1 = curr_func_name; 238 | temp_instruction->arg2 = "-"; 239 | temp_instruction->result = "-"; 240 | this->final_instruction.push_back(temp_instruction); 241 | out_table = out_table->father; 242 | return; 243 | } 244 | 245 | void GrammerAnalyzer::action616(hebo::LexicalUnit* root) { 246 | root->father->child_node_list[2]->attribute.type = root->father->child_node_list[0]->attribute.type; 247 | return; 248 | } 249 | 250 | void GrammerAnalyzer::action617(hebo::LexicalUnit* root) { 251 | root->father->child_node_list[4]->morpheme = root->father->child_node_list[2]->morpheme; 252 | return; 253 | } 254 | -------------------------------------------------------------------------------- /compiler/GrammerAnalyzer.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hlh981029/c-compiler/b7a3afe0b050d92f7b946f64f5a28d8e5e49183c/compiler/GrammerAnalyzer.cpp -------------------------------------------------------------------------------- /compiler/GrammerAnalyzer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "intput_and_output.hpp" 3 | #include 4 | #include 5 | 6 | class GrammerAnalyzer { 7 | private: 8 | typedef struct production { 9 | std::vector production_formula; 10 | production() {} 11 | }production; 12 | 13 | std::vector output_sequence; 14 | int terminal_number; 15 | std::string** terminal_list; 16 | int non_terminal_number; 17 | std::string** non_terminal_list; 18 | int production_number; 19 | int production_action_number; 20 | std::vector>* transfer_list; 21 | production** production_list; 22 | int table_number; 23 | std::vector> action_table; 24 | std::vector> goto_table; 25 | std::vector parameter_list; 26 | std::vector var_width_list; 27 | std::vector var_name_list; 28 | std::string curr_func_name; 29 | 30 | public: 31 | typedef struct { 32 | int index = -1; 33 | std::string op; 34 | std::string arg1; 35 | std::string arg2; 36 | std::string result; 37 | }three_address_instruction; 38 | std::vector final_instruction; 39 | hbst::SymbolTable* out_table; 40 | hbst::StructTable* struct_table; 41 | hbst::FunctionTable* function_table; 42 | GrammerAnalyzer(std::vector); 43 | hebo::LexicalUnit* root; 44 | private: 45 | void initialization(); 46 | hebo::LexicalUnit* init_tree(); 47 | void output_tree(hebo::LexicalUnit*, int); 48 | bool compare(std::vector, std::vector); 49 | void execute_action(int, hebo::LexicalUnit*); 50 | void say_error(int, std::string, std::string); 51 | bool check_type(std::string, std::vector); 52 | void clean_param_list(); 53 | void optimize_final_instructions(); 54 | 55 | private: 56 | void action1(hebo::LexicalUnit*); 57 | void action2(hebo::LexicalUnit*); 58 | void action3(hebo::LexicalUnit*); 59 | void action4(hebo::LexicalUnit*); 60 | void action5(hebo::LexicalUnit*); 61 | void action6(hebo::LexicalUnit*); 62 | void action7(hebo::LexicalUnit*); 63 | void action8(hebo::LexicalUnit*); 64 | void action9(hebo::LexicalUnit*); 65 | void action10(hebo::LexicalUnit*); 66 | void action11(hebo::LexicalUnit*); 67 | void action12(hebo::LexicalUnit*); 68 | void action13(hebo::LexicalUnit*); 69 | void action14(hebo::LexicalUnit*); 70 | void action15(hebo::LexicalUnit*); 71 | void action16(hebo::LexicalUnit*); 72 | void action17(hebo::LexicalUnit*); 73 | void action18(hebo::LexicalUnit*); 74 | void action19(hebo::LexicalUnit*); 75 | void action20(hebo::LexicalUnit*); 76 | void action21(hebo::LexicalUnit*); 77 | void action22(hebo::LexicalUnit*); 78 | void action23(hebo::LexicalUnit*); 79 | void action24(hebo::LexicalUnit*); 80 | void action25(hebo::LexicalUnit*); 81 | void action26(hebo::LexicalUnit*); 82 | void action27(hebo::LexicalUnit*); 83 | 84 | 85 | void action101(hebo::LexicalUnit*); 86 | void action102(hebo::LexicalUnit*); 87 | void action103(hebo::LexicalUnit*); 88 | void action104(hebo::LexicalUnit*); 89 | void action105(hebo::LexicalUnit*); 90 | void action106(hebo::LexicalUnit*); 91 | void action107(hebo::LexicalUnit*); 92 | void action108(hebo::LexicalUnit*); 93 | void action109(hebo::LexicalUnit*); 94 | void action110(hebo::LexicalUnit*); 95 | void action111(hebo::LexicalUnit*); 96 | void action112(hebo::LexicalUnit*); 97 | void action113(hebo::LexicalUnit*); 98 | void action114(hebo::LexicalUnit*); 99 | void action115(hebo::LexicalUnit*); 100 | void action116(hebo::LexicalUnit*); 101 | 102 | 103 | void action201(hebo::LexicalUnit*); 104 | void action202(hebo::LexicalUnit*); 105 | void action203(hebo::LexicalUnit*); 106 | void action204(hebo::LexicalUnit*); 107 | 108 | void action211(hebo::LexicalUnit*); 109 | void action212(hebo::LexicalUnit*); 110 | void action213(hebo::LexicalUnit*); 111 | 112 | void action214(hebo::LexicalUnit*); 113 | void action215(hebo::LexicalUnit*); 114 | 115 | 116 | void action216(hebo::LexicalUnit*); 117 | void action217(hebo::LexicalUnit*); 118 | void action218(hebo::LexicalUnit*); 119 | 120 | void action219(hebo::LexicalUnit*); 121 | void action220(hebo::LexicalUnit*); 122 | void action221(hebo::LexicalUnit*); 123 | void action222(hebo::LexicalUnit*); 124 | 125 | void action223(hebo::LexicalUnit*); 126 | void action224(hebo::LexicalUnit*); 127 | 128 | void action225(hebo::LexicalUnit*); 129 | void action226(hebo::LexicalUnit*); 130 | void action227(hebo::LexicalUnit*); 131 | void action228(hebo::LexicalUnit*); 132 | void action229(hebo::LexicalUnit*); 133 | void action230(hebo::LexicalUnit*); 134 | void action231(hebo::LexicalUnit*); 135 | void action232(hebo::LexicalUnit*); 136 | void action233(hebo::LexicalUnit*); 137 | void action234(hebo::LexicalUnit*); 138 | void action235(hebo::LexicalUnit*); 139 | void action236(hebo::LexicalUnit*); 140 | void action237(hebo::LexicalUnit*); 141 | void action238(hebo::LexicalUnit*); 142 | void action239(hebo::LexicalUnit*); 143 | void action240(hebo::LexicalUnit*); 144 | void action241(hebo::LexicalUnit*); 145 | void action242(hebo::LexicalUnit*); 146 | 147 | void action301(hebo::LexicalUnit*); 148 | void action302(hebo::LexicalUnit*); 149 | void action303(hebo::LexicalUnit*); 150 | void action304(hebo::LexicalUnit*); 151 | void action305(hebo::LexicalUnit*); 152 | 153 | 154 | void action401(hebo::LexicalUnit*); 155 | void action402(hebo::LexicalUnit*); 156 | void action403(hebo::LexicalUnit*); 157 | void action404(hebo::LexicalUnit*); 158 | 159 | void action405(hebo::LexicalUnit*); 160 | void action406(hebo::LexicalUnit*); 161 | void action407(hebo::LexicalUnit*); 162 | 163 | void action408(hebo::LexicalUnit*); 164 | void action409(hebo::LexicalUnit*); 165 | 166 | void action410(hebo::LexicalUnit*); 167 | void action411(hebo::LexicalUnit*); 168 | void action412(hebo::LexicalUnit*); 169 | void action413(hebo::LexicalUnit*); 170 | void action414(hebo::LexicalUnit*); 171 | void action415(hebo::LexicalUnit*); 172 | void action416(hebo::LexicalUnit*); 173 | void action417(hebo::LexicalUnit*); 174 | void action418(hebo::LexicalUnit*); 175 | void action419(hebo::LexicalUnit*); 176 | void action420(hebo::LexicalUnit*); 177 | void action421(hebo::LexicalUnit*); 178 | void action422(hebo::LexicalUnit*); 179 | void action423(hebo::LexicalUnit*); 180 | void action424(hebo::LexicalUnit*); 181 | 182 | void action425(hebo::LexicalUnit*); 183 | void action426(hebo::LexicalUnit*); 184 | void action427(hebo::LexicalUnit*); 185 | 186 | 187 | void action501(hebo::LexicalUnit*); 188 | void action502(hebo::LexicalUnit*); 189 | void action503(hebo::LexicalUnit*); 190 | void action504(hebo::LexicalUnit*); 191 | 192 | void action505(hebo::LexicalUnit*); 193 | void action506(hebo::LexicalUnit*); 194 | void action507(hebo::LexicalUnit*); 195 | void action508(hebo::LexicalUnit*); 196 | 197 | void action509(hebo::LexicalUnit*); 198 | void action510(hebo::LexicalUnit*); 199 | void action511(hebo::LexicalUnit*); 200 | void action512(hebo::LexicalUnit*); 201 | void action513(hebo::LexicalUnit*); 202 | 203 | void action514(hebo::LexicalUnit*); 204 | void action515(hebo::LexicalUnit*); 205 | void action516(hebo::LexicalUnit*); 206 | void action517(hebo::LexicalUnit*); 207 | void action518(hebo::LexicalUnit*); 208 | void action519(hebo::LexicalUnit*); 209 | void action520(hebo::LexicalUnit*); 210 | void action521(hebo::LexicalUnit*); 211 | void action522(hebo::LexicalUnit*); 212 | void action523(hebo::LexicalUnit*); 213 | void action524(hebo::LexicalUnit*); 214 | void action525(hebo::LexicalUnit*); 215 | 216 | void action601(hebo::LexicalUnit*); 217 | void action602(hebo::LexicalUnit*); 218 | void action603(hebo::LexicalUnit*); 219 | void action604(hebo::LexicalUnit*); 220 | void action605(hebo::LexicalUnit*); 221 | void action606(hebo::LexicalUnit*); 222 | void action607(hebo::LexicalUnit*); 223 | void action608(hebo::LexicalUnit*); 224 | void action609(hebo::LexicalUnit*); 225 | void action610(hebo::LexicalUnit*); 226 | void action611(hebo::LexicalUnit*); 227 | void action612(hebo::LexicalUnit*); 228 | void action613(hebo::LexicalUnit*); 229 | void action614(hebo::LexicalUnit*); 230 | void action615(hebo::LexicalUnit*); 231 | void action616(hebo::LexicalUnit*); 232 | void action617(hebo::LexicalUnit*); 233 | void action618(hebo::LexicalUnit*); 234 | 235 | }; -------------------------------------------------------------------------------- /compiler/LR.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hlh981029/c-compiler/b7a3afe0b050d92f7b946f64f5a28d8e5e49183c/compiler/LR.cpp -------------------------------------------------------------------------------- /compiler/LR.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include"ContextFreeGrammar.hpp" 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | namespace lr 10 | { 11 | using std::unordered_set; 12 | using std::cin; 13 | using std::endl; 14 | using std::cout; 15 | using std::vector; 16 | using std::map; 17 | using std::string; 18 | using std::unordered_map; 19 | using std::queue; 20 | class LALR1Item 21 | { 22 | public: 23 | struct Ter_pointer_hash 24 | { 25 | size_t operator()(cfg::Terminal* input) const { 26 | std::hash hash_fn; 27 | return hash_fn(input->value); 28 | } 29 | }; 30 | struct Ter_pointer_hash_compare 31 | { 32 | bool operator()(cfg::Terminal* input1, cfg::Terminal* input2) const { 33 | return input1->value == input2->value; 34 | } 35 | }; 36 | 37 | 38 | cfg::Production* production; 39 | int position; 40 | std::unordered_set lookaheads; 41 | bool is_kernel; 42 | 43 | int order; 44 | 45 | LALR1Item(); 46 | LALR1Item(cfg::Production* production_, int position, cfg::Terminal* sentence_ending, int order_); 47 | 48 | }; 49 | 50 | 51 | class LALR 52 | { 53 | public: 54 | 55 | struct item_pointer_hash 56 | { 57 | size_t operator()(LALR1Item* input) const { 58 | std::hash hash_fn; 59 | string sum = input->production->left->value; 60 | for each(auto str in input->production->right) 61 | { 62 | sum += str->value; 63 | } 64 | return hash_fn(sum) + input->position; 65 | } 66 | }; 67 | struct item_pointer_hash_compare 68 | { 69 | bool operator()(LALR1Item* input1, LALR1Item* input2) const { 70 | return 71 | input1->production->left == input2->production->left && 72 | input1->production->right == input2->production->right && 73 | input1->position == input2->position; 74 | } 75 | }; 76 | 77 | struct unordered_set_lalr_item_hash 78 | { 79 | size_t operator()(unordered_set input) const 80 | { 81 | item_pointer_hash hash_func; 82 | size_t result = 0; 83 | for each (auto item in input) 84 | { 85 | result += hash_func(item); 86 | } 87 | return result; 88 | } 89 | }; 90 | 91 | int production_number; 92 | cfg::Terminal* non_exist_terminal; 93 | 94 | unordered_set terminal_set; 95 | unordered_set nonterminal_set; 96 | unordered_set lr0_item_set; 97 | LALR1Item* argumented_grammar_start; 98 | cfg::Nonterminal* start_symbol; 99 | 100 | vector> kernel_status_vector; 101 | vector> kernel_goto_vector; 102 | 103 | 104 | cfg::Terminal* sentence_ending; 105 | 106 | LALR(const cfg::ContextFreeGrammar& context_free_grammar_); 107 | void get_kernel(); 108 | 109 | void LR0_closure(unordered_set& closure_set); 110 | void LALR_closuer(unordered_set& closure_set); 111 | 112 | 113 | LALR(); 114 | ~LALR(); 115 | 116 | vector> spontaneous_lookaheads_vector; 117 | vector> spreading_lookaheads_vector; 118 | 119 | void get_spontaneous_lookaheads_and_spreading_lookaheads(); 120 | void set_spontaneous_lookaheads(); 121 | void spread_lookaheads(); 122 | 123 | vector> status_vector; 124 | 125 | void get_full_status_vector(); 126 | 127 | vector terminal_vector; 128 | vector nonterminal_vector; 129 | 130 | map terminal_to_int_map; 131 | map nonterminal_to_int_map; 132 | 133 | vector> action_vector; 134 | vector> go_vector; 135 | 136 | void serialize_symbol(); 137 | void make_action_and_go(); 138 | void output(); 139 | }; 140 | 141 | std::ostream& operator<<(std::ostream& out, LALR1Item item); 142 | 143 | } 144 | -------------------------------------------------------------------------------- /compiler/LR1.cpp: -------------------------------------------------------------------------------- 1 | #include "LR1.h" 2 | #include 3 | #include 4 | #include 5 | namespace lr1{ 6 | using std::map; 7 | using std::make_pair; 8 | using std::stringstream; 9 | LR1Item::LR1Item(Production* production, int pnum, int pos) 10 | { 11 | this->production = production; 12 | this->position = pos; 13 | this->productionNum = pnum; 14 | for (int n = 0; n < this->production->right.size(); n++) { 15 | if (n == pos) { 16 | this->expect = this->production->right[n]; 17 | break; 18 | } 19 | else if (n == production->right.size() - 1) { 20 | this->expect = nullptr; 21 | break; 22 | } 23 | } 24 | } 25 | LR1Item::~LR1Item() 26 | { 27 | } 28 | bool LR1Item::addForward(Terminal* ter) 29 | { 30 | bool have_it = false; 31 | for (int i = 0; i < this->forward.size(); i++) { 32 | if (this->forward[i]->value == ter->value) { 33 | have_it = true; 34 | return false; 35 | } 36 | } 37 | if (!have_it) { 38 | this->forward.push_back(ter); 39 | return true; 40 | } 41 | //xiajibajiade 42 | else { 43 | std::cout << "addForward exception" << endl; 44 | return false; 45 | } 46 | } 47 | bool LR1Item::addForwards(vector ters) 48 | { 49 | bool added = false; 50 | for (int i = 0; i < ters.size(); i++) { 51 | bool have_it = false; 52 | for (int j = 0; j < this->forward.size(); j++) { 53 | if (ters[i]->value == this->forward[j]->value) { 54 | have_it = true; 55 | break; 56 | } 57 | } 58 | if (!have_it) { 59 | this->addForward(ters[i]); 60 | added = true; 61 | } 62 | } 63 | return added; 64 | } 65 | bool LR1Item::operator==(LR1Item & a) 66 | { 67 | if (this->production == a.production && this->position == a.position && this->forward.size() == a.forward.size()) 68 | { 69 | for (int i = 0; i < a.forward.size(); i++) 70 | { 71 | bool have_it = false; 72 | for (int j = 0; j < this->forward.size(); j++) 73 | { 74 | if (a.forward[i]->value == this->forward[j]->value) 75 | { 76 | have_it = true; 77 | break; 78 | } 79 | } 80 | if (!have_it) 81 | { 82 | return false; 83 | } 84 | } 85 | return true; 86 | } 87 | else 88 | { 89 | return false; 90 | } 91 | } 92 | 93 | 94 | LR1ItemSet::LR1ItemSet(LR1Item* item) 95 | { 96 | this->itemset.push_back(item); 97 | } 98 | LR1ItemSet::LR1ItemSet() 99 | { 100 | } 101 | LR1ItemSet::~LR1ItemSet() 102 | { 103 | } 104 | std::pair LR1ItemSet::addItem(LR1Item * Item) 105 | { 106 | bool have_it = false; 107 | for (int i = 0; i < this->itemset.size(); i++) { 108 | if (this->itemset[i]->production == Item->production && this->itemset[i]->position == Item->position) { 109 | have_it = true; 110 | bool a = this->itemset[i]->addForwards(Item->forward); 111 | // first��ʶ״̬���Ƿ����ı䣬second��ʶ�Ƿ�Ӧ��delete Item 112 | std::pair p(a, true); 113 | return p; 114 | } 115 | } 116 | if (!have_it) { 117 | this->itemset.push_back(Item); 118 | std::pair p(true, false); 119 | return p; 120 | } 121 | // xiajibajiade 122 | else { 123 | std::cout << "addItem exception" << endl; 124 | std::pair p(false, false); 125 | return p; 126 | } 127 | // 128 | } 129 | bool LR1ItemSet::addItem4NewSet(LR1Item* Item) { 130 | this->itemset.push_back(Item); 131 | return true; 132 | } 133 | bool LR1ItemSet::operator==(LR1ItemSet& a) 134 | { 135 | if (this->itemset.size() == a.itemset.size()) 136 | { 137 | for (int i = 0; i < this->itemset.size(); i++) 138 | { 139 | bool have_it = false; 140 | for (int j = 0; j < a.itemset.size(); j++) 141 | { 142 | if (*this->itemset[i] == *a.itemset[j]) 143 | { 144 | have_it = true; 145 | break; 146 | } 147 | } 148 | if (!have_it) 149 | { 150 | return false; 151 | } 152 | } 153 | return true; 154 | } 155 | else 156 | { 157 | return false; 158 | } 159 | } 160 | 161 | 162 | void LR1ItemSets::addLine() 163 | { 164 | this->GO.push_back(this->Goline); 165 | } 166 | bool LR1ItemSets::Go(LR1ItemSet* s, Symbol* x) 167 | { 168 | LR1ItemSet* newSet = new LR1ItemSet(); 169 | for (int i = 0; i < s->itemset.size(); i++) { 170 | if (s->itemset[i]->expect && s->itemset[i]->expect == x) { 171 | if (this->newNext(s->itemset[i])) { 172 | newSet->addItem4NewSet(s->itemset[i]->next); 173 | } 174 | else { 175 | std::cout << "There is a expect symbol but no next"; 176 | } 177 | } 178 | } 179 | if (newSet->itemset.size() != 0) { 180 | this->closure(newSet); 181 | LR1ItemSet* temp = this->addItemSet(newSet); 182 | bool flag; 183 | if (temp != newSet) { 184 | delete newSet; 185 | flag = false; 186 | } 187 | else { 188 | this->addLine(); 189 | // std::cout << *newSet << "added a line!!" << endl << endl; 190 | flag = true; 191 | } 192 | int from = 0, to = 0, via = 0; 193 | for (int i = 0; i < this->itemSets.size(); i++) { 194 | if (s == this->itemSets[i]) { 195 | from = i; 196 | } 197 | if (temp == this->itemSets[i]) { 198 | to = i; 199 | } 200 | } 201 | for (int j = 0; j < this->symbols.size(); j++) { 202 | if (x == this->symbols[j]) { 203 | via = j; 204 | } 205 | } 206 | this->GO[from][via] = to; 207 | return flag; 208 | } 209 | else { 210 | delete newSet; 211 | return false; 212 | } 213 | } 214 | LR1ItemSet* LR1ItemSets::addItemSet(LR1ItemSet* itemSet) 215 | { 216 | bool have_it = false; 217 | for (int i = 0; i < this->itemSets.size(); i++) { 218 | if (*itemSet == *this->itemSets[i]) { 219 | have_it = true; 220 | return this->itemSets[i]; 221 | } 222 | } 223 | if (!have_it) { 224 | this->itemSets.push_back(itemSet); 225 | return itemSet; 226 | } 227 | // xiajibajiade 228 | else { 229 | std::cout << "addItemSet exception" << endl; 230 | return itemSet; 231 | } 232 | } 233 | void LR1ItemSets::closure(LR1ItemSet* itemSet) 234 | { 235 | bool flag = true; 236 | while (flag) { 237 | flag = false; 238 | for (int i = 0; i < itemSet->itemset.size(); i++) { 239 | if (itemSet->itemset[i]->expect && itemSet->itemset[i]->expect->get_id() == Identify::Nonterminal) { 240 | for (int j = 0; j < this->productions.size(); j++) { 241 | if (this->productions[j]->left == itemSet->itemset[i]->expect) { 242 | LR1Item* newItem = new LR1Item(this->productions[j], j); 243 | int size = itemSet->itemset[i]->production->right.size(); 244 | if (itemSet->itemset[i]->position == size - 1) { 245 | newItem->addForwards(itemSet->itemset[i]->forward); 246 | } 247 | else { 248 | int afterPos = itemSet->itemset[i]->position + 1; 249 | Symbol* after = itemSet->itemset[i]->production->right[afterPos]; 250 | for each (Terminal* f in after->first_set) { 251 | newItem->addForward(f); 252 | } 253 | if (after->start_as_epsilon) { 254 | newItem->addForwards(itemSet->itemset[i]->forward); 255 | } 256 | } 257 | std::pair p = itemSet->addItem(newItem); 258 | if (p.first) { 259 | flag = true; 260 | } 261 | if (p.second) { 262 | delete newItem; 263 | } 264 | } 265 | } 266 | } 267 | } 268 | } 269 | } 270 | LR1Item* LR1ItemSets::newNext(LR1Item* item) 271 | { 272 | int sum = item->production->right.size(); 273 | if (item->position < sum) { 274 | LR1Item* next = new LR1Item(item->production, item->productionNum, item->position + 1); 275 | next->forward = item->forward; 276 | item->next = next; 277 | return next; 278 | } 279 | else { 280 | item->next = nullptr; 281 | return nullptr; 282 | } 283 | } 284 | LR1ItemSets::LR1ItemSets(ContextFreeGrammar grammar) 285 | { 286 | int nSym = 0; 287 | for each (Terminal* x in grammar.terminal_set) { 288 | this->terminals.push_back(x); 289 | this->symbols.push_back(x); 290 | nSym++; 291 | } 292 | for each (Nonterminal* x in grammar.nonterminal_set) { 293 | this->nonterminals.push_back(x); 294 | this->symbols.push_back(x); 295 | nSym++; 296 | } 297 | this->Goline = vector(nSym); 298 | for (int i = 0; i < nSym; i++) { 299 | this->Goline[i] = -1; 300 | } 301 | for each (Production* x in grammar.production_set) { 302 | this->productions.push_back(x); 303 | } 304 | for (int i = 0; i < this->productions.size(); i++) { 305 | if (this->productions[i]->left == grammar.start_symbol) { 306 | LR1Item* newItem = new LR1Item(this->productions[i], i); 307 | newItem->addForward(grammar.end_symbol); 308 | LR1ItemSet* firstItemSet = new LR1ItemSet(newItem); 309 | this->itemSets.push_back(firstItemSet); 310 | this->addLine(); 311 | this->closure(firstItemSet); 312 | break; 313 | } 314 | } 315 | } 316 | int8_t LR1ItemSets::can_merge(int status_1, int status_2) 317 | { 318 | /*if (itemSets[status_1]->itemset.size() != itemSets[status_2]->itemset.size()) 319 | { 320 | return 0; 321 | } 322 | map status_1_equivalence; 323 | map status_2_equivalence; 324 | 325 | int size = itemSets[status_1]->itemset.size(); 326 | for (int i = 0; i < size; i++) 327 | { 328 | status_1_equivalence.insert( 329 | make_pair( 330 | itemSets[status_1]->itemset[i]->productionNum, 331 | itemSets[status_1]->itemset[i]->position)); 332 | status_2_equivalence.insert( 333 | make_pair( 334 | itemSets[status_2]->itemset[i]->productionNum, 335 | itemSets[status_2]->itemset[i]->position)); 336 | } 337 | return status_1_equivalence == status_2_equivalence;*/ 338 | 339 | if (itemSets[status_1]->itemset.size() != itemSets[status_2]->itemset.size()) 340 | { 341 | return 0; 342 | } 343 | 344 | assert(status_2 < status_1); 345 | assert(itemSets[status_1]->itemset.size() == itemSets[status_2]->itemset.size()); 346 | 347 | map correspondence; 348 | int size = itemSets[status_1]->itemset.size(); 349 | for (int i = 0; i < size; i++) 350 | { 351 | for (int j = 0; j < size; j++) 352 | { 353 | if ( 354 | itemSets[status_1]->itemset[i]->productionNum == 355 | itemSets[status_2]->itemset[j]->productionNum && 356 | itemSets[status_1]->itemset[i]->position == 357 | itemSets[status_2]->itemset[j]->position) 358 | { 359 | correspondence.insert(make_pair(i, j)); 360 | } 361 | } 362 | } 363 | return correspondence.size() == size; 364 | } 365 | void LR1ItemSets::merge_all() 366 | { 367 | for (int i = 0; i < itemSets.size(); i++) 368 | { 369 | for (int j = 0; j < i; j++) 370 | { 371 | if (can_merge(i, j)) 372 | { 373 | merge_go_table(i, j); 374 | merge_itemSets(i, j); 375 | i--; 376 | break; 377 | } 378 | assert(GO.size() == itemSets.size()); 379 | 380 | } 381 | } 382 | } 383 | void LR1ItemSets::merge_go_table(int status_1, int status_2) 384 | { 385 | assert(status_2 < status_1); 386 | for (int i = 0; i < GO.size(); i++) 387 | { 388 | for (int j = 0; j < GO[i].size(); j++) 389 | { 390 | if (GO[i][j] == status_1) 391 | { 392 | GO[i][j] = status_2; 393 | } 394 | else if (GO[i][j] > status_1) 395 | { 396 | GO[i][j] -= 1; 397 | } 398 | } 399 | } 400 | GO.erase(GO.begin() + status_1); 401 | } 402 | void LR1ItemSets::merge_itemSets(int status_1, int status_2) 403 | { 404 | assert(status_2 < status_1); 405 | assert(itemSets[status_1]->itemset.size() == itemSets[status_2]->itemset.size()); 406 | map correspondence; 407 | int size = itemSets[status_1]->itemset.size(); 408 | for (int i = 0; i < size; i++) 409 | { 410 | for (int j = 0; j < size; j++) 411 | { 412 | if ( 413 | itemSets[status_1]->itemset[i]->productionNum == 414 | itemSets[status_2]->itemset[j]->productionNum && 415 | itemSets[status_1]->itemset[i]->position == 416 | itemSets[status_2]->itemset[j]->position) 417 | { 418 | correspondence.insert(make_pair(i, j)); 419 | } 420 | } 421 | } 422 | assert(correspondence.size() == size); 423 | int count = 0; 424 | for each(auto it in correspondence) 425 | { 426 | for each(auto terminal in itemSets[status_1]->itemset[it.first]->forward) 427 | { 428 | bool been_in = false; 429 | for (int i = 0; i < itemSets[status_2]->itemset[it.second]->forward.size(); i++) 430 | { 431 | if (itemSets[status_2]->itemset[it.second]->forward[i] == terminal) 432 | { 433 | been_in = true; 434 | break; 435 | } 436 | } 437 | if(!been_in) 438 | { 439 | itemSets[status_2]->itemset[it.second]->forward.push_back(terminal); 440 | } 441 | } 442 | count++; 443 | } 444 | assert(count == size); 445 | itemSets.erase(itemSets.begin() + status_1); 446 | } 447 | void LR1ItemSets::set_action_and_goto() 448 | { 449 | terminals.clear(); 450 | nonterminals.clear(); 451 | for (int i = 0; i < symbols.size(); i++) 452 | { 453 | if (symbols[i]->get_id() == cfg::Identify::Terminal) 454 | { 455 | terminals.push_back(dynamic_cast(symbols[i])); 456 | } 457 | else 458 | { 459 | break; 460 | } 461 | } 462 | for (int i = terminals.size(); i < symbols.size(); i++) 463 | { 464 | nonterminals.push_back(dynamic_cast(symbols[i])); 465 | } 466 | 467 | 468 | 469 | action_table = vector>(itemSets.size(), vector(terminals.size(), "e")); 470 | goto_table = vector>(itemSets.size(), vector(nonterminals.size(), -1)); 471 | 472 | stringstream ssss; 473 | 474 | for (int i = 0; i < itemSets.size(); i++) 475 | { 476 | for (int j = 0; j < terminals.size(); j++) 477 | { 478 | if (GO[i][j] == -1) 479 | { 480 | continue; 481 | } 482 | ssss << GO[i][j]; 483 | action_table[i][j] = "s" + ssss.str(); 484 | ssss.str(""); 485 | } 486 | } 487 | for (int i = 0; i < itemSets.size(); i++) 488 | { 489 | for (int j = 0; j < nonterminals.size(); j++) 490 | { 491 | goto_table[i][j] = GO[i][j + terminals.size()]; 492 | } 493 | } 494 | map terminal_to_int; 495 | for (int i = 0; i < terminals.size(); i++) 496 | { 497 | terminal_to_int.insert(make_pair(terminals[i], i)); 498 | } 499 | 500 | for (int i = 0; i < itemSets.size(); i++) 501 | { 502 | for (int j = 0; j < itemSets[i]->itemset.size(); j++) 503 | { 504 | if (itemSets[i]->itemset[j]->production->right.size() == itemSets[i]->itemset[j]->position) 505 | { 506 | for (int k = 0; k < itemSets[i]->itemset[j]->forward.size(); k++) 507 | { 508 | if (action_table[i][terminal_to_int[itemSets[i]->itemset[j]->forward[k]]] != "e") 509 | { 510 | cout << action_table[i][terminal_to_int[itemSets[i]->itemset[j]->forward[k]]] << endl; 511 | cout << "chong tu" << endl; 512 | ssss.str(""); 513 | ssss << itemSets[i]->itemset[j]->productionNum; 514 | action_table[i][terminal_to_int[itemSets[i]->itemset[j]->forward[k]]] += "r" + ssss.str(); 515 | cout << "r" + ssss.str(); 516 | } 517 | else 518 | { 519 | ssss.str(""); 520 | ssss << itemSets[i]->itemset[j]->productionNum; 521 | action_table[i][terminal_to_int[itemSets[i]->itemset[j]->forward[k]]] = "r" + ssss.str(); 522 | } 523 | if (itemSets[i]->itemset[j]->production->left->value == "argumented_translation_unit" && itemSets[i]->itemset[j]->position == 1) 524 | //if (itemSets[i]->itemset[j]->production->left->value == "sp" && itemSets[i]->itemset[j]->position == 1) 525 | { 526 | action_table[i][terminal_to_int[itemSets[i]->itemset[j]->forward[k]]] = "acc"; 527 | } 528 | } 529 | } 530 | } 531 | } 532 | 533 | } 534 | void LR1ItemSets::output() 535 | { 536 | ofstream lalr("lalr.txt"); 537 | lalr << terminals.size() << endl; 538 | for (int i = 0; i < terminals.size(); i++) 539 | { 540 | lalr << *terminals[i] << endl; 541 | } 542 | lalr << nonterminals.size() << endl; 543 | for (int i = 0; i < nonterminals.size(); i++) 544 | { 545 | lalr << *nonterminals[i] << endl; 546 | } 547 | lalr << productions.size() << endl; 548 | for (int i = 0; i < productions.size(); i++) 549 | { 550 | lalr << *(productions[i]->left) << ' '; 551 | for (int j = 0; j < productions[i]->right.size(); j++) 552 | { 553 | lalr << *(productions[i]->right[j]) << ' '; 554 | } 555 | lalr << endl; 556 | } 557 | lalr << action_table.size() << endl; 558 | for (int i = 0; i < action_table.size(); i++) 559 | { 560 | assert(terminals.size() == action_table[i].size()); 561 | for (int j = 0; j < terminals.size(); j++) 562 | { 563 | lalr << action_table[i][j] << ' '; 564 | } 565 | lalr << endl; 566 | } 567 | for (int i = 0; i < goto_table.size(); i++) 568 | { 569 | assert(nonterminals.size() == goto_table[i].size()); 570 | for (int j = 0; j < nonterminals.size(); j++) 571 | { 572 | lalr << goto_table[i][j] << ' '; 573 | } 574 | lalr << endl; 575 | } 576 | } 577 | LR1ItemSets::~LR1ItemSets() 578 | { 579 | 580 | } 581 | void LR1ItemSets::getSets() 582 | { 583 | for (int i = 0; i < this->itemSets.size(); i++) { 584 | for (int j = 0; j < this->symbols.size(); j++) { 585 | if (this->symbols[j]->value!="$" && this->Go(this->itemSets[i], this->symbols[j])) 586 | { 587 | 588 | } 589 | } 590 | } 591 | } 592 | 593 | ostream & operator<<(ostream & out, LR1Item iter) 594 | { 595 | out << iter.production->left->value << "->"; 596 | int i = 0; 597 | for each (auto sybom_pointer in iter.production->right) 598 | { 599 | if (i == iter.position) { 600 | out << '@' << sybom_pointer->value << ' '; 601 | } 602 | else if (i == iter.position - 1) { 603 | out << sybom_pointer->value << ' ' << '@'; 604 | } 605 | else { 606 | out << sybom_pointer->value << ' '; 607 | } 608 | i++; 609 | } 610 | out << ", "; 611 | for each (auto sybom_pointer in iter.forward) { 612 | out << sybom_pointer->value << ' '; 613 | } 614 | return out; 615 | } 616 | 617 | ostream & operator<<(ostream & out, LR1ItemSet iterSet) 618 | { 619 | out << "****size: " << iterSet.itemset.size() << " ****" << endl; 620 | for each (auto item in iterSet.itemset) 621 | { 622 | out << *item << endl; 623 | } 624 | out << "****************"; 625 | return out; 626 | } 627 | 628 | } 629 | 630 | 631 | // �ϲ���Ŀ����ʱ�� ��ǰ����ȥ�� 632 | // go��ĺϲ� -------------------------------------------------------------------------------- /compiler/LR1.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include"ContextFreeGrammar.hpp" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace lr1 11 | { 12 | using namespace cfg; 13 | using std::cin; 14 | using std::cout; 15 | using std::endl; 16 | 17 | using std::string; 18 | using std::vector; 19 | using std::unordered_set; 20 | 21 | using std::ostream; 22 | using std::istream; 23 | 24 | using std::fstream; 25 | using std::ofstream; 26 | using std::ifstream; 27 | 28 | class LR1Item { 29 | public: 30 | Production* production; 31 | int position; 32 | vector forward; 33 | int productionNum; 34 | Symbol* expect; 35 | LR1Item* next; 36 | 37 | 38 | LR1Item(Production* production, int pnum, int pos = 0); 39 | ~LR1Item(); 40 | bool addForward(Terminal* ter); 41 | bool addForwards(vector ters); 42 | bool operator==(LR1Item &a); 43 | friend ostream& operator<<(ostream& out, LR1Item iter); 44 | }; 45 | 46 | class LR1ItemSet { 47 | public: 48 | vector itemset; 49 | 50 | LR1ItemSet(LR1Item* item); 51 | LR1ItemSet(); 52 | ~LR1ItemSet(); 53 | std::pair addItem(LR1Item* Item); 54 | bool addItem4NewSet(LR1Item* Item); 55 | bool operator==(LR1ItemSet& a); 56 | friend ostream& operator<<(ostream& out, LR1ItemSet iterSet); 57 | }; 58 | 59 | class LR1ItemSets { 60 | private: 61 | // ContextFreeGrammar grammar; 62 | // vector allItems; 63 | vector Goline; 64 | 65 | void addLine(); 66 | bool Go(LR1ItemSet* s, Symbol* x); 67 | LR1ItemSet* addItemSet(LR1ItemSet* itemSet); 68 | void closure(LR1ItemSet* itemSet); 69 | LR1Item* newNext(LR1Item* item); 70 | public: 71 | vector itemSets; 72 | vector symbols; 73 | vector terminals; 74 | vector nonterminals; 75 | vector productions; 76 | vector> GO; 77 | 78 | vector> action_table; 79 | vector> goto_table; 80 | 81 | LR1ItemSets(ContextFreeGrammar grammar); 82 | 83 | int8_t can_merge(int status_1, int status_2); 84 | void merge_all(); 85 | void merge_go_table(int status_1, int status_2); 86 | void merge_itemSets(int status_1, int status_2); 87 | 88 | void set_action_and_goto(); 89 | void output(); 90 | ~LR1ItemSets(); 91 | void getSets(); 92 | }; 93 | } -------------------------------------------------------------------------------- /compiler/Min_DFA.cpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | 11 | class Min_DFA { 12 | public: 13 | vector> vec; 14 | int dfa_s; 15 | int n_dfa_states; 16 | int n_chars; 17 | int** matrix; 18 | 19 | set start_set; 20 | set final_set; 21 | 22 | vector>ans; 23 | mapmap_ans; 24 | int start_state_ans; 25 | 26 | Min_DFA(map dfa_end, int** dfa_map, int dfa_s, int n_dfa_states, int n_chars) { 27 | this->matrix = dfa_map; 28 | this->dfa_s = dfa_s; 29 | this->n_dfa_states = n_dfa_states; 30 | this->n_chars = n_chars; 31 | size_t final_state_num = dfa_end.size(); 32 | set* final_set_list = new set[final_state_num]; 33 | int final_count = 0; 34 | for (map::iterator it = dfa_end.begin(); it != dfa_end.end(); it++) { 35 | final_set.insert((*it).first); 36 | bool flag = false; 37 | for (int t = 0; t < final_count; t++) { 38 | if (dfa_end.find(*(final_set_list[t].begin()))->second == it->second) { 39 | flag = true; 40 | final_set_list[t].insert(it->first); 41 | break; 42 | } 43 | } 44 | if (flag == false) { 45 | final_set_list[final_count].insert(it->first); 46 | final_count++; 47 | } 48 | } 49 | for (int i = 0; i < final_count; i++) { 50 | vec.push_back(final_set_list[i]); 51 | } 52 | for (int i = 1; i < n_dfa_states; i++) { 53 | if (final_set.find(i) == final_set.end()) { 54 | start_set.insert(i); 55 | } 56 | } 57 | vec.push_back(start_set); 58 | size_t count_flag = size(vec); 59 | while (count_flag != 0) { 60 | vector>::iterator it = vec.begin(); 61 | set temp = *it; 62 | if (size(temp) == 1) { 63 | vec.erase(vec.begin()); 64 | vec.push_back(temp); 65 | count_flag--; 66 | continue; 67 | } 68 | else { 69 | if (break_up(temp)) { 70 | count_flag = size(vec) - 1; 71 | } 72 | else { 73 | count_flag--; 74 | } 75 | } 76 | vec.erase(vec.begin()); 77 | } 78 | map final_select; 79 | int* remain_select = new int[vec.size() + 1]; 80 | final_select.insert(pair(0, 0)); 81 | int i = 1; 82 | for (vector>::iterator it = vec.begin(); it != vec.end(); it++, i++) { 83 | final_select.insert(pair(*((*it).begin()), i)); 84 | remain_select[i] = *((*it).begin()); 85 | } 86 | vector> ans; 87 | vectorvec0; 88 | for (int i = 0; i < this->n_chars; i++) { 89 | vec0.push_back(0); 90 | } 91 | ans.push_back(vec0); 92 | for (unsigned int i = 1; i <= vec.size(); i++) { 93 | int line_number = remain_select[i]; 94 | vector vec_temp; 95 | for (int j = 0; j < this->n_chars; j++) { 96 | int alter = get_begin(matrix[j][line_number]); 97 | vec_temp.push_back((final_select.find(alter))->second); 98 | } 99 | ans.push_back(vec_temp); 100 | } 101 | start_state_ans = final_select.find(get_begin(this->dfa_s))->second; 102 | bool* has_appended = new bool[vec.size() + 1]; 103 | for (unsigned int i = 0; i < vec.size() + 1; i++) { 104 | has_appended[i] = false; 105 | } 106 | for (map::iterator it = dfa_end.begin(); it != dfa_end.end(); it++) { 107 | int temp = it->first; 108 | int dest = final_select.find(get_begin(temp))->second; 109 | if (has_appended[dest] == false) { 110 | this->map_ans.insert(pair(dest, it->second)); 111 | has_appended[dest] = true; 112 | } 113 | } 114 | ofstream outfile("ans.txt"); 115 | outfile << "n_dfa_states: " << vec.size() + 1 << endl; 116 | outfile << "n_chars: " << this->n_chars << endl; 117 | outfile << "start_state_ans: " << this->start_state_ans << endl; 118 | outfile << "matrix:" << endl; 119 | for (vector>::iterator it1 = ans.begin(); it1 != ans.end(); it1++) { 120 | vector temp_vec = *it1; 121 | for (vector::iterator it2 = temp_vec.begin(); it2 != temp_vec.end(); it2++) { 122 | outfile << *it2 << ' '; 123 | } 124 | outfile << endl; 125 | } 126 | outfile << "map: " << endl; 127 | for (map::iterator it = map_ans.begin(); it != map_ans.end(); it++) { 128 | outfile << (*it).first << " " << (*it).second << endl; 129 | } 130 | } 131 | 132 | int get_begin(int destination) { 133 | for (vector>::iterator it = vec.begin(); it != vec.end(); it++) { 134 | if ((*it).find(destination) != (*it).end()) { 135 | return *((*it).begin()); 136 | } 137 | } 138 | return 0; 139 | } 140 | 141 | int get_position(int destination) { 142 | int i = 1; 143 | for (vector>::iterator it = vec.begin(); it != vec.end(); it++, i++) { 144 | if ((*it).find(destination) != (*it).end()) { 145 | return i; 146 | } 147 | } 148 | return 0; 149 | } 150 | 151 | bool break_up(set origin_set) { 152 | size_t large = vec.size() + 1; 153 | set* set_pointer = new set[large]; 154 | for (int i = 0; i < this->n_chars; i++) { 155 | for (set::iterator it = origin_set.begin(); it != origin_set.end(); it++) { 156 | int temp = matrix[i][*it]; 157 | int result = get_position(temp); 158 | set_pointer[result].insert(*it); 159 | } 160 | bool flag = false; 161 | for (int i = 0; i < large; i++) { 162 | if (size(set_pointer[i]) == size(origin_set)) { 163 | set_pointer[i].clear(); 164 | flag = true; 165 | break; 166 | } 167 | } 168 | if (flag == false) { 169 | for (int i = 0; i < large; i++) { 170 | if (set_pointer[i].size() > 0 && set_pointer[i].size() < origin_set.size()) { 171 | vec.push_back(set_pointer[i]); 172 | } 173 | else { 174 | continue; 175 | } 176 | } 177 | delete[] set_pointer; 178 | return true; 179 | } 180 | } 181 | vec.push_back(origin_set); 182 | delete[] set_pointer; 183 | return false; 184 | } 185 | }; -------------------------------------------------------------------------------- /compiler/Nfa.cpp: -------------------------------------------------------------------------------- 1 | #include "Nfa.h" 2 | using namespace std; 3 | 4 | 5 | Nfa::Nfa() 6 | { 7 | } 8 | 9 | Nfa::Nfa(NFA hlh) { 10 | this->wordlist = new int[129]; 11 | for (int i = 0; i < 128; i++) { 12 | wordlist[i] = i; 13 | } 14 | wordlist[128] = -1; 15 | this->nfa_map = new int**[hlh.current_state + 1]; 16 | this->nfa_map[hlh.current_state] = nullptr; 17 | for (int i = 0; i < hlh.current_state; i++) { 18 | this->nfa_map[i] = new int*[129]; 19 | this->nfa_map[i][128] = nullptr; 20 | for (int j = 0; j < 128; j++) { 21 | int size = hlh.transition[i][j].size(); 22 | if (size == 0) { 23 | this->nfa_map[i][j] = new int[2]; 24 | this->nfa_map[i][j][1] = -1; 25 | this->nfa_map[i][j][0] = 0; 26 | } 27 | else { 28 | this->nfa_map[i][j] = new int[size + 1]; 29 | this->nfa_map[i][j][size] = -1; 30 | for (int k = 0; k < size; k++) { 31 | this->nfa_map[i][j][k] = hlh.transition[i][j][k]; 32 | } 33 | } 34 | } 35 | } 36 | this->s = hlh.start; 37 | this->nfa_end = hlh.end; 38 | } 39 | 40 | 41 | Nfa::~Nfa() { 42 | } 43 | -------------------------------------------------------------------------------- /compiler/Nfa.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include "hlhNFA.h" 6 | using namespace std; 7 | class Nfa 8 | { 9 | public: 10 | Nfa(); 11 | Nfa(NFA hlh); 12 | ~Nfa(); 13 | int*** nfa_map; 14 | int s; 15 | map nfa_end; 16 | int* wordlist; 17 | }; 18 | -------------------------------------------------------------------------------- /compiler/Nfa_to_dfa.cpp: -------------------------------------------------------------------------------- 1 | #include "Nfa_to_dfa.h" 2 | #include "Nfa.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | class Dstate { 11 | public: 12 | int index; 13 | set* state; 14 | bool marked; 15 | friend bool operator<(const Dstate& former, const Dstate& input) { 16 | return former.index < input.index; 17 | } 18 | Dstate() { 19 | this->index = -1; 20 | this->marked = false; 21 | } 22 | Dstate(const Dstate& input) { 23 | this->index = input.index; 24 | this->state = input.state; 25 | this->marked = input.marked; 26 | } 27 | }; 28 | 29 | NfaToDfa::NfaToDfa(Nfa nfa) { 30 | this->nfa = nfa; 31 | this->wordlist = nfa.wordlist; 32 | int i, j; 33 | for (i = 0; nfa.nfa_map[i] != nullptr; i++); 34 | for (j = 0; nfa.wordlist[j] != -1; j++); 35 | this->dfa_map = new int*[j]; 36 | for (int t = 0; t < j; t++) { 37 | dfa_map[t] = new int[i]; 38 | for (int tt = 0; tt < i; tt++) { 39 | dfa_map[t][tt] = 0; 40 | } 41 | } 42 | } 43 | 44 | 45 | NfaToDfa::~NfaToDfa() { 46 | } 47 | 48 | set NfaToDfa::closure(set T) { 49 | stack st; 50 | set closure = T; 51 | for (set::iterator iter = T.begin(); iter != T.end(); iter++) { 52 | st.push(*iter); 53 | } 54 | while (!st.empty()) { 55 | int t = st.top(); 56 | st.pop(); 57 | for (int i = 0; this->nfa.nfa_map[t][0][i] != -1; i++) { 58 | int tt = this->nfa.nfa_map[t][0][i]; 59 | if (tt != 0 && closure.insert(this->nfa.nfa_map[t][0][i]).second) { 60 | st.push(this->nfa.nfa_map[t][0][i]); 61 | } 62 | } 63 | } 64 | return closure; 65 | } 66 | 67 | set NfaToDfa::next(int head, int character) { 68 | set ne; 69 | for (int i = 0; this->nfa.nfa_map[head][character][i] != -1; i++) { 70 | int t = this->nfa.nfa_map[head][character][i]; 71 | if (t != 0) { 72 | ne.insert(t); 73 | } 74 | } 75 | return ne; 76 | } 77 | 78 | void NfaToDfa::transform() { 79 | 80 | set dfa_states; 81 | 82 | set s0; 83 | s0.insert(this->nfa.s); 84 | Dstate s; 85 | s.index = 1; 86 | s.state = new set(closure(s0)); 87 | s.marked = false; 88 | dfa_states.insert(s); 89 | this->dfa_s = 1; 90 | int index = 2; 91 | for (map::iterator e = nfa.nfa_end.begin(); e != nfa.nfa_end.end(); e++) { 92 | if ((*(s.state)).find((*e).first) != (*(s.state)).end()) { 93 | dfa_end.insert(pair(s.index, (*e).second)); 94 | } 95 | } 96 | for (set::iterator iter = dfa_states.begin(); iter != dfa_states.end(); iter++) { 97 | if (!(*iter).marked) { 98 | Dstate temp = (*iter); 99 | dfa_states.erase(*iter); 100 | temp.marked = true; 101 | dfa_states.insert(temp); 102 | for (int i = 1; wordlist[i] != -1; i++) { 103 | set temp_next; 104 | for (set::iterator j = (*(temp.state)).begin(); j != (*(temp.state)).end(); j++) { 105 | set temp_j_next = next(*j, wordlist[i]); 106 | for (set::iterator m = temp_j_next.begin(); m != temp_j_next.end(); m++) { 107 | temp_next.insert(*m); 108 | } 109 | } 110 | if (temp_next.size() == 0) { 111 | continue; 112 | } 113 | set U = closure(temp_next); 114 | bool have = false; 115 | Dstate newstate; 116 | for (set::iterator j = dfa_states.begin(); j != dfa_states.end(); j++) { 117 | set thestate = *(*j).state; 118 | if (U == thestate) { 119 | have = true; 120 | newstate = *j; 121 | break; 122 | } 123 | } 124 | if (!have) { 125 | newstate.index = index; 126 | newstate.state = new set(U); 127 | newstate.marked = false; 128 | for (map::iterator e = nfa.nfa_end.begin(); e != nfa.nfa_end.end(); e++) { 129 | if (U.find((*e).first) != U.end()) { 130 | dfa_end.insert(pair(newstate.index, (*e).second)); 131 | } 132 | } 133 | dfa_states.insert(newstate); 134 | /*for (set::iterator it = dfa_states.begin(); it != dfa_states.end(); it++) { 135 | cout << "dfa state " << (*it).index << ": "; 136 | for (set::iterator pr = (*(*it).state).begin(); pr != (*(*it).state).end(); pr++) { 137 | cout << *pr << " "; 138 | } 139 | cout << endl; 140 | } 141 | cout << endl;*/ 142 | index++; 143 | } 144 | dfa_map[wordlist[i]][temp.index] = newstate.index; 145 | } 146 | iter = dfa_states.begin(); 147 | } 148 | } 149 | this->n_dfa_states = index; 150 | int chars; 151 | for (chars = 0; wordlist[chars] != -1; chars++); 152 | this->n_chars = chars; 153 | int **temp_map = new int*[n_chars]; 154 | for (int i = 0; i < n_chars; i++) { 155 | temp_map[i] = new int[n_dfa_states]; 156 | for (int j = 0; j < n_dfa_states; j++) { 157 | temp_map[i][j] = dfa_map[i][j]; 158 | } 159 | } 160 | dfa_map = temp_map; 161 | } 162 | -------------------------------------------------------------------------------- /compiler/Nfa_to_dfa.h: -------------------------------------------------------------------------------- 1 | #include "Nfa.h" 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | #pragma once 7 | class NfaToDfa 8 | { 9 | public: 10 | NfaToDfa(Nfa nfa); 11 | ~NfaToDfa(); 12 | 13 | Nfa nfa; 14 | int* wordlist; 15 | 16 | int** dfa_map; 17 | int dfa_s; 18 | int n_dfa_states; 19 | int n_chars; 20 | map dfa_end; 21 | 22 | set closure(set T); 23 | set next(int head, int character); 24 | void transform(); 25 | }; 26 | -------------------------------------------------------------------------------- /compiler/RegExp.cpp: -------------------------------------------------------------------------------- 1 | #include "RegExp.h" 2 | #include 3 | #include 4 | #include 5 | 6 | RegExp::RegExp(std::string exp, int mode) 7 | { 8 | if(mode == 0) 9 | { 10 | infix_exp = exp; 11 | reg_tree = nullptr; 12 | suffix_exp = to_suffix(); 13 | reg_tree = to_reg_tree(); 14 | } 15 | else if(mode == 1) 16 | { 17 | infix_exp = exp; 18 | suffix_exp = exp; 19 | reg_tree = to_reg_tree(); 20 | } 21 | 22 | } 23 | 24 | std::string RegExp::get_suffix_exp() 25 | { 26 | return suffix_exp; 27 | } 28 | 29 | RegTreeNode* RegExp::get_reg_tree() 30 | { 31 | return reg_tree; 32 | } 33 | 34 | std::string RegExp::to_suffix() 35 | { 36 | for(int count = 0; count < infix_exp.length()-1; count++) 37 | { 38 | if(!is_operator(infix_exp[count]) && !is_operator(infix_exp[count + 1]) && infix_exp[count + 1] != '\5' && infix_exp[count] != '\4') 39 | { 40 | infix_exp.insert(count + 1, 1, '\3'); 41 | count++; 42 | } 43 | else if(infix_exp[count]=='\1' && !is_operator(infix_exp[count + 1]) && infix_exp[count + 1] != '\5' ) 44 | { 45 | infix_exp.insert(count + 1, 1, '\3'); 46 | count++; 47 | } 48 | } 49 | std::stack operator_stack; 50 | std::string suffix; 51 | for(int count = 0; count < infix_exp.length(); count++) 52 | { 53 | if(is_operator(infix_exp[count])) 54 | { 55 | if(!operator_stack.empty() && !is_prior(operator_stack.top(), infix_exp[count])) 56 | { 57 | while(!operator_stack.empty()&&operator_stack.top()!='\4') 58 | { 59 | suffix.append(1, operator_stack.top()); 60 | operator_stack.pop(); 61 | } 62 | } 63 | operator_stack.push(infix_exp[count]); 64 | } 65 | else if(infix_exp[count] == '\4') 66 | { 67 | operator_stack.push(infix_exp[count]); 68 | } 69 | else if(infix_exp[count] == '\5') 70 | { 71 | while(operator_stack.top() != '\4') 72 | { 73 | suffix.append(1, operator_stack.top()); 74 | operator_stack.pop(); 75 | } 76 | operator_stack.pop(); 77 | } 78 | else 79 | { 80 | suffix.append(1, infix_exp[count]); 81 | } 82 | } 83 | while(!operator_stack.empty()) 84 | { 85 | suffix.append(1, operator_stack.top()); 86 | operator_stack.pop(); 87 | } 88 | return suffix; 89 | } 90 | 91 | RegTreeNode* RegExp::to_reg_tree() 92 | { 93 | std::stack node_stack; 94 | RegTreeNode *temp, *left_child, *right_child; 95 | for(int count = 0; countright = right_child; 105 | } 106 | left_child = node_stack.top(); 107 | node_stack.pop(); 108 | temp->left = left_child; 109 | } 110 | node_stack.push(temp); 111 | } 112 | return node_stack.top(); 113 | } 114 | 115 | bool RegExp::is_prior(char opreand1, char operand2) 116 | { 117 | if(operand2 == '\1') 118 | { 119 | return opreand1 != '\1'; 120 | } 121 | else if(operand2 == '\2') 122 | { 123 | return !(opreand1 == '\1' || opreand1 == '\2'); 124 | } 125 | else 126 | { 127 | return false; 128 | } 129 | } 130 | 131 | bool RegExp::is_operator(char operand) 132 | { 133 | return operand == '\1' || operand == '\2' || operand == '\3'; 134 | } 135 | 136 | void RegExp::get_explicit_suffix_exp() 137 | { 138 | for(int count = 0; count 5 | 6 | struct RegTreeNode 7 | { 8 | // 该节点的操作符 9 | char reg_op; // '\1'='*' '\2'='|' '\3'='.' '\4'='(' '\5'=')' 10 | // 该节点的左右子节点 11 | RegTreeNode* left; 12 | RegTreeNode* right; 13 | // 起止状态号 14 | int start; 15 | int end; 16 | RegTreeNode(char _reg_op, RegTreeNode* _left = nullptr, RegTreeNode* _right = nullptr) 17 | { 18 | reg_op = _reg_op; 19 | left = _left; 20 | right = _right; 21 | start = end = 0; 22 | } 23 | }; 24 | 25 | class RegExp 26 | { 27 | // 中缀表达式字符串 28 | std::string infix_exp; 29 | // 后缀表达式字符串 30 | std::string suffix_exp; 31 | // 语法分析树根节点指针 32 | RegTreeNode* reg_tree; 33 | public: 34 | // 构造函数 35 | RegExp(std::string exp, int mode = 0); 36 | // 返回该后缀表达式字符串 37 | std::string get_suffix_exp(); 38 | // 返回语法分析树根节点指针 39 | RegTreeNode* get_reg_tree(); 40 | // 将后缀表达式输出到控制台 41 | void get_explicit_suffix_exp(); 42 | private: 43 | // 中缀表达式转后缀表达式 44 | std::string to_suffix(); 45 | // 后缀表达式转正则树 46 | RegTreeNode* to_reg_tree(); 47 | // 判断操作符优先级 48 | bool is_prior(char opreand1, char operand2); 49 | // 判断是否为操作符 50 | bool is_operator(char operand); 51 | }; 52 | 53 | #endif //COMPILER_REGEXP_H 54 | -------------------------------------------------------------------------------- /compiler/StatementAction.cpp: -------------------------------------------------------------------------------- 1 | #include "GrammerAnalyzer.h" 2 | 3 | void GrammerAnalyzer::action301(hebo::LexicalUnit* root) { 4 | root->father->child_node_list[1]->attribute.con_instr = root->father->attribute.con_instr; 5 | root->father->child_node_list[1]->attribute.break_instr = root->father->attribute.break_instr; 6 | return; 7 | } 8 | 9 | void GrammerAnalyzer::action302(hebo::LexicalUnit* root) { 10 | root->father->child_node_list[1]->attribute.con_instr = root->father->attribute.con_instr; 11 | root->father->child_node_list[1]->attribute.break_instr = root->father->attribute.break_instr; 12 | return; 13 | } 14 | 15 | void GrammerAnalyzer::action303(hebo::LexicalUnit* root) { 16 | root->father->child_node_list[3]->attribute.con_instr = root->father->attribute.con_instr; 17 | root->father->child_node_list[3]->attribute.break_instr = root->father->attribute.break_instr; 18 | return; 19 | } 20 | 21 | void GrammerAnalyzer::action304(hebo::LexicalUnit* root) { 22 | root->father->child_node_list[1]->attribute.con_instr = root->father->attribute.con_instr; 23 | root->father->child_node_list[1]->attribute.break_instr = root->father->attribute.break_instr; 24 | return; 25 | } 26 | 27 | void GrammerAnalyzer::action305(hebo::LexicalUnit* root) { 28 | root->father->child_node_list[1]->attribute.con_instr = root->father->attribute.con_instr; 29 | root->father->child_node_list[1]->attribute.break_instr = root->father->attribute.break_instr; 30 | return; 31 | } -------------------------------------------------------------------------------- /compiler/SwitchToFunction.cpp: -------------------------------------------------------------------------------- 1 | #include "GrammerAnalyzer.h" 2 | 3 | void GrammerAnalyzer::execute_action(int action_number, hebo::LexicalUnit* root) { 4 | if (action_number > 0 && action_number < 100) { 5 | switch (action_number) { 6 | case 1: 7 | this->action1(root); 8 | break; 9 | case 2: 10 | this->action2(root); 11 | break; 12 | case 3: 13 | this->action3(root); 14 | break; 15 | case 4: 16 | this->action4(root); 17 | break; 18 | case 5: 19 | this->action5(root); 20 | break; 21 | case 6: 22 | this->action6(root); 23 | break; 24 | case 7: 25 | this->action7(root); 26 | break; 27 | case 8: 28 | this->action8(root); 29 | break; 30 | case 9: 31 | this->action9(root); 32 | break; 33 | case 10: 34 | this->action10(root); 35 | break; 36 | case 11: 37 | this->action11(root); 38 | break; 39 | case 12: 40 | this->action12(root); 41 | break; 42 | case 13: 43 | this->action13(root); 44 | break; 45 | case 14: 46 | this->action14(root); 47 | break; 48 | case 15: 49 | this->action15(root); 50 | break; 51 | case 16: 52 | this->action16(root); 53 | break; 54 | case 17: 55 | this->action17(root); 56 | break; 57 | case 18: 58 | this->action18(root); 59 | break; 60 | case 19: 61 | this->action19(root); 62 | break; 63 | case 20: 64 | this->action20(root); 65 | break; 66 | case 21: 67 | this->action21(root); 68 | break; 69 | case 22: 70 | this->action22(root); 71 | break; 72 | case 23: 73 | this->action23(root); 74 | break; 75 | case 24: 76 | this->action24(root); 77 | break; 78 | case 25: 79 | this->action25(root); 80 | break; 81 | case 26: 82 | this->action26(root); 83 | break; 84 | case 27: 85 | this->action27(root); 86 | break; 87 | default: 88 | std::cout << ""; 89 | break; 90 | } 91 | } 92 | else if (action_number > 100 && action_number < 200) { 93 | switch (action_number) { 94 | case 101: 95 | this->action101(root); 96 | break; 97 | case 102: 98 | this->action102(root); 99 | break; 100 | case 103: 101 | this->action103(root); 102 | break; 103 | case 104: 104 | this->action104(root); 105 | break; 106 | case 109: 107 | this->action109(root); 108 | break; 109 | case 110: 110 | this->action110(root); 111 | break; 112 | case 111: 113 | this->action111(root); 114 | break; 115 | case 112: 116 | this->action112(root); 117 | break; 118 | case 113: 119 | this->action113(root); 120 | break; 121 | case 114: 122 | this->action114(root); 123 | break; 124 | case 115: 125 | this->action115(root); 126 | break; 127 | case 116: 128 | this->action116(root); 129 | break; 130 | default: 131 | std::cout << ""; 132 | break; 133 | } 134 | } 135 | else if (action_number > 200 && action_number < 300) { 136 | switch (action_number) { 137 | case 201: 138 | this->action201(root); 139 | break; 140 | case 202: 141 | this->action202(root); 142 | break; 143 | case 203: 144 | this->action203(root); 145 | break; 146 | case 204: 147 | this->action204(root); 148 | break; 149 | case 211: 150 | this->action211(root); 151 | break; 152 | case 212: 153 | this->action212(root); 154 | break; 155 | case 213: 156 | this->action213(root); 157 | break; 158 | case 214: 159 | this->action214(root); 160 | break; 161 | case 215: 162 | this->action215(root); 163 | break; 164 | case 216: 165 | this->action216(root); 166 | break; 167 | case 217: 168 | this->action217(root); 169 | break; 170 | case 218: 171 | this->action218(root); 172 | break; 173 | case 219: 174 | this->action219(root); 175 | break; 176 | case 220: 177 | this->action220(root); 178 | break; 179 | case 221: 180 | this->action221(root); 181 | break; 182 | case 222: 183 | this->action222(root); 184 | break; 185 | case 223: 186 | this->action223(root); 187 | break; 188 | case 224: 189 | this->action224(root); 190 | break; 191 | case 225: 192 | this->action225(root); 193 | break; 194 | case 226: 195 | this->action226(root); 196 | break; 197 | case 227: 198 | this->action227(root); 199 | break; 200 | case 228: 201 | this->action228(root); 202 | break; 203 | case 229: 204 | this->action229(root); 205 | break; 206 | case 230: 207 | this->action230(root); 208 | break; 209 | case 231: 210 | this->action231(root); 211 | break; 212 | case 232: 213 | this->action232(root); 214 | break; 215 | case 233: 216 | this->action233(root); 217 | break; 218 | case 234: 219 | this->action234(root); 220 | break; 221 | case 235: 222 | this->action235(root); 223 | break; 224 | case 236: 225 | this->action236(root); 226 | break; 227 | case 237: 228 | this->action237(root); 229 | break; 230 | case 238: 231 | this->action238(root); 232 | break; 233 | case 239: 234 | this->action239(root); 235 | break; 236 | case 240: 237 | this->action240(root); 238 | break; 239 | case 241: 240 | this->action241(root); 241 | break; 242 | case 242: 243 | this->action242(root); 244 | break; 245 | default: 246 | std::cout << ""; 247 | break; 248 | } 249 | } 250 | else if (action_number > 300 && action_number < 400) { 251 | switch (action_number) { 252 | case 301: 253 | this->action301(root); 254 | break; 255 | case 302: 256 | this->action302(root); 257 | break; 258 | case 303: 259 | this->action303(root); 260 | break; 261 | case 304: 262 | this->action304(root); 263 | break; 264 | case 305: 265 | this->action305(root); 266 | break; 267 | default: 268 | std::cout << ""; 269 | break; 270 | } 271 | } 272 | else if (action_number > 400 && action_number < 500) { 273 | switch (action_number) { 274 | case 401: 275 | this->action401(root); 276 | break; 277 | case 402: 278 | this->action402(root); 279 | break; 280 | case 403: 281 | this->action403(root); 282 | break; 283 | case 404: 284 | this->action404(root); 285 | break; 286 | case 405: 287 | this->action405(root); 288 | break; 289 | case 406: 290 | this->action406(root); 291 | break; 292 | case 407: 293 | this->action407(root); 294 | break; 295 | case 408: 296 | this->action408(root); 297 | break; 298 | case 409: 299 | this->action409(root); 300 | break; 301 | case 410: 302 | this->action410(root); 303 | break; 304 | case 411: 305 | this->action411(root); 306 | break; 307 | case 412: 308 | this->action412(root); 309 | break; 310 | case 413: 311 | this->action413(root); 312 | break; 313 | case 414: 314 | this->action414(root); 315 | break; 316 | case 415: 317 | this->action415(root); 318 | break; 319 | case 416: 320 | this->action416(root); 321 | break; 322 | case 417: 323 | this->action417(root); 324 | break; 325 | case 418: 326 | this->action418(root); 327 | break; 328 | case 419: 329 | this->action419(root); 330 | break; 331 | case 420: 332 | this->action420(root); 333 | break; 334 | case 421: 335 | this->action421(root); 336 | break; 337 | case 422: 338 | this->action422(root); 339 | break; 340 | case 423: 341 | this->action423(root); 342 | break; 343 | case 424: 344 | this->action424(root); 345 | break; 346 | case 425: 347 | this->action425(root); 348 | break; 349 | case 426: 350 | this->action426(root); 351 | break; 352 | case 427: 353 | this->action427(root); 354 | break; 355 | default: 356 | std::cout << ""; 357 | break; 358 | } 359 | } 360 | else if (action_number > 500 && action_number < 600) { 361 | switch (action_number) { 362 | case 501: 363 | this->action501(root); 364 | break; 365 | case 502: 366 | this->action502(root); 367 | break; 368 | case 503: 369 | this->action503(root); 370 | break; 371 | case 504: 372 | this->action504(root); 373 | break; 374 | case 505: 375 | this->action505(root); 376 | break; 377 | case 506: 378 | this->action506(root); 379 | break; 380 | case 507: 381 | this->action507(root); 382 | break; 383 | case 508: 384 | this->action508(root); 385 | break; 386 | case 509: 387 | this->action509(root); 388 | break; 389 | case 510: 390 | this->action510(root); 391 | break; 392 | case 511: 393 | this->action511(root); 394 | break; 395 | case 512: 396 | this->action512(root); 397 | break; 398 | case 513: 399 | this->action513(root); 400 | break; 401 | case 514: 402 | this->action514(root); 403 | break; 404 | case 515: 405 | this->action515(root); 406 | break; 407 | case 516: 408 | this->action516(root); 409 | break; 410 | case 517: 411 | this->action517(root); 412 | break; 413 | case 518: 414 | this->action518(root); 415 | break; 416 | case 519: 417 | this->action519(root); 418 | break; 419 | case 520: 420 | this->action520(root); 421 | break; 422 | case 521: 423 | this->action521(root); 424 | break; 425 | case 522: 426 | this->action522(root); 427 | break; 428 | case 523: 429 | this->action523(root); 430 | break; 431 | case 524: 432 | this->action524(root); 433 | break; 434 | case 525: 435 | this->action525(root); 436 | break; 437 | default: 438 | std::cout << ""; 439 | break; 440 | } 441 | } 442 | else if (action_number > 600 && action_number < 700) { 443 | switch (action_number) { 444 | case 601: 445 | this->action601(root); 446 | break; 447 | case 602: 448 | this->action602(root); 449 | break; 450 | case 603: 451 | this->action603(root); 452 | break; 453 | case 604: 454 | this->action604(root); 455 | break; 456 | case 605: 457 | this->action605(root); 458 | break; 459 | case 606: 460 | this->action606(root); 461 | break; 462 | case 607: 463 | this->action607(root); 464 | break; 465 | case 608: 466 | this->action608(root); 467 | break; 468 | case 609: 469 | this->action609(root); 470 | break; 471 | case 610: 472 | this->action610(root); 473 | break; 474 | case 611: 475 | this->action611(root); 476 | break; 477 | case 612: 478 | this->action612(root); 479 | break; 480 | case 613: 481 | this->action613(root); 482 | break; 483 | case 614: 484 | this->action614(root); 485 | break; 486 | case 615: 487 | this->action615(root); 488 | break; 489 | case 616: 490 | this->action616(root); 491 | break; 492 | case 617: 493 | this->action617(root); 494 | break; 495 | case 618: 496 | this->action618(root); 497 | break; 498 | default: 499 | std::cout << ""; 500 | break; 501 | } 502 | } 503 | else { 504 | std::cout << ""; 505 | } 506 | } -------------------------------------------------------------------------------- /compiler/SymbolTable.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hlh981029/c-compiler/b7a3afe0b050d92f7b946f64f5a28d8e5e49183c/compiler/SymbolTable.cpp -------------------------------------------------------------------------------- /compiler/SymbolTable.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | namespace hbst 8 | { 9 | class SymbolItem 10 | { 11 | static int symbol_count; 12 | public: 13 | SymbolItem(); 14 | std::string address; 15 | std::string name; 16 | std::string type; 17 | int offset; 18 | int width; 19 | SymbolItem(std::string _name, std::string _type, int _offset, int _width); 20 | }; 21 | 22 | class SymbolTable 23 | { 24 | static int symbol_table_count; 25 | void put_struct(std::string object_name, std::string struct_name); 26 | void put_struct_array(std::string array_name, std::string struct_name, int length); 27 | public: 28 | SymbolTable* father; 29 | std::vector symbol_item_vector; 30 | std::string symbol_table_name; 31 | std::vector son_vector; 32 | 33 | SymbolTable(); 34 | SymbolTable(std::string _name, SymbolTable* _father = nullptr); 35 | SymbolTable(const SymbolTable& copied); 36 | 37 | void put_symbol(const SymbolItem& symbol) throw(std::string); 38 | SymbolItem& get_symbol(std::string symbol_name) throw(std::string); 39 | SymbolItem& get_symbol_from_address(std::string symbol_address) throw(std::string); 40 | 41 | 42 | 43 | ~SymbolTable(); 44 | }; 45 | 46 | class StructItem 47 | { 48 | public: 49 | std::string name; 50 | SymbolTable symbol_table; 51 | 52 | StructItem(); 53 | StructItem(std::string _name, SymbolTable _symbol_table); 54 | }; 55 | 56 | 57 | class StructTable 58 | { 59 | public: 60 | std::vector struct_item_vector; 61 | StructItem& put_struct(const StructItem& struct_item) throw(std::string); 62 | StructItem& get_struct(std::string struct_name) throw(std::string); 63 | StructTable(); 64 | }; 65 | 66 | 67 | 68 | class FunctionItem 69 | { 70 | public: 71 | std::string name; 72 | std::string return_type; 73 | std::vector parameter_vector; 74 | void add_parameter(std::string parameter); 75 | FunctionItem(); 76 | FunctionItem(std::string _name, std::string _return_type); 77 | }; 78 | 79 | 80 | class FunctionTable 81 | { 82 | public: 83 | std::vector function_item_vector; 84 | FunctionTable(); 85 | void put_function(const FunctionItem& function_item) throw(std::string); 86 | FunctionItem& get_function(std::string name) throw(std::string); 87 | }; 88 | } 89 | extern std::map constant_map; 90 | extern hbst::SymbolTable global_symbol_table; 91 | extern hbst::StructTable global_struct_table; 92 | extern hbst::FunctionTable global_function_table; -------------------------------------------------------------------------------- /compiler/action.txt: -------------------------------------------------------------------------------- 1 | 115 2 | primary_expression IDENTIFIER action1 3 | primary_expression CONSTANT action2 4 | primary_expression ( expression ) action4 5 | postfix_expression primary_expression action5 6 | postfix_expression IDENTIFIER [ expression ] action6 7 | postfix_expression postfix_expression ( ) action7 8 | postfix_expression postfix_expression ( argument_expression_list ) action8 9 | postfix_expression IDENTIFIER . IDENTIFIER action9 10 | postfix_expression postfix_expression INC_OP action10 11 | postfix_expression postfix_expression DEC_OP action11 12 | unary_expression postfix_expression action12 13 | unary_expression INC_OP unary_expression action13 14 | unary_expression DEC_OP unary_expression action14 15 | unary_expression unary_operator cast_expression action15 16 | unary_expression SIZEOF unary_expression action16 17 | unary_expression SIZEOF ( type_name ) action17 18 | unary_operator & action18 19 | unary_operator * action19 20 | unary_operator + action20 21 | unary_operator - action21 22 | unary_operator ~ action22 23 | unary_operator ! action23 24 | cast_expression unary_expression action24 25 | cast_expression ( type_name ) cast_expression action25 26 | argument_expression_list assignment_expression action26 27 | argument_expression_list argument_expression_list , assignment_expression action27 28 | argumented_translation_unit action113 translation_unit 29 | compound_statement { action101 } 30 | compound_statement { action102 statement_list } action114 31 | compound_statement { action103 declaration_list } action115 32 | compound_statement { action104 declaration_list statement_list } action116 33 | translation_unit action109 external_declaration 34 | translation_unit action110 translation_unit external_declaration 35 | external_declaration action111 function_definition 36 | external_declaration action112 declaration 37 | type_specifier VOID action201 38 | type_specifier INT action203 39 | type_specifier struct_or_union_specifier action204 40 | direct_declarator IDENTIFIER action211 41 | direct_declarator IDENTIFIER [ assignment_expression ] action212 42 | direct_declarator ( direct_declarator ) action213 43 | declarator action214 direct_declarator action215 44 | init_declarator action216 declarator action217 45 | declaration type_specifier action218 init_declarator_list ; 46 | init_declarator_list action219 init_declarator 47 | init_declarator_list action220 init_declarator_list , action221 init_declarator 48 | type_name type_specifier action222 49 | init_declarator action223 declarator = initializer action224 50 | initializer assignment_expression action225 51 | initializer { initializer_list } action226 52 | initializer { initializer_list , } action227 53 | initializer_list assignment_expression action228 54 | initializer_list initializer_list , assignment_expression action229 55 | struct_or_union_specifier STRUCT IDENTIFIER { action231 struct_declaration_list action230 } 56 | struct_or_union_specifier STRUCT { action232 struct_declaration_list action233 } 57 | struct_or_union_specifier STRUCT IDENTIFIER action234 58 | struct_declaration_list struct_declaration action235 59 | struct_declaration_list struct_declaration_list struct_declaration action236 60 | struct_declaration type_specifier action237 struct_declarator_list ; action238 61 | struct_declarator_list action239 declarator action240 62 | struct_declarator_list action241 struct_declarator_list , declarator action242 63 | statement_list action301 statement 64 | statement_list action302 statement_list action303 statement 65 | statement action304 jump_statement 66 | statement action305 compound_statement 67 | statement selection_statement 68 | statement expression_statement 69 | statement iteration_statement 70 | multiplicative_expression cast_expression action401 71 | multiplicative_expression multiplicative_expression * cast_expression action402 72 | multiplicative_expression multiplicative_expression / cast_expression action403 73 | multiplicative_expression multiplicative_expression % cast_expression action404 74 | additive_expression multiplicative_expression action405 75 | additive_expression additive_expression + multiplicative_expression action406 76 | additive_expression additive_expression - multiplicative_expression action407 77 | shift_expression additive_expression action408 78 | relational_expression shift_expression action409 79 | relational_expression relational_expression < shift_expression action410 80 | relational_expression relational_expression > shift_expression action411 81 | relational_expression relational_expression LE_OP shift_expression action412 82 | relational_expression relational_expression GE_OP shift_expression action413 83 | equality_expression relational_expression action414 84 | equality_expression equality_expression EQ_OP relational_expression action415 85 | equality_expression equality_expression NE_OP relational_expression action416 86 | exclusive_or_expression equality_expression action417 87 | exclusive_or_expression exclusive_or_expression ^ equality_expression action418 88 | logical_and_expression exclusive_or_expression action419 89 | logical_and_expression logical_and_expression AND_OP exclusive_or_expression action420 90 | logical_or_expression logical_and_expression action421 91 | logical_or_expression logical_or_expression OR_OP logical_and_expression action422 92 | assignment_expression logical_or_expression action423 93 | assignment_expression unary_expression = assignment_expression action424 94 | expression assignment_expression action425 95 | expression expression , assignment_expression action426 96 | expression_statement expression ; action427 97 | iteration_statement WHILE ( action501 expression action502 ) action503 statement action504 98 | iteration_statement FOR ( expression_statement action505 expression_statement action506 ) action507 statement action508 99 | iteration_statement FOR ( expression_statement action509 expression_statement action510 expression action511 ) action512 statement action513 100 | selection_statement IF ( expression action514 ) action515 statement action516 101 | selection_statement IF ( expression action517 ) action518 statement action519 ELSE action520 statement action521 102 | jump_statement CONTINUE ; action522 103 | jump_statement BREAK ; action523 104 | jump_statement RETURN ; action524 105 | jump_statement RETURN expression ; action525 106 | direct_declarator action601 direct_declarator action602 ( parameter_list ) 107 | direct_declarator action603 direct_declarator ( ) action604 108 | parameter_list parameter_declaration action605 109 | parameter_list action618 parameter_list , parameter_declaration action606 110 | parameter_declaration type_specifier declarator action607 111 | parameter_declaration type_specifier action608 112 | function_compound_statement { } action609 113 | function_compound_statement { action610 statement_list action611 } 114 | function_compound_statement { action612 declaration_list action613 } 115 | function_compound_statement { action614 declaration_list statement_list action615 } 116 | function_definition type_specifier action616 direct_declarator action617 function_compound_statement -------------------------------------------------------------------------------- /compiler/compile_asm.bat: -------------------------------------------------------------------------------- 1 | "D:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\devenv" ..\Assembly\Project.sln /rebuild "Debug|Win32" 2 | 3 | ..\Assembly\Debug\Project.exe 4 | -------------------------------------------------------------------------------- /compiler/compiler.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {26511C81-B83A-4A1D-A915-75EA90A893D5} 24 | compiler 25 | 10.0.16299.0 26 | 27 | 28 | 29 | Application 30 | true 31 | v141 32 | MultiByte 33 | 34 | 35 | Application 36 | false 37 | v141 38 | true 39 | MultiByte 40 | 41 | 42 | Application 43 | true 44 | v141 45 | MultiByte 46 | 47 | 48 | Application 49 | false 50 | v141 51 | true 52 | MultiByte 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | Level3 76 | Disabled 77 | true 78 | 79 | 80 | 81 | 82 | Level3 83 | Disabled 84 | true 85 | 86 | 87 | 88 | 89 | Level3 90 | MaxSpeed 91 | true 92 | true 93 | true 94 | 95 | 96 | true 97 | true 98 | UseLinkTimeCodeGeneration 99 | 100 | 101 | 102 | 103 | Level3 104 | MaxSpeed 105 | true 106 | true 107 | true 108 | 109 | 110 | true 111 | true 112 | UseFastLinkTimeCodeGeneration 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /compiler/compiler.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | 源文件 23 | 24 | 25 | 源文件 26 | 27 | 28 | 源文件 29 | 30 | 31 | 源文件 32 | 33 | 34 | 源文件 35 | 36 | 37 | 源文件 38 | 39 | 40 | 源文件 41 | 42 | 43 | 源文件 44 | 45 | 46 | 源文件 47 | 48 | 49 | 源文件 50 | 51 | 52 | 源文件 53 | 54 | 55 | 源文件 56 | 57 | 58 | 源文件 59 | 60 | 61 | 源文件 62 | 63 | 64 | 源文件 65 | 66 | 67 | 源文件 68 | 69 | 70 | 源文件 71 | 72 | 73 | 源文件 74 | 75 | 76 | 77 | 78 | 头文件 79 | 80 | 81 | 头文件 82 | 83 | 84 | 头文件 85 | 86 | 87 | 头文件 88 | 89 | 90 | 头文件 91 | 92 | 93 | 头文件 94 | 95 | 96 | 头文件 97 | 98 | 99 | 头文件 100 | 101 | 102 | 头文件 103 | 104 | 105 | 106 | 107 | 头文件 108 | 109 | 110 | 111 | 112 | 资源文件 113 | 114 | 115 | -------------------------------------------------------------------------------- /compiler/hlhNFA.cpp: -------------------------------------------------------------------------------- 1 | #include "hlhNFA.h" 2 | #include "RegExp.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | NFA::NFA(RegExp **exps, std::string *names, int n) 11 | { 12 | current_state = 2; 13 | max_state = 1; 14 | start = 1; 15 | for(int count = 0; countget_suffix_exp().length()*2); 18 | } 19 | transition = new std::vector*[max_state]; 20 | for(int count = 0; count[128]; 23 | } 24 | RegTreeNode *temp; 25 | RegTreeNode *start_node = new RegTreeNode('\2'); 26 | start_node->start = 1; 27 | for(int count = 0; countget_reg_tree()); 30 | to_nfa(temp); 31 | end.insert(std::pair(temp->end, names[count])); 32 | transition[1][0].push_back(temp->start); 33 | } 34 | } 35 | 36 | void NFA::to_nfa(RegTreeNode *root) 37 | { 38 | recurse_to_nfa(root); 39 | } 40 | 41 | void NFA::recurse_to_nfa(RegTreeNode *root) 42 | { 43 | if(root->left != nullptr) 44 | { 45 | recurse_to_nfa(root->left); 46 | } 47 | if(root->right!= nullptr) 48 | { 49 | recurse_to_nfa(root->right); 50 | } 51 | if(!is_operator(root->reg_op)) 52 | { 53 | root->start = current_state++; 54 | root->end = current_state++; 55 | transition[root->start][(int)(root->reg_op)].push_back(root->end); 56 | } 57 | else if(root->reg_op == '\3') 58 | { 59 | root->start = root->left->start; 60 | root->end = root->right->end; 61 | transition[root->left->end][0].push_back(root->right->start); 62 | } 63 | else if(root->reg_op == '\2') 64 | { 65 | root->start = current_state++; 66 | root->end = current_state++; 67 | transition[root->start][0].push_back(root->left->start); 68 | transition[root->start][0].push_back(root->right->start); 69 | transition[root->left->end][0].push_back(root->end); 70 | transition[root->right->end][0].push_back(root->end); 71 | } 72 | else if(root->reg_op == '\1') 73 | { 74 | root->start = current_state++; 75 | root->end = current_state++; 76 | transition[root->start][0].push_back(root->left->start); 77 | transition[root->start][0].push_back(root->end); 78 | transition[root->left->end][0].push_back(root->left->start); 79 | transition[root->left->end][0].push_back(root->end); 80 | } 81 | } 82 | 83 | bool NFA::is_operator(char operand) 84 | { 85 | return operand == '\1' || operand == '\2' || operand == '\3'; 86 | } 87 | 88 | void NFA::print_diagram() 89 | { 90 | std::cout << current_state << std::endl; 91 | for (int i = 0; i < current_state; i++) 92 | { 93 | for (int j = 0; j < 128; j++) 94 | { 95 | if (!transition[i][j].empty()) 96 | { 97 | std::cout << i << '-'; 98 | if (j == 0) { 99 | std::cout << "empty"; 100 | } 101 | else 102 | { 103 | std::cout << char(j); 104 | } 105 | std::cout << "->["; 106 | for (int k = 0; k < transition[i][j].size(); k++) { 107 | std::cout << transition[i][j][k] << ","; 108 | } 109 | std::cout << "]"; 110 | } 111 | } 112 | std::cout << std::endl; 113 | } 114 | } 115 | 116 | NFA::~NFA() 117 | { 118 | 119 | } 120 | 121 | NFA::NFA() 122 | { 123 | 124 | } 125 | -------------------------------------------------------------------------------- /compiler/hlhNFA.h: -------------------------------------------------------------------------------- 1 | #ifndef COMPILER_NFA_H 2 | #define COMPILER_NFA_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "RegExp.h" 10 | 11 | class NFA 12 | { 13 | public: 14 | NFA(); 15 | NFA(RegExp **exps, std::string *names, int n); 16 | ~NFA(); 17 | // 当前状态数 18 | int current_state; 19 | // 最大状态数 20 | int max_state; 21 | // 状态转换表 22 | std::vector** transition; 23 | // 初始状态号 24 | int start; 25 | // 结束状态集 26 | std::map end; 27 | // 正则树转NFA 28 | void to_nfa(RegTreeNode *root); 29 | // 转NFA调用的递归函数 30 | void recurse_to_nfa(RegTreeNode *root); 31 | // 判断是否为操作符 32 | bool is_operator(char operand); 33 | // 输出状态转换表到控制台 34 | void print_diagram(); 35 | }; 36 | 37 | 38 | #endif //COMPILER_NFA_H 39 | -------------------------------------------------------------------------------- /compiler/input_and_output.cpp: -------------------------------------------------------------------------------- 1 | #include "intput_and_output.hpp" 2 | // hlhlsadjfka;fj;laskdj 3 | // the std::ifstream cpp_source had better be set as a member variable, maybe. 4 | namespace hebo 5 | { 6 | std::string uint2string(unsigned int input) 7 | { 8 | std::stringstream trans; 9 | trans << input; 10 | return trans.str(); 11 | } 12 | int string2int(const std::string& input) 13 | { 14 | std::stringstream trans; 15 | trans << input; 16 | int result; 17 | trans >> result; 18 | return result; 19 | } 20 | 21 | DFA::DFA(std::string source_file_name, int row_number_, int column_number_) 22 | :current_status(1), current_memory(0), row_number(row_number_), column_number(column_number_) 23 | { 24 | cpp_source.open(source_file_name); 25 | if (!cpp_source.is_open()) 26 | { 27 | std::cerr << "Not open the source file." << std::endl; 28 | } 29 | matrix = new int*[row_number]; 30 | for (int i = 0; i < row_number; i++) 31 | { 32 | matrix[i] = new int[column_number]; 33 | for (int j = 0; j < column_number; j++) 34 | { 35 | matrix[i][j] = i * 10 + j; 36 | } 37 | } 38 | } 39 | 40 | DFA::DFA(DFA& input) :current_status(1) 41 | { 42 | row_number = input.row_number; 43 | column_number = input.column_number; 44 | matrix = new int*[row_number]; 45 | for (int i = 0; i < row_number; i++) 46 | { 47 | matrix[i] = new int[column_number]; 48 | for (int j = 0; j < column_number; j++) 49 | { 50 | matrix[i][j] = input.matrix[i][j]; 51 | } 52 | } 53 | status_to_pattern = input.status_to_pattern; 54 | } 55 | 56 | DFA::DFA(std::string dfa_file_name, std::string source_file_name) 57 | { 58 | cpp_source.open(source_file_name, std::ios::in); 59 | std::ifstream dfa_file(dfa_file_name); 60 | if (!dfa_file.is_open() || !cpp_source.is_open()) 61 | { 62 | std::cerr << "Not open files" << std::endl; 63 | } 64 | std::string temp_string; 65 | dfa_file >> temp_string >> row_number; 66 | dfa_file >> temp_string >> column_number; 67 | dfa_file >> temp_string >> init_status; 68 | dfa_file >> temp_string; 69 | matrix = new int*[row_number]; 70 | for (int i = 0; i < row_number; i++) 71 | { 72 | matrix[i] = new int[column_number]; 73 | for (int j = 0; j < column_number; j++) 74 | { 75 | dfa_file >> matrix[i][j]; 76 | } 77 | } 78 | dfa_file >> temp_string; 79 | int end_status; 80 | std::string pattern; 81 | while (dfa_file >> end_status >> pattern) 82 | { 83 | status_to_pattern.insert(std::make_pair(end_status, pattern)); 84 | if (pattern == "//") 85 | { 86 | line__note_ = end_status; 87 | } 88 | else if (pattern == "/*") 89 | { 90 | left__note_ = end_status; 91 | } 92 | else if (pattern == "*/") 93 | { 94 | right_note_ = end_status; 95 | } 96 | } 97 | current_status = init_status; 98 | #ifdef DEBUG 99 | for (int i = 0; i < row_number; i++) 100 | { 101 | for (int j = 0; j < column_number; j++) 102 | { 103 | std::cout << matrix[i][j] << ' '; 104 | } 105 | std::cout << std::endl; 106 | } 107 | #endif // DEBUG 108 | 109 | } 110 | 111 | DFA::~DFA() 112 | { 113 | for (int i = 0; i < row_number; i++) 114 | { 115 | delete[] matrix[i]; 116 | matrix[i] = nullptr; 117 | } 118 | delete[] matrix; 119 | matrix = nullptr; 120 | status_to_pattern.clear(); 121 | row_number = 0; 122 | column_number = 0; 123 | word_list.clear(); 124 | } 125 | 126 | std::ostream& operator<<(std::ostream& my_out, const DFA& dfa) 127 | { 128 | for (int i = 0; i < dfa.row_number; i++) 129 | { 130 | for (int j = 0; j < dfa.column_number; j++) 131 | { 132 | my_out << dfa.matrix[i][j] << ' '; 133 | } 134 | my_out << std::endl; 135 | } 136 | return my_out; 137 | } 138 | 139 | /* 140 | 141 | -> means turn into 142 | 143 | input 144 | the current character 145 | the current string { member variable } 146 | the current status { member variable } 147 | output 148 | 149 | 150 | 151 | modify 152 | the current status -> the next status 153 | the current string -> the next string = the current string + the character { update member variable } 154 | word_list if dead status and new morpheme then append a (morpheme, value) 155 | output_sequence if dead status and new morpheme then append a unit 156 | */ 157 | 158 | //feed a single character from the source file to the dfa matrix and monitor the transition of the status 159 | auto DFA::feed(char ch) -> void 160 | { 161 | int next_status = matrix[current_status][ch]; 162 | bool is_dead = (next_status == dead_status); 163 | bool is_line = (next_status == line__note_); 164 | bool is_left = (next_status == left__note_); 165 | if (!(is_dead || is_line || is_left)) 166 | { 167 | current_string += ch; 168 | current_status = next_status; 169 | } 170 | else if (is_dead) 171 | { 172 | update_output_sequence(); 173 | current_string = ch; 174 | current_status = matrix[init_status][ch]; 175 | } 176 | else if (is_line) 177 | { 178 | deal_with_line_note(); 179 | } 180 | else if (is_left) 181 | { 182 | deal_with_multiplied_note(); 183 | } 184 | } 185 | 186 | void DFA::deal_with_multiplied_note() 187 | { 188 | current_status = init_status; 189 | char ch; 190 | while (1) 191 | { 192 | ch = cpp_source.get(); 193 | current_status = matrix[current_status][ch]; 194 | if (current_status == dead_status) 195 | { 196 | current_status = matrix[init_status][ch]; 197 | } 198 | else if (current_status == right_note_) 199 | { 200 | break; 201 | } 202 | } 203 | current_status = init_status; 204 | current_string.clear(); 205 | } 206 | 207 | 208 | void DFA::deal_with_line_note() 209 | { 210 | std::getline(cpp_source, std::string()); 211 | current_string.clear(); 212 | current_status = init_status; 213 | } 214 | 215 | void DFA::update_output_sequence() 216 | { 217 | LexicalUnit lexical_unit; 218 | lexical_unit.name = status_to_pattern[current_status]; 219 | lexical_unit.morpheme = current_string; 220 | 221 | if (lexical_unit.name == "BLANK") 222 | { 223 | return; 224 | } 225 | else if (lexical_unit.name.empty()) 226 | { 227 | lexical_unit.name = "WRONG INPUT"; 228 | } 229 | output_sequence.push_back(lexical_unit); 230 | current_status = init_status; 231 | current_string.clear(); 232 | current_string = std::string("1"); 233 | } 234 | 235 | 236 | 237 | void DFA::run() 238 | { 239 | char ch; 240 | while ((ch = cpp_source.get()) != -1) 241 | { 242 | 243 | feed(ch); 244 | } 245 | feed(0); 246 | std::ofstream output("lexical analyzer.txt"); 247 | print_output_sequence(output); 248 | } 249 | 250 | 251 | DFA& DFA::operator<<(std::ifstream& input) 252 | { 253 | char ch; 254 | while ((ch = input.get()) != -1) 255 | { 256 | std::cout << ch; 257 | } 258 | return *this; 259 | } 260 | 261 | void DFA::print_current_string() 262 | { 263 | std::cout << current_string << std::endl; 264 | } 265 | 266 | void DFA::print_output_sequence(std::ostream& output) 267 | { 268 | output.setf(std::ios::left); 269 | output 270 | << std::setw(15) << "Name" 271 | << std::setw(15) << "Morpheme" 272 | << std::endl << std::endl; 273 | 274 | for (int i = 0; i < output_sequence.size(); i++) 275 | { 276 | output 277 | << std::setw(15) << output_sequence[i].name 278 | << std::setw(15) << output_sequence[i].morpheme 279 | << std::endl; 280 | } 281 | } 282 | } 283 | -------------------------------------------------------------------------------- /compiler/intput_and_output.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "SymbolTable.hpp" 12 | namespace hebo 13 | { 14 | typedef struct { 15 | std::string name; 16 | std::string element_type; 17 | std::string pos; 18 | int element_width; 19 | std::vector element_addr; 20 | }array_info; 21 | 22 | class LexicalUnit 23 | { 24 | public: 25 | std::string name; 26 | bool if_action; 27 | int action_num; 28 | std::string morpheme; 29 | struct attribute { 30 | int width; 31 | std::string type; 32 | std::string addr; 33 | int const_value; 34 | 35 | std::string op_value; 36 | bool if_struct; 37 | 38 | array_info array_info; 39 | hbst::StructItem struct_info; 40 | 41 | int param_number; 42 | 43 | int instr; 44 | int next_instr; 45 | int true_instr; 46 | int false_instr; 47 | int con_instr; 48 | int break_instr; 49 | } attribute; 50 | std::vector child_node_list; 51 | LexicalUnit* father; 52 | 53 | LexicalUnit() { 54 | this->if_action = false; 55 | this->action_num = -1; 56 | this->father = NULL; 57 | this->attribute.instr = -1; 58 | this->attribute.next_instr = -1; 59 | this->attribute.true_instr = -1; 60 | this->attribute.false_instr = -1; 61 | this->attribute.con_instr = -1; 62 | this->attribute.break_instr = -1; 63 | this->attribute.if_struct = false; 64 | } 65 | }; 66 | typedef std::string morpheme; 67 | typedef std::string value; 68 | std::string uint2string(unsigned int input); 69 | int string2int(const std::string& input); 70 | class DFA 71 | { 72 | const static int dead_status = 0; 73 | int init_status; 74 | int line__note_; 75 | int left__note_; 76 | int right_note_; 77 | int current_status; 78 | std::string current_string; 79 | 80 | int** matrix; 81 | int row_number; 82 | int column_number; 83 | std::map status_to_pattern;//end status to pattern 84 | // Four data above should be given. 85 | 86 | std::map word_list;//morpheme to value 87 | 88 | std::ifstream cpp_source; 89 | 90 | int current_memory; 91 | public: 92 | DFA(std::string source_file_name, int row_number_ = 10, int column_number_ = 10); 93 | DFA(DFA& input); 94 | DFA(std::string dfa_file_name, std::string source_file_name); 95 | ~DFA(); 96 | std::vector output_sequence; 97 | friend std::ostream& operator<<(std::ostream& my_out, const DFA& dfa); 98 | auto feed(char ch) -> void; 99 | void deal_with_multiplied_note(); 100 | void deal_with_line_note(); 101 | void update_output_sequence(); 102 | void run(); 103 | DFA& operator<<(std::ifstream& input); 104 | void print_current_string(); 105 | void print_output_sequence(std::ostream& output); 106 | }; 107 | } 108 | 109 | -------------------------------------------------------------------------------- /compiler/lexical analyzer.txt: -------------------------------------------------------------------------------- 1 | Name Morpheme 2 | 3 | STRUCT struct 4 | { { 5 | INT int 6 | IDENTIFIER a1 7 | , , 8 | IDENTIFIER a2 9 | ; ; 10 | INT int 11 | IDENTIFIER a3 12 | ; ; 13 | } } 14 | IDENTIFIER b 15 | ; ; 16 | VOID void 17 | IDENTIFIER main 18 | ( ( 19 | ) ) 20 | { { 21 | INT int 22 | IDENTIFIER a 23 | ; ; 24 | IDENTIFIER a 25 | = = 26 | IDENTIFIER input 27 | ( ( 28 | ) ) 29 | ; ; 30 | IDENTIFIER b 31 | . . 32 | IDENTIFIER a1 33 | = = 34 | CONSTANT 1 35 | ; ; 36 | IDENTIFIER b 37 | . . 38 | IDENTIFIER a2 39 | = = 40 | IDENTIFIER b 41 | . . 42 | IDENTIFIER a1 43 | ; ; 44 | IDENTIFIER b 45 | . . 46 | IDENTIFIER a3 47 | = = 48 | IDENTIFIER a 49 | ; ; 50 | IDENTIFIER print 51 | ( ( 52 | IDENTIFIER b 53 | . . 54 | IDENTIFIER a1 55 | ) ) 56 | ; ; 57 | IDENTIFIER print 58 | ( ( 59 | IDENTIFIER b 60 | . . 61 | IDENTIFIER a2 62 | ) ) 63 | ; ; 64 | IDENTIFIER print 65 | ( ( 66 | IDENTIFIER b 67 | . . 68 | IDENTIFIER a3 69 | ) ) 70 | ; ; 71 | } } 72 | -------------------------------------------------------------------------------- /compiler/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "Nfa.h" 4 | #include "Nfa_to_dfa.h" 5 | #include "RegExp.h" 6 | #include "hlhNFA.h" 7 | #include "Min_DFA.cpp" 8 | #include "intput_and_output.hpp" 9 | #include "ContextFreeGrammar.hpp" 10 | #include "GrammerAnalyzer.h" 11 | #include "LR1.h" 12 | #include "AsmGenerator.h" 13 | using namespace std; 14 | // #define GRAMMAR 15 | #define COMPILE_ASM 16 | #define HB 17 | // #define LEX 18 | //#define LYH 19 | 20 | //struct HLH 21 | //{ 22 | // int a; 23 | //}; 24 | // 25 | //struct set_hash 26 | //{ 27 | // size_t operator()(unordered_set input)const 28 | // { 29 | // int result = 0; 30 | // for each (int x in input) 31 | // { 32 | // result += x; 33 | // result = result << 2; 34 | // } 35 | // return result; 36 | // } 37 | //}; 38 | 39 | int main() 40 | { 41 | #ifdef GRAMMAR 42 | cfg::ContextFreeGrammar a; 43 | a.input_productions("../productions.txt"); 44 | a.set_start("argumented_translation_unit"); 45 | a.set_first(); 46 | a.set_follow(); 47 | 48 | cout << "-----------terminals----------" << endl; 49 | for each (auto t in a.terminal_set) { 50 | cout << t->value << endl; 51 | } 52 | cout << "------------------------------" << endl; 53 | 54 | cout << "-----------nonterminals----------" << endl; 55 | for each (auto t in a.nonterminal_set) { 56 | cout << "*** " << t->value << " ***" << endl; 57 | cout << "first set: " << t->start_as_epsilon << endl << t->first_set << endl; 58 | cout << "follow set:" << endl << t->follow_set; 59 | cout << "***********" << endl << endl; 60 | } 61 | cout << "---------------------------------" << endl; 62 | lr::LALR lalr(a); 63 | lalr.get_kernel(); 64 | lalr.get_spontaneous_lookaheads_and_spreading_lookaheads(); 65 | lalr.set_spontaneous_lookaheads(); 66 | lalr.spread_lookaheads(); 67 | lalr.get_full_status_vector(); 68 | lalr.serialize_symbol(); 69 | lalr.make_action_and_go(); 70 | lalr.output(); 71 | system("pause"); 72 | return 0; 73 | #endif // GRAMMAR 74 | 75 | #ifdef LYH 76 | cfg::ContextFreeGrammar a; 77 | a.input_productions("../productions.txt"); 78 | a.set_start("argumented_translation_unit"); 79 | //a.input_productions("../testh.txt"); 80 | //a.set_start("sp"); 81 | a.set_first(); 82 | a.set_follow(); 83 | lr1::LR1ItemSets lr1(a); 84 | lr1.getSets(); 85 | ofstream hlhsb("2018-12-29.txt"); 86 | int i = 0; 87 | for each (auto set in lr1.itemSets) { 88 | hlhsb << "״̬��" << i << endl << *set << endl << endl; 89 | i++; 90 | } 91 | hlhsb << "״̬ \t"; 92 | for each (auto s in lr1.symbols) { 93 | hlhsb << *s << '\t'; 94 | } 95 | hlhsb << endl; 96 | int sts = 0; 97 | for each (auto v in lr1.GO) { 98 | hlhsb << "״̬" << sts << "\t"; 99 | for each (auto n in v) { 100 | hlhsb << n << '\t'; 101 | } 102 | hlhsb << endl; 103 | sts++; 104 | } 105 | hlhsb << endl; 106 | for (int i = 0; i < lr1.productions.size(); i++) 107 | { 108 | hlhsb << i << '\t' << *lr1.productions[i] << endl; 109 | } 110 | //lr1.set_action_and_goto(); 111 | //lr1.output(); 112 | lr1.merge_all(); 113 | lr1.set_action_and_goto(); 114 | lr1.output(); 115 | std::system("pause"); 116 | 117 | #endif // LYH 118 | 119 | 120 | #ifdef HB 121 | 122 | hebo::DFA dfa("ans.txt", "test.c"); 123 | dfa.run(); 124 | GrammerAnalyzer* grammer_analyzer = new GrammerAnalyzer(dfa.output_sequence); 125 | AssemblyGenerator asmgen; 126 | asmgen.global_symbol_table = grammer_analyzer->out_table; 127 | asmgen.function_table = grammer_analyzer->function_table; 128 | asmgen.struct_table = grammer_analyzer->struct_table; 129 | asmgen.final_instruction = &grammer_analyzer->final_instruction; 130 | //asmgen.generate_example(); 131 | asmgen.generate_asm(); 132 | asmgen.output_instructions(); 133 | #ifdef COMPILE_ASM 134 | system("compile_asm.bat"); 135 | #endif // COMPILE_ASM 136 | system("pause"); 137 | return 0; 138 | #endif // HB 139 | 140 | #ifdef LEX 141 | RegExp **exps; 142 | int n = 85; 143 | exps = new RegExp*[n]; 144 | string dig = "\0040\0021\0022\0023\0024\0025\0026\0027\0028\0029\005"; 145 | string ch1 = "\004A\002B\002C\002D\002E\002F\002G\002H\002I\002J\002K\002L\002M\002N\002O\002P\002Q\002R\002S\002T\002U\002V\002W\002X\002Y\002Z"; 146 | string ch2 = "\002a\002b\002c\002d\002e\002f\002g\002h\002i\002j\002k\002l\002m\002n\002o\002p\002q\002r\002s\002t\002u\002v\002w\002x\002y\002z\002_\005"; 147 | string ch = ch1 + ch2; 148 | string data[][2] = { 149 | "int", "INT", 150 | "long", "LONG", 151 | "short", "SHORT", 152 | "float", "FLOAT", 153 | "double", "DOUBLE", 154 | "char", "CHAR", 155 | "unsigned", "UNSIGNED", 156 | "signed", "SIGNED", 157 | "const", "CONST", 158 | "void", "VOID", 159 | "volatile", "VOLATILE", 160 | "enum", "ENUM", 161 | "struct", "STRUCT", 162 | "union", "UNION", 163 | "if", "IF", 164 | "else", "ELSE", 165 | "goto", "GOTO", 166 | "switch", "SWITCH", 167 | "case", "CASE", 168 | "do", "DO", 169 | "while", "WHILE", 170 | "for", "FOR", 171 | "continue", "CONTINUE", 172 | "break", "BREAK", 173 | "return", "RETURN", 174 | "default", "DEFAULT", 175 | "typedef", "TYPEDEF", 176 | "auto", "AUTO", 177 | "register", "REGISTER", 178 | "extern", "EXTERN", 179 | "static", "STATIC", 180 | "sizeof", "SIZEOF", 181 | "+", "+", 182 | "-", "-", 183 | "*", "*", 184 | "/", "/", 185 | "%", "%", 186 | "++", "INC_OP", 187 | "--", "DEC_OP", 188 | "==", "EQ_OP", 189 | "!=", "NE_OP", 190 | "<", "<", 191 | ">", ">", 192 | ">=", "GE_OP", 193 | "<=", "LE_OP", 194 | "&&", "AND_OP", 195 | "||", "OR_OP", 196 | "!", "!", 197 | "&", "&", 198 | "|", "|", 199 | "^", "^", 200 | "<<", "LEFT_OP", 201 | ">>", "RIGHT_OP", 202 | "~", "~", 203 | "=", "=", 204 | "+=", "ADD_ASSIGN", 205 | "-=", "SUB_ASSIGN", 206 | "*=", "MUL_ASSIGN", 207 | "/=", "DIV_ASSIGN", 208 | "%=", "MOD_ASSIGN", 209 | "<<=", "LEFT_ASSIGN", 210 | ">>=", "RIGHT_ASSIGN", 211 | "&=", "AND_ASSIGN", 212 | "^=", "XOR_ASSIGN", 213 | "|=", "OR_ASSIGN", 214 | "?", "?", 215 | ":", ":", 216 | "->", "PTR_OP", 217 | "(", "(", 218 | ")", ")", 219 | "{", "{", 220 | "}", "}", 221 | "[", "[", 222 | "]", "]", 223 | "\"", "\"",// 224 | "'", "'", 225 | "/*", "/*",// 226 | "*/", "*/",// 227 | "//", "//",// 228 | ";", ";", 229 | ",", ",", 230 | ".", ".", 231 | dig + dig + "\001", "CONSTANT", 232 | ch + "\004" + ch + "\002" + dig + "\005\001", "IDENTIFIER", 233 | "\004 \002\t\002\n\005\001", "BLANK"// 234 | }; 235 | string *names = new string[n]; 236 | for (int count = 0; count < n; count++) 237 | { 238 | exps[count] = new RegExp(data[count][0]); 239 | names[count] = data[count][1]; 240 | } 241 | NFA nfa(exps, names, n); 242 | //nfa.print_diagram(); 243 | cout << endl << endl << endl; 244 | Nfa mynfa(nfa); 245 | //for (int i = 0; mynfa.nfa_map[i] != nullptr; i++) { 246 | // for (int j = 0; mynfa.nfa_map[i][j] != nullptr; j++) { 247 | // int f = 0; 248 | // for (int k = 0; mynfa.nfa_map[i][j][k] != -1; k++) { 249 | // cout << i << ", " << j << ": " << mynfa.nfa_map[i][j][k] << " "; 250 | // f = 1; 251 | // } 252 | // if (f == 1) { 253 | // cout << endl; 254 | // } 255 | // } 256 | //} 257 | NfaToDfa ntd(mynfa); 258 | ntd.transform(); 259 | /*for (int i = 0; i < ntd.n_chars; i++) { 260 | for (int j = 0; j < ntd.n_dfa_states; j++) { 261 | cout << ntd.dfa_map[i][j] << " "; 262 | } 263 | cout << endl; 264 | }*/ 265 | Min_DFA mdfa(ntd.dfa_end, ntd.dfa_map, ntd.dfa_s, ntd.n_dfa_states, ntd.n_chars); 266 | system("pause"); 267 | #endif // LEX 268 | 269 | return 0; 270 | } -------------------------------------------------------------------------------- /compiler/python.py: -------------------------------------------------------------------------------- 1 | item_file = open("item.txt") 2 | status_number = int(item_file.readline()) 3 | item_list = [] 4 | for i in range(status_number): 5 | status_order, item_number = (int(x) for x in item_file.readline().strip().split(' ')) 6 | item_dict = dict() 7 | for j in range(item_number): 8 | production = item_file.readline().strip() 9 | item_dict[production] = item_file.readline().strip() 10 | item_file.readline() 11 | item_list.append(item_dict) 12 | print(item_list) -------------------------------------------------------------------------------- /compiler/test.c: -------------------------------------------------------------------------------- 1 | struct { 2 | int a1,a2; 3 | int a3; 4 | }b; 5 | 6 | 7 | void main() { 8 | int a; 9 | a = input(); 10 | b.a1 = 1; 11 | b.a2 = b.a1; 12 | b.a3 = a; 13 | print(b.a1); 14 | print(b.a2); 15 | print(b.a3); 16 | 17 | } -------------------------------------------------------------------------------- /compiler/test1.c: -------------------------------------------------------------------------------- 1 | // void lyh() 2 | // { 3 | // int a; 4 | // a = 1; 5 | // } 6 | 7 | // void hlh(int aa) 8 | // { 9 | // int a[3] = {1, 2, 3}; 10 | // print(a[aa]); 11 | // } 12 | 13 | // void main(){ 14 | // // hlh(1); 15 | // int a[3] = {1,2,3}; 16 | // print(a[1]); 17 | // } 18 | 19 | 20 | void print_plus_1(int puls_num) 21 | { 22 | print(puls_num + 1); 23 | } 24 | 25 | void print_twice(int twice_num) 26 | { 27 | print(twice_num * 2); 28 | } 29 | 30 | void main() 31 | { 32 | int a = 10; 33 | int arr[3] = {1, 2, 3}; 34 | int b = 1; 35 | int i; 36 | 37 | print(arr[2] * 3); 38 | b++; 39 | print(b); 40 | b = input(); 41 | print(b); 42 | 43 | print_plus_1(a + 1); 44 | // print_plus_1(arr[2]); 45 | // print_plus_1(arr[2] + 1); 46 | 47 | // print_plus_1(arr[2] + 1); 48 | // print_plus_1(arr[2] + 1); 49 | // print_plus_1(arr[arr[0]]); 50 | 51 | // print_twice(a + 2); 52 | // print_twice(arr[2] * 3); 53 | // print_twice(a + 1); 54 | 55 | 56 | 57 | // each adjacent 2 lines -> error 58 | // print_twice(a + 2); 59 | // print_twice(arr[2] * 3); 60 | // print_twice(a + 1); 61 | 62 | // print_twice(arr[2]); 63 | // print(get_sign(a)); 64 | // a = -1; 65 | // print(get_sign_simple(a)); 66 | 67 | // print_plus_1(arr[1]); 68 | } 69 | 70 | -------------------------------------------------------------------------------- /compiler/test2.c: -------------------------------------------------------------------------------- 1 | // void lyh() 2 | // { 3 | // int a; 4 | // a = 1; 5 | // } 6 | 7 | // void hlh(int aa) 8 | // { 9 | // int a[3] = {1, 2, 3}; 10 | // print(a[aa]); 11 | // } 12 | 13 | // void main(){ 14 | // // hlh(1); 15 | // int a[3] = {1,2,3}; 16 | // print(a[1]); 17 | // } 18 | 19 | // int get_sign_simple(int a) 20 | // { 21 | // int result; 22 | // if(a > 0) 23 | // { 24 | // result = 1; 25 | // } 26 | // else if(a == 0) 27 | // { 28 | // result = 0; 29 | // } 30 | // else 31 | // { 32 | // result = -1; 33 | // } 34 | // return result; 35 | // } 36 | 37 | // int get_sign(int a) 38 | // { 39 | // if(a > 0) 40 | // { 41 | // return 1; 42 | // } 43 | // else if(a == 0) 44 | // { 45 | // return 0; 46 | // } 47 | // else 48 | // { 49 | // return -1; 50 | // } 51 | // } 52 | 53 | // struct simple_struct 54 | // { 55 | // int key; 56 | // int value; 57 | // } 58 | // simple_object_0; 59 | 60 | // struct simple_struct simple_object_1; 61 | 62 | // struct complex_struct 63 | // { 64 | // int key; 65 | // struct simple_struct value; 66 | // } 67 | // complex_object_0; 68 | 69 | // struct complex_struct complex_object_1; 70 | 71 | 72 | // void print_plus_1(int input); 73 | // void print_twice(int input); 74 | 75 | void print_plus_1(int puls_num) 76 | { 77 | print(puls_num + 1); 78 | } 79 | 80 | // void print_twice(int twice_num) 81 | // { 82 | // print(twice_num * 2); 83 | // } 84 | 85 | void main() 86 | { 87 | int a = 10, c; 88 | int arr[3] = {1, 2, 3}; 89 | int b = 1; 90 | int i; 91 | c = 0; 92 | for(i = 0; i < 10; i++) 93 | { 94 | print(i); 95 | if(i < 5) 96 | { 97 | c = c + 1; 98 | print(a); 99 | } 100 | } 101 | // each adjacent 2 lines -> error 102 | // print_twice(a + 2); 103 | // print_twice(arr[2] * 3); 104 | // print_twice(a + 1); 105 | 106 | // print_twice(arr[2]); 107 | // print(get_sign(a)); 108 | // a = -1; 109 | // print(get_sign_simple(a)); 110 | 111 | // print_plus_1(arr[1]); 112 | } 113 | 114 | -------------------------------------------------------------------------------- /grammar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hlh981029/c-compiler/b7a3afe0b050d92f7b946f64f5a28d8e5e49183c/grammar.jpg -------------------------------------------------------------------------------- /images/grammar_reduce_shift.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hlh981029/c-compiler/b7a3afe0b050d92f7b946f64f5a28d8e5e49183c/images/grammar_reduce_shift.jpg -------------------------------------------------------------------------------- /images/lexical_min_DFA_amount.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hlh981029/c-compiler/b7a3afe0b050d92f7b946f64f5a28d8e5e49183c/images/lexical_min_DFA_amount.jpg -------------------------------------------------------------------------------- /productions.txt: -------------------------------------------------------------------------------- 1 | primary_expression 2 | IDENTIFIER 3 | CONSTANT 4 | ( expression ) 5 | ;; 6 | 7 | postfix_expression 8 | primary_expression 9 | IDENTIFIER [ expression ] 10 | postfix_expression ( ) 11 | postfix_expression ( argument_expression_list ) 12 | IDENTIFIER . IDENTIFIER 13 | postfix_expression INC_OP 14 | postfix_expression DEC_OP 15 | ;; 16 | 17 | argument_expression_list 18 | assignment_expression 19 | argument_expression_list , assignment_expression 20 | ;; 21 | 22 | unary_expression 23 | postfix_expression 24 | INC_OP unary_expression 25 | DEC_OP unary_expression 26 | unary_operator cast_expression 27 | SIZEOF unary_expression 28 | SIZEOF ( type_name ) 29 | ;; 30 | 31 | unary_operator 32 | & 33 | * 34 | + 35 | - 36 | ~ 37 | ! 38 | ;; 39 | 40 | cast_expression 41 | unary_expression 42 | ( type_name ) cast_expression 43 | ;; 44 | 45 | multiplicative_expression 46 | cast_expression 47 | multiplicative_expression * cast_expression 48 | multiplicative_expression / cast_expression 49 | multiplicative_expression % cast_expression 50 | ;; 51 | 52 | additive_expression 53 | multiplicative_expression 54 | additive_expression + multiplicative_expression 55 | additive_expression - multiplicative_expression 56 | ;; 57 | 58 | shift_expression 59 | additive_expression 60 | ;; 61 | 62 | relational_expression 63 | shift_expression 64 | relational_expression < shift_expression 65 | relational_expression > shift_expression 66 | relational_expression LE_OP shift_expression 67 | relational_expression GE_OP shift_expression 68 | ;; 69 | 70 | equality_expression 71 | relational_expression 72 | equality_expression EQ_OP relational_expression 73 | equality_expression NE_OP relational_expression 74 | ;; 75 | 76 | exclusive_or_expression 77 | equality_expression 78 | exclusive_or_expression ^ equality_expression 79 | ;; 80 | 81 | logical_and_expression 82 | exclusive_or_expression 83 | logical_and_expression AND_OP exclusive_or_expression 84 | ;; 85 | 86 | logical_or_expression 87 | logical_and_expression 88 | logical_or_expression OR_OP logical_and_expression 89 | ;; 90 | 91 | assignment_expression 92 | logical_or_expression 93 | unary_expression = assignment_expression 94 | ;; 95 | 96 | expression 97 | assignment_expression 98 | expression , assignment_expression 99 | ;; 100 | 101 | declaration 102 | type_specifier ; 103 | type_specifier init_declarator_list ; 104 | ;; 105 | 106 | init_declarator_list 107 | init_declarator 108 | init_declarator_list , init_declarator 109 | ;; 110 | 111 | init_declarator 112 | declarator 113 | declarator = initializer 114 | ;; 115 | 116 | type_specifier 117 | VOID 118 | INT 119 | struct_or_union_specifier 120 | ;; 121 | 122 | struct_or_union_specifier 123 | STRUCT IDENTIFIER { struct_declaration_list } 124 | STRUCT { struct_declaration_list } 125 | STRUCT IDENTIFIER 126 | ;; 127 | 128 | struct_declaration_list 129 | struct_declaration 130 | struct_declaration_list struct_declaration 131 | ;; 132 | 133 | struct_declaration 134 | type_specifier struct_declarator_list ; 135 | ;; 136 | 137 | struct_declarator_list 138 | declarator 139 | struct_declarator_list , declarator 140 | ;; 141 | 142 | declarator 143 | direct_declarator 144 | ;; 145 | 146 | direct_declarator 147 | IDENTIFIER 148 | ( direct_declarator ) 149 | IDENTIFIER [ assignment_expression ] 150 | direct_declarator ( parameter_list ) 151 | direct_declarator ( ) 152 | ;; 153 | 154 | parameter_list 155 | parameter_declaration 156 | parameter_list , parameter_declaration 157 | ;; 158 | 159 | parameter_declaration 160 | type_specifier declarator 161 | type_specifier 162 | ;; 163 | 164 | type_name 165 | type_specifier 166 | ;; 167 | 168 | initializer 169 | assignment_expression 170 | { initializer_list } 171 | { initializer_list , } 172 | ;; 173 | 174 | initializer_list 175 | assignment_expression 176 | initializer_list , assignment_expression 177 | ;; 178 | 179 | statement 180 | compound_statement 181 | expression_statement 182 | selection_statement 183 | iteration_statement 184 | jump_statement 185 | ;; 186 | 187 | 188 | compound_statement 189 | { } 190 | { statement_list } 191 | { declaration_list } 192 | { declaration_list statement_list } 193 | ;; 194 | 195 | function_compound_statement 196 | { } 197 | { statement_list } 198 | { declaration_list } 199 | { declaration_list statement_list } 200 | ;; 201 | 202 | declaration_list 203 | declaration 204 | declaration_list declaration 205 | ;; 206 | 207 | statement_list 208 | statement 209 | statement_list statement 210 | ;; 211 | 212 | expression_statement 213 | ; 214 | expression ; 215 | ;; 216 | 217 | selection_statement 218 | IF ( expression ) statement 219 | IF ( expression ) statement ELSE statement 220 | SWITCH ( expression ) statement 221 | ;; 222 | 223 | iteration_statement 224 | WHILE ( expression ) statement 225 | FOR ( expression_statement expression_statement ) statement 226 | FOR ( expression_statement expression_statement expression ) statement 227 | ;; 228 | 229 | jump_statement 230 | CONTINUE ; 231 | BREAK ; 232 | RETURN ; 233 | RETURN expression ; 234 | ;; 235 | 236 | translation_unit 237 | external_declaration 238 | translation_unit external_declaration 239 | ;; 240 | 241 | external_declaration 242 | function_definition 243 | declaration 244 | ;; 245 | 246 | function_definition 247 | type_specifier direct_declarator function_compound_statement 248 | ;; 249 | 250 | argumented_translation_unit 251 | translation_unit 252 | ;; -------------------------------------------------------------------------------- /wordlist.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | string dig = "\0040\0021\0022\0023\0024\0025\0026\0027\0028\0029\005"; 3 | string ch1 = "\004A\002B\002C\002D\002E\002F\002G\002H\002I\002J\002K\002L\002M\002N\002O\002P\002Q\002R\002S\002T\002U\002V\002W\002X\002Y\002Z"; 4 | string ch2 = "\002a\002b\002c\002d\002e\002f\002g\002h\002i\002j\002k\002l\002m\002n\002o\002p\002q\002r\002s\002t\002u\002v\002w\002x\002y\002z\002_\005"; 5 | string ch = ch1 + ch2; 6 | string a[][2] = { 7 | "int", "INT", 8 | "long", "LONG", 9 | "short", "SHORT", 10 | "float", "FLOAT", 11 | "double", "DOUBLE", 12 | "char", "CHAR", 13 | "unsigned", "UNSIGNED", 14 | "signed", "SIGNED", 15 | "const", "CONST", 16 | "void", "VOID", 17 | "volatile", "VOLATILE", 18 | "enum", "ENUM", 19 | "struct", "STRUCT", 20 | "union", "UNION", 21 | "if", "IF", 22 | "else", "ELSE", 23 | "goto", "GOTO", 24 | "switch", "SWITCH", 25 | "case", "CASE", 26 | "do", "DO", 27 | "while", "WHILE", 28 | "for", "FOR", 29 | "continue", "CONTINUE", 30 | "break", "BREAK", 31 | "return", "RETURN", 32 | "default", "DEFAULT", 33 | "typedef", "TYPEDEF", 34 | "auto", "AUTO", 35 | "register", "REGISTER", 36 | "extern", "EXTERN", 37 | "static", "STATIC", 38 | "sizeof", "SIZEOF", 39 | "+", "+", 40 | "-", "-", 41 | "*", "*", 42 | "/", "/", 43 | "%", "%", 44 | "++", "++", 45 | "--", "--", 46 | "==", "==", 47 | "!=", "!=", 48 | "<", "<", 49 | ">", ">", 50 | ">=", ">=", 51 | "<=", "<=", 52 | "&&", "&&", 53 | "||", "||", 54 | "!", "!", 55 | "&", "&", 56 | "|", "|", 57 | "^", "^", 58 | "<<", "<<", 59 | ">>", ">>", 60 | "~", "~", 61 | "=", "=", 62 | "+=", "+=", 63 | "-=", "-=", 64 | "*=", "*=", 65 | "/=", "/=", 66 | "%=", "%=", 67 | "<<=", "<<=",// 68 | ">>=", ">>=",// 69 | "&=", "&=",// 70 | "^=", "^=",// 71 | "|=", "|=",// 72 | "?", "?", 73 | ":", ":", 74 | "->", "->", 75 | "(", "(", 76 | ")", ")", 77 | "{", "{", 78 | "}", "}", 79 | "[", "[", 80 | "]", "]", 81 | "\"", "\"", 82 | "'", "'", 83 | "/*", "/*", 84 | "*/", "*/", 85 | "//", "//", 86 | ";", ";", 87 | ",", ",", 88 | ".", ".", 89 | dig + dig + "\001", "NUMBER", 90 | ch + "\004" + ch + "\002" + dig + "\005\001", "ID", 91 | "\004 \002\t\002\n\005\001", "BLANK" 92 | } -------------------------------------------------------------------------------- /三地址代码.txt: -------------------------------------------------------------------------------- 1 | op arg1 arg2 result 说明 2 | 3 | 双目运算指令 4 | + operand1 operand2 result result = operand1 + operand2 5 | - operand1 operand2 result result = operand1 - operand2 6 | * operand1 operand2 result result = operand1 * operand2 7 | / operand1 operand2 result result = operand1 / operand2 8 | % operand1 operand2 result result = operand1 % operand2 9 | ^ operand1 operand2 result result = operand1 ^ operand2 10 | = operand - result result = operand 11 | 12 | 单目运算指令 13 | ++ operand - result result = operand++ 14 | -- operand - result result = operand-- 15 | MINUS operand - result result = -operand 16 | ! operand - result result = !operand 17 | 18 | 数组操作指令 19 | =[] array offset operand operand = array[offset] 20 | []= array offset operand array[offset] = operand 21 | 22 | 跳转指令(line)为跳转到的行号 23 | JMP - - line 无条件跳转 24 | JE operand1 operand2 line operand1等于operand2则跳转 25 | JNE operand1 operand2 line operand1不等于operand2则跳转 26 | JG operand1 operand2 line operand1大于operand2则跳转 27 | JNG operand1 operand2 line operand1不大于operand2则跳转 28 | JGE operand1 operand2 line operand1大于等于operand2则跳转 29 | JNGE operand1 operand2 line operand1不大于等于operand2则跳转 30 | JL operand1 operand2 line operand1小于operand2则跳转 31 | JNL operand1 operand2 line operand1不小于operand2则跳转 32 | JLE operand1 operand2 line operand1小于等于operand2则跳转 33 | JNLE operand1 operand2 line operand1不小于等于operand2则跳转 34 | JZ operand - line operand为假则跳转 35 | JNZ operand - line operand为真则跳转 36 | 37 | 函数调用指令 38 | PARAM argument - - 将argument添加到参数列表 39 | CALL name - - 调用名为name的函数 40 | 41 | 函数定义指令 42 | FUNC name - - 定义一个为name的函数 43 | ENDF name - - 结束定义一个为name的函数 44 | RET argument - - 终止函数,返回值为argument(可为空) 45 | 46 | 空指令 47 | NULL - - - 不生成任何指令 --------------------------------------------------------------------------------