自制编译器---c++实现词法分析器

Posted yqtaowhu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自制编译器---c++实现词法分析器相关的知识,希望对你有一定的参考价值。

一直想写一个编译器,在csdn上看到tyler_download网友用Java写的编译器,自己也有所启发,非常感谢他的分享,但是,感觉他的词法分析函数的调用过多,感觉很是不习惯,同时还很复杂,自己是学c/c++的,因此想用c++编写一个编译器。
在这个过程中,其中对我帮助最大的是一个外国的网友,虽然不知道他的名字,但是还是要感谢他。。。。

词法单元词法解析器在编译器中的作用,是将输入流解析为一种能够被语法解析器使用和管理的格式。他将输入文本分割,打标签,也就是用一些数值来指代一系列相应的字符串。
例如:

int a,b,c;
a=34;
b=56;
int c=a*b;

经过词法单元会生成如下的形式
首先定义一组词法单元

#include <iostream>
#include <string>
using namespace std;
#define NTOKEN 1000
//定义词法单元值
enum TokenValue 
    TOK_COMMA,          //逗号
    TOK_DIV,
    TOK_END,
    TOK_EQUAL,
    TOK_FOR,
    TOK_ID,
    TOK_IF,
    TOK_INTEGER,
    TOK_MINUS,
    TOK_MULT,
    TOK_PLUS,
    TOK_SEMICOLON,
    TOK_UNDEFINED,
    TOK_WHILE,
;
string TOKEN_VALUE_DESCRIPTION[] =

    "TOK_COMMA",
    "TOK_DIV",
    "TOK_END",
    "TOK_EQUAL",
    "TOK_FOR",
    "TOK_ID",
    "TOK_IF",
    "TOK_INTEGER",
    "TOK_MINUS",
    "TOK_MULT",
    "TOK_PLUS",
    "TOK_SEMICOLON",
    "TOK_UNDEFINED",
    "TOK_WHILE",
;
//标签和标签的值
typedef struct _Token 
    int  type;
    string str;
 Token;

然后在主程序中进行单词的分割

#include <stdio.h>
#include <ctype.h>
#include "lexer.h"
Token token[NTOKEN];
//输入参数为路径
int lexer(char *path) 
    FILE *fin;
    int  ch;
    char buf[256], *p;
    int n = 0;

    if ((fin = fopen(path, "r")) == NULL) 
        fprintf(stderr, "Cant' open the file... :(\\n");
    
    while ((ch = fgetc(fin)) != EOF) 
        if (ch <= ' ') continue;                  // [\\n\\t ]
        p = buf;
        switch (ch)     
        
        case '+':
            token[n].type = TOK_PLUS;
            token[n++].str = '+';
            break;
        case '-':
            token[n].type = TOK_MINUS;
            token[n++].str = '-';
            break;
        case '*':
            token[n].type = TOK_MINUS;
            token[n++].str = '*';
            break;
        case ';':
            token[n].type = TOK_SEMICOLON;
            token[n++].str = ';';
            break;
        case '=':
            token[n].type = TOK_EQUAL;
            token[n++].str = '=';
            break;  
        case ',':
            token[n].type = TOK_COMMA;
            token[n++].str = ',';
            break;
        default:
            break;
        
        if (isalpha(ch))                         // [A-Za-z][A-Za-z0-9],以字母开头为真
            token[n].type = TOK_ID;               //是一个标识符
            *p++ = ch;
            while (isalnum(ch = fgetc(fin))) *p++ = ch;  //是否为字母或数字
            ungetc(ch, fin);
            *p++ = '\\0';
            token[n++].str = buf;
        
        if (isdigit(ch))                  // [0-9]+
            token[n].type = TOK_INTEGER;
            *p++ = ch;
            while (isdigit(ch = fgetc(fin))) *p++ = ch;
            ungetc(ch, fin);
            *p++ = '\\0';
            token[n++].str = buf;
        
    
    fclose(fin);
    return n;

/*************************************************************************************
CMD下运行的结果。
void main(int argc, char* argv[]) 
    int n;
    int nToken = lexer(argv[1]);
    for (n = 0; n < nToken; n++) 
        //printf("%s: %s\\n", TOKEN_VALUE_DESCRIPTION[token[n].type], token[n].str);
        cout << TOKEN_VALUE_DESCRIPTION[token[n].type] << ": " << token[n].str << endl;
    

***************************************************************************************/
//vs上调试结果
void main(int argc, char* argv[]) 
    int n;
    char* input = "aa.txt";
    int nToken = lexer(input);
    for (n = 0; n < nToken; n++) 
        cout << TOKEN_VALUE_DESCRIPTION[token[n].type] << ": " << token[n].str << endl;
    

以上是关于自制编译器---c++实现词法分析器的主要内容,如果未能解决你的问题,请参考以下文章

自制操作系统Antz(14)——实现内置编程语言(词法解析器)

编译原理 实验一 java语言实现对C语言词法分析

编译原理 实验一 java语言实现对C语言词法分析

编译原理--词法分析器(python语言实现)

C词法分析器的Python简单实现

编译原理:词法分析器实现