zoukankan      html  css  js  c++  java
  • 一个编译器的实现1——开篇

    一直就想弄懂编译原理,弄明白编译器是怎么工作的。

    学了编译原理的课,只理解到了语法分析,后面的理解就无法再在想象中完成了。

    于是想做一个编译器。虽然书上把编译原理讲的那么深奥难懂,但是说穿了,编译器也只不过是几个算法而已。书也有,编程也学了,算法现成的,写个编译器,有什么难的呢。就这么愉快的决定了~

    目标确定为:写个C语言的编译器,包括词法分析、语法分析、语义分析、中间代码生成,代码优化。如果心情好,就写写生成最终可执行程序那部分。这是主要目标,另外我希望这个编译器工程的代码具有可扩展性,就是得能够比较方便的修改为各种语言的编译器。

    首先要确定数据结构。

    源代码,用字符串就可以了。

    源代码经过词法分析器(LexicalAnalyzer),得到单词流。“流”这个概念太玄幻,其实就是单词的列表(TokenList),一个数组或者链表而已。

    单词列表经过语法分析器(SyntaxParser)的分析,得到语法树(SyntaxTree),语法树是用树状的数据结构表示程序的方式。

    语法树再经过语义分析,就得到了信息更加丰富的语法树,之后就可以据此生成中间代码或其它想要的东西了。

    中间代码生成可执行程序的部分,我先不考虑写,因为不是很感兴趣,都是一些零零散散的东西,形式化程度不强。

    那么基本的数据结构就有了:词法分析器;单词列表;语法分析器;语法树。

    为了更具可扩展性和灵活性,我设计了如下的接口和类来实现上述数据结构。

    词法分析器接口
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace SmileWei.Compiler.MiddleData
    {
    /// <summary>
    /// 词法分析器接口
    /// <para>编写自己的词法分析器并实现此接口,可立即使用本系列产品的其他功能,如实时词法分析器</para>
    /// </summary>
    /// <typeparam name="TEnumTokenType">单词的枚举类型</typeparam>
    public interface ILexicalAnalyzer<TEnumTokenType>
    where TEnumTokenType : struct, IComparable, IFormattable, IConvertible
    {
    /// <summary>
    /// 要分析的源代码
    /// </summary>
    string SourceCode { get; set; }
    /// <summary>
    /// 分析源代码获得Token序列
    /// <para>分析之前会重置词法分析器到初始状态</para>
    /// </summary>
    /// <returns></returns>
    TokenList<TEnumTokenType> Analyze();
    /// <summary>
    /// 分析源代码获得Token序列
    /// <para>当得到maxTokenCount数目的Token时(或源代码分析完毕时)返回</para>
    /// </summary>
    /// <param name="maxTokenCount">应分析得到的Token数目最大值</param>
    /// <returns></returns>
    TokenList<TEnumTokenType> Analyze(int maxTokenCount);
    /// <summary>
    /// 重置此词法分析器,这样就可以开始分析新的源代码
    /// <para>重置的目的是保证Token的行、列数正确</para>
    /// </summary>
    void Reset();
    }
    }
    单词列表
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Text;
    using System.Xml.Linq;

    namespace SmileWei.Compiler.MiddleData
    {
    /// <summary>
    /// Description of TokenList.
    /// </summary>
    /// <typeparam name="TEnumTokenType">单词的枚举类型</typeparam>
    public class TokenList<TEnumTokenType> : List<Token<TEnumTokenType>>
    where TEnumTokenType : struct, IComparable, IFormattable, IConvertible
    {
    }
    }
    单词
    using System;
    using System.Xml.Linq;

    namespace SmileWei.Compiler.MiddleData
    {
    /// <summary>
    /// 单词,即词法分析器输出列表的元素
    /// </summary>
    /// <typeparam name="TEnumTokenType">单词的枚举类型</typeparam>
    public class Token<TEnumTokenType>
    where TEnumTokenType : struct, IComparable, IFormattable, IConvertible
    {
    /// <summary>
    /// 单词类型
    /// </summary>
    public TEnumTokenType TokenType { get; set; }
    /// <summary>
    /// 具体信息
    /// </summary>
    public string Detail { get; set; }
    /// <summary>
    /// 备注说明,一般在LexicalError为true的时候不为空
    /// </summary>
    public string Tag { get; set; }
    /// <summary>
    /// 标识是否是正确的单词
    /// </summary>
    public bool LexicalError { get; set; }
    /// <summary>
    /// 所在行(从0开始)
    /// </summary>
    public int Line { get; set; }
    /// <summary>
    /// 所在列(从0开始)
    /// </summary>
    public int Column { get; set; }
    /// <summary>
    /// 第一个字符在源代码字符串中的索引
    /// </summary>
    public int IndexOfSourceCode { get; set; }
    /// <summary>
    /// 单词长度(字符个数)
    /// </summary>
    public int Length { get; set; }
    /// <summary>
    /// 创建一个单词
    /// </summary>
    public Token()
    {
    TokenType = default(TEnumTokenType);
    Detail = string.Empty;
    LexicalError = false;
    Tag = string.Empty;
    }
    /// <summary>
    /// 显示[具体信息]$[单词类型]$[行数]$[列数]$[是否是正确的单词]$[备注说明]
    /// </summary>
    /// <returns></returns>
    public override string ToString()
    {
    return string.Format("[{0}]$[{1}]$[{2},{3}]$[{4}]$[{5}]"
    , Detail.ToString().Replace("\r\n", "$").Replace('\r', '$').Replace('\n', '$')
    , TokenType, Line, Column, LexicalError
    , Tag.Replace("\r\n", "$").Replace('\r', '$').Replace('\n', '$'));
    }


    /// <summary>
    /// 检验两个单词是否一样
    /// </summary>
    /// <param name="tk"></param>
    /// <returns></returns>
    public bool SameWith(Token<TEnumTokenType> tk)
    {
    if (tk == null) return false;
    if (this.Column != tk.Column) return false;
    if (this.Detail != tk.Detail) return false;
    if (this.IndexOfSourceCode != tk.IndexOfSourceCode) return false;
    if (this.Length != tk.Length) return false;
    if (this.LexicalError != tk.LexicalError) return false;
    if (this.Line != tk.Line) return false;
    if (this.Tag != tk.Tag) return false;
    if (this.TokenType.CompareTo(tk.TokenType) != 0) return false;
    return true;
    }

    }
    }
    语法分析器接口
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace SmileWei.Compiler.MiddleData
    {
    /// <summary>
    /// 语法分析器接口
    /// <para>编写自己的语法分析器并实现此接口,可立即使用本系列产品的其他功能,如直接处理词法分析器的输出</para>
    /// </summary>
    /// <typeparam name="TEnumTokenType">单词的枚举类型</typeparam>
    /// <typeparam name="TEnumVType">语法分析中的结点类型(某Vn or 某Vt),建议使用枚举类型</typeparam>
    public interface ISyntaxParser<TEnumTokenType, TEnumVType, TTreeNodeValue>
    where TEnumTokenType : struct, IComparable, IFormattable, IConvertible
    where TEnumVType : struct, IComparable, IFormattable, IConvertible
    where TTreeNodeValue : class, new()
    {
    /// <summary>
    /// 要分析的单词列表
    /// </summary>
    TokenList<TEnumTokenType> TokenListSource { get; set; }
    /// <summary>
    /// 分析TokenListSource获得语法树
    /// <para>分析之前会重置词法分析器到初始状态</para>
    /// </summary>
    /// <returns></returns>
    SyntaxTree<TEnumTokenType, TEnumVType, TTreeNodeValue> Parse();
    /// <summary>
    /// 重置此语法分析器,这样就可以重新分析
    /// <para>重置的目的是保证语法分析器内部TokenListSource的索引指针回到第一个Token的位置</para>
    /// </summary>
    void Reset();
    /// <summary>
    /// 获取源代码的规范格式
    /// </summary>
    /// <returns></returns>
    string GetFormattedSourceCode();
    /// <summary>
    /// 获取源代码的规范格式
    /// </summary>
    /// <returns></returns>
    string GetFormattedSourceCode(SyntaxTree<TEnumTokenType, TEnumVType, TTreeNodeValue> tree);
    }
    }
    语法树
    using System;
    using System.Collections.Generic;

    namespace SmileWei.Compiler.MiddleData
    {
    /// <summary>
    /// Description of SyntaxTreeGeneric.
    /// </summary>
    /// <typeparam name="TEnumTokenType">单词的枚举类型</typeparam>
    /// <typeparam name="TEnumVType">语法分析中的结点类型(某Vn or 某Vt),建议使用枚举类型</typeparam>
    /// <typeparam name="TTreeNodeValue">语法树结点值,根据语音特性自定义类型进行填充</typeparam>
    public class SyntaxTree<TEnumTokenType, TEnumVType, TTreeNodeValue>
    where TEnumTokenType : struct, IComparable, IFormattable, IConvertible
    where TEnumVType : struct, IComparable, IFormattable, IConvertible
    where TTreeNodeValue : class, new()
    {

    #region 字段和属性
    /// <summary>
    /// 产生此语法树所直接调用的候选式
    /// </summary>
    protected Func<SyntaxTree<TEnumTokenType, TEnumVType, TTreeNodeValue>, SyntaxTree<TEnumTokenType, TEnumVType, TTreeNodeValue>> m_CandidateFunc;
    /// <summary>
    /// 产生此语法树所直接调用的候选式
    /// </summary>
    public Func<SyntaxTree<TEnumTokenType, TEnumVType, TTreeNodeValue>, SyntaxTree<TEnumTokenType, TEnumVType, TTreeNodeValue>> CandidateFunc
    {
    get { return m_CandidateFunc; }
    set { m_CandidateFunc = value; }
    }
    private int m_MappedTokenStartIndex = 0;
    /// <summary>
    /// 对应的第一个单词
    /// </summary>
    public int MappedTokenStartIndex
    {
    get { return m_MappedTokenStartIndex; }
    set { m_MappedTokenStartIndex = value; }
    }
    private int m_MappedTokenLength = 0;
    /// <summary>
    /// 对应的单词数目
    /// </summary>
    public int MappedTokenLength
    {
    get { return m_MappedTokenLength; }
    set { m_MappedTokenLength = value; }
    }

    /// <summary>
    /// 对应的单词列表
    /// </summary>
    public TokenList<TEnumTokenType> GetMappedTokenList()
    {
    var result = new TokenList<TEnumTokenType>();
    if (MappedTotalTokenList != null && MappedTotalTokenList.Count > 0)
    {
    if (MappedTokenLength > 0)
    {
    for (int i = 0, j = MappedTokenStartIndex; i < MappedTokenLength; i++, j++)
    {
    result.Add(MappedTotalTokenList[j]);
    }
    }
    }
    return result;
    }
    private TokenList<TEnumTokenType> m_MappedTotalTokenList = new TokenList<TEnumTokenType>();
    /// <summary>
    /// 整个语法树对应的单词列表
    /// </summary>
    public TokenList<TEnumTokenType> MappedTotalTokenList
    {
    get { return m_MappedTotalTokenList; }
    set { m_MappedTotalTokenList = value; }
    }
    private string m_Tag = string.Empty;
    /// <summary>
    /// 标记,若发生语法错误,应在此说明
    /// </summary>
    public string Tag
    {
    get { return m_Tag; }
    set { m_Tag = value; }
    }
    private bool m_SyntaxError = false;
    /// <summary>
    /// 是否有语法错误
    /// </summary>
    public bool SyntaxError
    {
    get { return m_SyntaxError; }
    set { m_SyntaxError = value; }
    }
    /// <summary>
    /// 此结点的值
    /// </summary>
    private TTreeNodeValue m_NodeValue = new TTreeNodeValue();
    /// <summary>
    /// 此结点的值
    /// </summary>
    public TTreeNodeValue NodeValue
    {
    get { return m_NodeValue; }
    set { m_NodeValue = value; }
    }
    private SyntaxTreeList<TEnumTokenType, TEnumVType, TTreeNodeValue> m_Children = new SyntaxTreeList<TEnumTokenType, TEnumVType, TTreeNodeValue>();
    /// <summary>
    /// 子结点
    /// </summary>
    public SyntaxTreeList<TEnumTokenType, TEnumVType, TTreeNodeValue> Children
    {
    get { return m_Children; }
    set { m_Children = value; }
    }
    private SyntaxTree<TEnumTokenType, TEnumVType, TTreeNodeValue> m_Parent = null;
    /// <summary>
    /// 父结点
    /// </summary>
    public SyntaxTree<TEnumTokenType, TEnumVType, TTreeNodeValue> Parent
    {
    get { return m_Parent; }
    set { m_Parent = value; }
    }
    #endregion 字段和属性

    }
    }






     

  • 相关阅读:
    Gist
    Gist
    Gist
    汉字编码与其16进制对照
    Horizon组件安装详解
    Github目录生成器
    MVC模式网站编写经验总结
    Java多线程小结
    JGit与远程仓库链接使用的两种验证方式(ssh和https)
    Peterson算法与Dekker算法解析
  • 原文地址:https://www.cnblogs.com/bitzhuwei/p/compiler_basic_data_structure.html
Copyright © 2011-2022 走看看