├── .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