当前位置:   article > 正文

编译原理学习笔记(二)翻译程序的实现_翻译程序实现逻辑

翻译程序实现逻辑

上一节所学的主要是语法到语义的内容,通过手动构造语法树来理解编译过程。
在3.5节,书中给出了后缀表达式翻译程序的java实现。根据前面的内容,今天对NC代码编译给出简易的实现。

在实现前,需要几个准备内容用以简化代码:
1. 正则表达式
正则表达式能够对一个字符串进行模式匹配,可以对符合模式的字符串进行检索、替换。
2. 宏
c++中使用宏可以对代码进行批量预处理,对于某些重复的代码可以用宏进行代替。
3. 哈希表

在得到一行代码后,需要对其词法单元进行读入,书中使用的是一个单字符lookahead。这里也使用lookahead,但是每次读入的一个字符串,因为NC代码每个部分都是空格隔开的。
对于每个字符串(即词法单元),都要进行模式判断检查语法是否正确(match),这里需要用到正则表达式,然后用对应的函数进行处理,处理对象过多且代码单一则需要用到宏。
在书中提到,抽象语法树的结点是程序,对应于分析树的非终结符。即是说每个非终结符对应一个函数,用以执行对应的内容。

词法匹配部分如下:


class regs{
    map<string, regex> mesh;
    smatch m;
    string temp;
public:
    regs(string file){//从文件读正则表达式
        ifstream fin(file);
        string str1,str2;
        while (!fin.eof()){
            fin >> str1 >> str2;
            mesh[str1] = regex(str2);
        }
    }
    int match(string pat,string str){//用非终结符pat代表的结构匹配str
        temp = str;//必须用temp暂存str 否则会丢失匹配信息
        if (mesh.find(pat)!=mesh.end()){
            auto pp = mesh[pat];
            if (!regex_match(temp, pp))return -1;
            regex_search(temp, m, pp);
            if (m.size() >= 0){
                return m.position();
            }
        }
        return -1;
    }
    string match_result(){//获取上次匹配的结果(仅限有分组)
        return m[1].str();//*!这里需要扩展
    }
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

这个类的使用方法是,构造时传入文件名,文件中内容是非终结符和其模式的正则表达式。它以非终结符名作为关键字、正则表达式作为值,构造一个哈希表,用以查询。

翻译器主体如下:


class NCpaser{//手工编写
    string cur;
    regs pattern;
    char code_type;
    string lookahead;
public:
    NCpaser():pattern("NC\\regs.txt"){//初始化哈希表
        ;
    }
    //非终结符列表:stmt id G X Y Z M S T F 
    void _stmt(){//检验基本语法
        if (pattern.match("stmt", cur)>=0){
            cur = pattern.match_result();
        }
        else{
            ;//报错
        }
        string temp = cur;
        istringstream strin(temp);
        while (strin >> lookahead){
#define stmt_pat(s)if (pattern.match(#s, lookahead) >= 0){\
                cur = pattern.match_result();\
                _##s();\
            }
            stmt_pat(G)else
            stmt_pat(M)else
            stmt_pat(X)else
            stmt_pat(Y)else
            stmt_pat(Z)else
            stmt_pat(S)else
            stmt_pat(T)else
            stmt_pat(F)

        }

    }
    void _N(){
        ;
    }
    void _G(){
        cout << "执行G指令" << cur << endl;
    }
    void _M(){
        cout << "执行M指令" << cur << endl;
    }
    void _X(){
        cout << "X轴方向" << cur << endl;
    }
    void _Y(){
        cout << "Y轴方向" << cur << endl;
    }
    void _Z(){
        cout << "Z轴方向" << cur << endl;
    }
    void _S(){
        cout << "主轴转速:" << cur << endl;
    }
    void _T(){
        cout << "刀号:" << cur << endl;
    }
    void _F(){
        cout << "进给量:" << cur << endl;
    }


    void compile(string filename){
        ifstream fin(filename);

        //预处理,暂空

        char buf[512];
        ;//按行读取
        while (fin.getline(buf, 512)){
            cur = string(buf);
            _stmt();
        }

    }

};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81

正则表达式文件regs.txt内容:
stmt N[0-9]+(.*);
N N([0-9]+)
G G([0-9]+)
M M([0-9]+)
T T([0-9]+)
F F([0-9]+)
S S([0-9]+)
X X([+-]?[0-9]+)
Y Y([+-]?[0-9]+)
Z Z([+-]?[0-9]+)

输入code.txt文件内容:
N001 G01 X-100 Y20 Z+35 M03 S40 T50 F40;
N002 G01 X35 Y-29 Z30 M03 S40 T50 F40;
运行结果:
这里写图片描述

总结:这个简易程序主要给出了简单NC语法的翻译,而且在某种意义上并没有实现上一节构造的语法树,因为这里使用了regex库作为辅助。这里的语义动作是输出显示,相当于直接运行代码。事实上代码必须经过语法检验,像之前一篇文章中提到的(http://blog.csdn.net/u011602557/article/details/66979730),指令间存在互斥性,也没有表现出这个语法。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/秋刀鱼在做梦/article/detail/855891
推荐阅读
相关标签
  

闽ICP备14008679号