编译原理课程设计(四)
以下是全流程步骤:
1. 创建项目目录:
在你选择的位置创建一个新目录,例如 SimpleCompiler
。
mkdir SimpleCompiler cd SimpleCompiler
|
2. 创建 Lex 文件:
在项目目录中创建 lex.l
文件,将下面的内容复制到文件中。
%{ #include "main.h" #include "yacc.tab.h" extern "C" { int yylval; } %}
%% [ \t\n] ; // Skip whitespace [a-zA-Z][a-zA-Z0-9]* { yylval = strdup(yytext); return IDENTIFIER; } := return ASSIGN; [0-9]+ { yylval = atoi(yytext); return INTEGER; } \; return SEMICOLON; \. return PERIOD; . ; %%
|
3. 创建 Yacc 文件:
在项目目录中创建 yacc.y
文件,将下面的内容复制到文件中。
%{ #include "main.h" #include <iostream> #include <vector>
std::vector<std::string> variables; // 保存变量信息
extern "C" { int yylex(); void yyerror(const char* s); }
%union { int intval; char* strval; }
%token <intval> INTEGER %token <strval> IDENTIFIER %token ASSIGN SEMICOLON PERIOD
%start program
%%
program: block PERIOD { printf("Compilation successful!\n"); exit(0); }
block: BEGIN statement_list END { printf("Executing program...\n"); }
statement_list: statement { printf("Statement executed\n"); } | statement_list SEMICOLON statement { printf("Statement executed\n"); }
statement: assignment { printf("Assignment statement\n"); }
assignment: IDENTIFIER ASSIGN expression { // 生成赋值代码 printf("%s = %d;\n", $1, $3); }
expression: INTEGER { $$ = $1; } | IDENTIFIER { // 在表达式中使用变量,保存变量信息 variables.push_back($1); $$ = lookup_variable($1); }
%%
int lookup_variable(const char* var) { // Dummy implementation for variable lookup printf("Looking up variable %s\n", var); return 0; }
int main() { printf("Simple Pascal Compiler\n"); yyparse();
// 打印变量信息 printf("Variables used in the program:\n"); for (const std::string& var : variables) { printf("%s\n", var.c_str()); }
return 0; }
|
4. 创建主文件:
在项目目录中创建 main.cpp
文件,将下面的内容复制到文件中。
#include <cstdio> #include "main.h" extern "C" { int yylex(); int yyparse(); }
int main() { printf("Simple Pascal Compiler\n"); yyparse(); return 0; }
|
5. 创建头文件:
在项目目录中创建 main.h
文件,将下面的内容复制到文件中。
#ifndef MAIN_HPP #define MAIN_HPP
#include <cstdlib>
#define YYSTYPE Type
struct Type { int intval; char* strval; };
#endif
|
6. 创建 CMakeLists.txt 文件:
在项目目录中创建 CMakeLists.txt
文件,将下面的内容复制到文件中。
cmake_minimum_required(VERSION 3.10)
project(SimpleCompiler)
find_package(FLEX REQUIRED) find_package(BISON REQUIRED)
FLEX_TARGET(MyScanner lex.l ${CMAKE_CURRENT_BINARY_DIR}/lex.yy.c) BISON_TARGET(MyParser yacc.y ${CMAKE_CURRENT_BINARY_DIR}/y.tab.c)
ADD_FLEX_BISON_DEPENDENCY(MyScanner MyParser)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
add_executable(simple_compiler main.cpp ${FLEX_MyScanner_OUTPUTS} ${BISON_MyParser_OUTPUTS})
|
7. 构建项目:
打开终端,进入项目目录,然后运行以下命令构建项目。
mkdir build cd build cmake .. make
|
这将在 build
文件夹中生成一个名为 simple_compiler
的可执行文件。
8. 运行编译器:
在终端中,你可以使用以下命令运行生成的编译器,并将 Pascal 代码作为输入。
编译器会提示 “Simple Pascal Compiler”,然后等待输入。你可以输入Pascal代码并按Ctrl+D结束输入。
请注意,由于我们的示例编译器没有实际的代码生成,它只输出一些信息以演示流程。在实际编译器中,你需要更多的规则来覆盖Pascal语言的其他方面,并生成实际的目标代码。