\documentclass[../main.tex]{subfiles}

\begin{document}
\section{课程设计总结}

% 1) 体会/收获（每个成员完成的工作、收获等）
% 2) 设计过程中遇到或存在的主要问题及解决方案
% 3) 改进建议

\subsection{成员分工}

\begin{table}[htbp]
    \centering
    \begin{tabular}{|l|l|}
        \hline
        \textbf{姓名} & \textbf{分工} \\
        \hline
        任昌骏 & 组长，主持开发工作，负责编译器的总体设计 \\
        \hline
        张弈纶 & 负责语法分析和类型检查部分的开发，前端界面的搭建 \\
        \hline
        兰建国 & 类型系统、符号表和代码生成部分的开发 \\
        \hline
        肖可扬 & 词法令牌、词法分析器的设计与实现 \\
        \hline
        杜含韵 & 词法分析和语法分析单元测试的编写 \\
        \hline
        陈劲淞 & 撰写课程设计文档 \\
        \hline
    \end{tabular}
    \caption{成员分工表}
    \label{tab:my_label}
\end{table}

\subsection{体会与收获}

\subsubsection{张弈纶}

这次课设我主要负责语法的定义引入、语义分析中代码类型检查和前端可视化落地。上学期我仅仅是完成了课程要求的词法分析和语法分析实验，对语义分析和其中的代码类型检查部分没有实际的了解。通过这次课程设计，我充分理解了代码类型检查的必要性和其实际运作流程。并且，我通过这次的编码了解了c\#访问者模式和事件机制的使用，对我来说是一次开阔眼界的过程，收获颇多。

编码过程中，我经历了多次代码重构和迭代更新，这让我充分认识到代码质量对编码效率的影响。同时，对于一些代码设计，也重复验证了很多次。这给我很深的体会，在今后的程序设计中要做好规划，提高代码的鲁棒性与可读性。

这次课设还让我培养了一定的文献调查能力。对于语法树的绘制，我参考了相关论文并进行了复现，这也让我锻炼了论文的调研能力。同时，这次课设也让我加深了团队合作的精神，培养了团结协作的能力。

\subsubsection{兰建国}

本次课程设计我主要负责代码生成部分，在此过程中我学到了很多。首先我对代码生成的过程有了更深入的理解。在一开始，我以为代码生成就是机械地将Pascal-S代码翻译到C语言代码，但是在动手编码之后发现困难重重。在经过几次代码重构和迭代之后，我反应过来发现是设计方面的缺陷。在开始的设计中，我采取的是一种"遍历到哪，翻译到哪"的设计。但实际上应该在语法树上收集够了相应信息之后才进行代码的生成。其次，我体会到了三地址代码的便捷性。在引入三地址代码之前，很多语句的代码生成很难进行，在引入三地址代码之后，代码生成的过程也更加清晰，程序的可扩展性也大大增加。此外，我还感受到了在开发过程的不稳定性，在实际开发过程中，设计方案需要不断调整，以适应各种变化。最后，此次课设还让我感受到了团队交流的重要性，通过在发现问题时及时沟通，提高了我们的开发效率。

\subsubsection{任昌骏}

在这次的课程设计中我有幸担任组长，负责整个编译器的总体设计。站在现在的角度上看来，当时选择整个编译器的设计和实现不依赖与传统的工具而是完全手动实现是非常冒险的，并且在语言选型方面也非常的``激进''。所幸在全组同学的通力配合以及王老师和助教同学的大力支持下顺利完成了。

这次的课程设计也算是我个人能力上的一次突破。在以往的项目经历中，很少有像``设计一个编译器''这样一个在算法设计和软件设计上都非常具有挑战性的课题。也正是有了这个机会，使我得以将过去几年学到的各种知识和技能融会贯通，无论是按照编译课本上的描述实现词法分析和语法分析的相关算法，还是考古论文实现树的可视化绘制都是对于我算法能力的考验；亦或是使用访问者模式在语法树节点上扩展各种功能，还是通过事件的机制抽象同一个语法树节点可能使用的多个不同的生成式，都是对我软件工程能力的挑战。而且，编译原理课程设计作为大学少数几门要求由5至7人协作完成的课程设计也进一步锻炼了我组织小组合作的能力。无论是复杂项目的\texttt{Git}管理还是使用\texttt{CI/CD}实现持续测试和快速部署，都是我在个人项目之中难以接触到的东西。

最后还是非常感谢老师和各位同学能给我这样一个锻炼自己和提高自己的机会，在未来我一定认真复盘这次课程设计中的得与失，进一步的提高自己的个人能力。

\subsubsection{肖可扬}

这次课设我主要负责词法分析器的编写，在上学期实验的基础上，此次课设的词法分析器更接近真实场景，需要处理更多与Pascal语法特性相关的内容，所以在前期调研方面我们首先形成了翻译表，在这个过程中我感受到了明确需求的重要性。此外，这是我第一次使用C\#在纯代码环境中开发软件，和小组同学学习到了许多工具的使用、软件的组织架构以及代码编写规范等内容；在重构自己的代码的过程中，我更好地理解和掌握了面向对象的相关语法以及设计模式。同时，和负责测试的同学进行交流也是宝贵的经验，我意识到了自己在编程方面的严谨性还有待提高，需要更系统地全面地考虑输入的各种情况。在编写程序过程中，我明白了团队交流的意义，在编译的不同流程之间确定接口以及对特殊问题的配合处理需要团队紧密讨论、通力协作，才能提高代码的效率。

\subsubsection{杜含韵}

本次课程设计我主要参与了单元测试的部分编写，并在此过程中受益良多。首先是通过此次项目，我熟悉了C\#语言特性与.NET框架，纠正了先前对git的错误使用，帮助拓宽了我的技术认知与技术组成。其次是对Xunit测试框架的熟练使用也使得我在本学期其他课程中操作实践。最后是作为对上学期编译原理理论课程延申而出的课程设计，帮助我学会如何将理论转化为实践，以及如何克服实践的具体困难。同时，我还认识到了测试的编写需要更为明确的对组件任务的了解和认知，需要从宏观角度上思考测试的方向和方法，组内同学的实践也让我了解到测试载体的多样化。而头歌平台测试集对边界情况的探索也帮助我认识到在思考的完善性上有着诸多不足。最后，我最为感激的是组内同学的通力配合和辛苦付出，他们在我遇到困难时的耐心解答与帮助使得我受益匪浅。此次学习实践经验也将助力我日后的学习生活行稳致远。

\subsubsection{陈劲淞}

在本次课程设计中，我主要负责撰写项目的文档。这不仅仅包括项目的设计文档，还有整个开发过程的文档记录和最终的报告。通过这个过程，我深刻理解到了文档在软件开发过程中的重要性。良好的文档不仅可以帮助团队成员理解和维护代码，还可以为未来的开发提供参考。

首先，我学习并实践了如何使用\LaTeX 来创建专业的文档。这包括了解其基本语法、文档结构组织、图表和代码的插入等。这些技能的获得，让我在未来的学术写作和报告制作中更加得心应手。

其次，团队在开发过程中采用Docker容器化技术，这极大地提高了开发环境的一致性和项目的可移植性。通过Docker，我们能够确保每个团队成员都在相同的环境中开发和测试，减少了环境差异带来的问题。我在文档中详细记录了如何使用Docker来配置和管理我们的开发环境，这对于团队成员理解整个系统的部署和运行至关重要。

同时，本项目中使用Git进行版本控制和团队协作，我负责记录各个分支的合并和版本发布的详细过程，确保所有团队成员都能迅速地获取最新的项目状态和历史修改记录。这不仅提高了团队的工作效率，也增强了项目的可追溯性。

在编译原理中，词法分析、语法分析和语义分析是构建编译器的重要步骤。在本次课程设计中，我们团队的工作涉及到了这些方面，我作为文档撰写者也深刻地参与其中并从中受益匪浅。通过撰写文档的过程，我加深了对整个项目的理解，提高了与团队成员的交流合作能力，并锻炼了自己的表达和文字组织能力。

此外，我参与了单元测试和集成测试的文档撰写，记录了测试策略和测试结果。通过Xunit框架进行单元测试，以及使用Jenkins进行持续集成，我们能够及时发现并解决开发过程中出现的问题，保证软件质量。这一过程不仅加深了我对测试理论的理解，也提升了我在实际项目中应用测试的能力。

最后，通过这次经验，我认识到了持续学习和自我提升的重要性。未来，我希望能继续提高我的专业技能，尤其是在技术写作和项目管理方面，以便在未来的职业生涯中更好地服务于团队和项目。

\subsection{设计中的主要问题和解决方案}

\paragraph{生成LR(1)分析表耗时较长}
 在编译的过程中，从原始的语法生成对应的LR(1)分析表是一个时间复杂度较大的工作。经过实际测试，生成本课程设计中需要支持的基础语法对应的分析表就需要大约7秒至10秒的时间。

\textbf{解决方案}: 将生成好的LR(1)分析表以C\#源代码的形式直接输出，再打包编译到程序中。在输入的Pasccal语法没有变化的情况下不用重复的生成相同的分析表。

\paragraph{语法树的访问者和类型检测访问者}
在编译过程中，管理和遍历语法树对于进行有效的类型检查和语义分析至关重要。传统的遍历方法可能导致代码重复，难以维护，且使用递归进行遍历还可能因为递归深度过深而造成占空间耗尽的运行时错误。

\textbf{解决方案}: 采用访问者设计模式（Visitor Pattern）来分离数据结构和操作。这使得在不修改语法树结构的情况下，添加新的操作变得简单，提高了代码的可维护性和扩展性。对于类型检测，定义一个专门的类型检测访问者，该访问者遍历语法树并对每个节点进行类型验证。

\paragraph{语法中的左递归难以进行类型检查}
在原始需求文档中给定的Pascal语法中存在的大量左递归，使得我们在进行语义分析时很难设计出S-属性的翻译方案。

\textbf{解决方案}: 改写文法，消除文法中的左递归，详解\ref{pascal_grammar}节中给出的对应语法和修改说明。

\paragraph{代码生成中涉及的各种困难}
在初始设计面向C语言的代码生成时，在翻译循环语句和函数调用语句时遇到了很大的困难，因为初始化仍然采用一对一的翻译思想，试图将Pascal中的每一个语法结构都翻译到一个对应的语法结构。

\textbf{解决方案}: 借鉴三地址代码，将翻译思想设计为翻译到一种使用C语言书写的三地址代码，并且大量的使用\texttt{goto}语句和标签，成功地解决了上述问题。

\subsection{改进建议}

\paragraph{提供更为详尽的报错信息} 目前语法分析的报错系统仍然十分的不人性化，仅仅输出了编译器此时希望输入什么样的词法记号。

\paragraph{进行代码优化} 因为在进行代码生成时使用率类似于三地址代码的代码生成形式，因此在进行代码生成会生成大量的冗余变量，造成程序的编译时间和运行占用的内存空间都非常大。


\end{document}