欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

实验:实现C语言小子集程序的词法分析

程序员文章站 2024-03-22 23:57:28
...

实现C语言小子集程序的词法分析

(1)以表1的小语言(C语言小子集)为例实现词法分析
实验:实现C语言小子集程序的词法分析
(2)设计单词属性值;设计表格(表示标识符表),单词符号及机内表示
(3)编码实现词法分析程序
(4)要求:
- 输入方式:文件(源文件)
- 输出方式:词法分析的结果(单词串)输出到屏幕上同时保存文件上(目标文件)。
(5)要求实现:

  • 对正确源程序的识别;
  • 对包含有注释//和/* */的源程序的识别;
  • 对包含错误标识符和错误数的源程序的识别并作相应的错误处理。
    (6)自己设计3-5个测试实例,要求覆盖上述功能。测试实例可参看(附录A)

附录A

实验:实现C语言小子集程序的词法分析

实验:实现C语言小子集程序的词法分析

源代码

//词法生成器
#include<iostream>
#include<vector>
using namespace std;
#include<fstream>
#include<iomanip>
#include<map>
#include<string>
map<string, int>SYMBOL;
vector<string>VARIABLE;//保存标识符
vector<int>v;//处理行
const int num = 25500;//文本最多25500个字符
bool Flag = true;//注释
string FileName = "3.txt";
FILE *f_out = fopen("符号表.txt", "w");
FILE *f = fopen("标识符表.txt", "w");
void LoadSymbol()
{
    int sum = 0, i = 0;
    string s = "";
    char temp[num];
    ifstream f_in("C语言小子集定义表.txt");
    f_in.getline(temp, num, 0);//一次性读入所有符号,保存到temp中
    //cout << temp << endl;
    while (temp[i] != '#')
    {
        while (temp[i] != ':')
            s += temp[i], i++;
        i++;
        while (temp[i] != '\n')
            sum = sum * 10 + (temp[i] - '0'), i++;
        SYMBOL[s] = sum;
        s = "", sum = 0;
        i++;
    }
    /*map<string, int>::iterator it;
    for (it = SYMBOL.begin();it != SYMBOL.end();it++)
    {
        cout << (*it).first << ":" << (*it).second << endl;
    }*/
}
int Find(string s)//查询函数,如果查到存在此关键词便返回值,否则返回零,不包括常数以及标识符
{
    map<string, int>::iterator it;
    it = SYMBOL.find(s);
    if (it != SYMBOL.end())
    {
        return SYMBOL[s];
    }
    else
        return 0;
}
//预处理(去空格以及注释)- Tab无法处理
void PreDeal(string &s)
{
    //处理注释
    int index = 0;
    if (s.find("//") != -1)
    {
        index = s.find("//");
        s = s.substr(0, index);
        cout << s << endl;
    }
    else if (s.find("/*") != -1)
    {
        index = s.find("/*");
        if (s.find("*/") == -1)
        {
            Flag = false;
            s = "";
        }
        else
        {
            index = s.find("*/");
            s = s.substr(index + 2, s.size() - 1);
        }
    }
    else if (s.find("*/") != -1 && Flag == false)
    {
        index = s.find("*/");
        s = s.substr(index + 2, s.size() - 1);
        Flag = true;
    }

    //处理空格
    string temp = "";
    for (int i = 0;i < s.size();)
    {
        while (s[i] == ' '&&s[i + 1] == ' ')
        {
            i++;
        }
        temp += s[i];
        i++;
    }
    s = temp;
}
//处理单行语句
void Deal(string &s, int line)
{
    //fputs("adsdsa", f_out);
    PreDeal(s);
    string temp = "";
    for (int i = 0;i < s.size();)
    {
        if (s[i] == '>')
        {
            if (s[i + 1] == '=')
            {
                fputs("<", f_out);
                fprintf(f_out, "%d,", SYMBOL[">="]);
                fputs("->,", f_out);
                i = i + 2;
            }
            else
            {
                fputs("<", f_out);
                fprintf(f_out, "%d,", SYMBOL[">"]);
                fputs("->,", f_out);
                i++;
            }
        }
        else if (s[i] == '<')
        {
            if (s[i + 1] == '=')
            {
                fputs("<", f_out);
                fprintf(f_out, "%d,", SYMBOL["<="]);
                fputs("->,", f_out);
                i = i + 2;
            }
            else
            {
                fputs("<", f_out);
                fprintf(f_out, "%d,", SYMBOL["<"]);
                fputs("->,", f_out);
                i++;
            }
        }
        else if (s[i] == '=')
        {
            if (s[i + 1] == '=')
            {
                fputs("<", f_out);
                fprintf(f_out, "%d,", SYMBOL["=="]);
                fputs("->,", f_out);
                i = i + 2;
            }
            else
            {
                fputs("<", f_out);
                fprintf(f_out, "%d,", SYMBOL["="]);
                fputs("->,", f_out);
                i++;
            }
        }
        else if (s[i] == '!'&&s[i + 1] == '=')
        {
            fputs("<", f_out);
            fprintf(f_out, "%d,", SYMBOL["!="]);
            fputs("->,", f_out);
            i = i + 2;
        }
        else if (s[i] == '&'&&s[i + 1] == '&')
        {
            fputs("<", f_out);
            fprintf(f_out, "%d,", SYMBOL["&&"]);
            fputs("->,", f_out);
            i = i + 2;
        }
        else if (s[i] == '|'&&s[i + 1] == '|')
        {
            fputs("<", f_out);
            fprintf(f_out, "%d,", SYMBOL["||"]);
            fputs("->,", f_out);
            i = i + 2;
        }
        else if (Find(temp = s[i]))
        {
            fputs("<", f_out);
            fprintf(f_out, "%d,", SYMBOL[temp]);
            fputs("->,", f_out);
            i++;
        }
        else if (true)
        {
            temp = "";
            while (s[i] != ' '&&s[i] != '\n'&&s[i] != ')'&&s[i] != ';'&&s[i] != '('&&s[i] != '{'&&s[i] != '}'&&s[i] != '['&&s[i] != ']'&&s[i] != ','&&s[i] != '+'&&s[i] != '-'&&s[i] != '*'&&s[i] != '/'&&s[i] != '%'&&s[i] != '>'&&s[i] != '<'&&s[i] != '='&&s[i] != '!'&&s[i] != '&')
            {
                temp += s[i];
                i++;
                if (i == s.size())break;
            }
            if (Find(temp))
            {
                fputs("<", f_out);
                fprintf(f_out, "%d,", SYMBOL[temp]);
                fputs("->,", f_out);
            }
            else if (temp != "")
            {
                if (temp[0] >= '0'&&temp[0] <= '9' && (temp[temp.size() - 1] >= 'a'&&temp[temp.size() - 1] <= 'z' || temp[temp.size() - 1] >= 'A'&&temp[temp.size() - 1] <= 'Z'))
                {
                    fputs("LexicalError,", f_out);
                    v.push_back(line);
                }
                else if ((temp[0] >= 'a'&&temp[0] <= 'z' || temp[0] >= 'A'&&temp[0] <= 'Z'))
                {
                    fputs("<", f_out);
                    fprintf(f_out, "%d,", 1);
                    fprintf(f_out, "%s>,", temp.c_str());
                    VARIABLE.push_back(temp.c_str());
                }
                else 
                {
                    int sum = 0;
                    while (s[i] != ' '&&s[i] != ';'&&s[i] != ')'&&s[i] != ';')
                        sum = sum * 10 + (s[i] - '0'), i++;
                    fputs("<", f_out);
                    fprintf(f_out, "%d,", 2);
                    fprintf(f_out, "%s>,", temp.c_str());
                }
            }
        }
        if (s[i] == ' ' || s[i] == '\n')
            i++;
    }
}
void LoadFile()//读入文本
{
    string s = "";
    int i = 0, line = 1;
    char temp[num];
    ifstream f_in(FileName);
    f_in.getline(temp, num, 0);
    while (temp[i] != '#')
    {
        while (temp[i] != '\n')
        {
            s += temp[i];
            i++;
        }
        if (Flag == false)
        {
            if (s.find("*/") != -1)
                Flag = true;
            fputs("\n", f_out);
        }
        else
            Deal(s, line);
        fputs("\n", f_out);
        s = "", i++, line++;
    }
    if (v.size() == 0)
        fputs("LexicalError(s) 0 errors\n", f_out);
    else
    {
        fputs("LexicalError(s) on line(s) ", f_out);
        fprintf(f_out, "%d", v[0]);
        for (int j = 1;j < v.size();j++)
            fprintf(f_out, ",%d", v[j]);
        fputs("\n", f_out);
    }
    fputs("#", f_out);
    v.clear();
    fclose(f_out);
}
void Print_symbol()
{
    cout << "打印符号表:" << endl;
    char temp[num];
    ifstream f_in("符号表.txt");
    f_in.getline(temp, num, 0);//一次性读入所有符号,保存到temp中
    cout << temp << endl;
}
void Print_variable()
{
    FILE*f = fopen("标识符表.txt", "w");
    cout << endl << "打印标识符表:" << endl;
    fputs("标识符表:\n", f);
    for (int i = 0;i < VARIABLE.size();i++)
    {
        cout << fixed << setw(10) << i + 1 << ":" << VARIABLE[i] << " ";
        fprintf(f, "%d:%s\n", i + 1, VARIABLE[i].c_str());
        if ((i + 1) % 5 == 0)cout << endl;
    }
    cout << endl;
}
int main()
{
    cout << "输入文本名称:" << endl;
    cin >> FileName;
    LoadSymbol();//加载C语言小子集定义表至map中
    LoadFile();
    Print_symbol();//打印符号表
    Print_variable();//打印标识符表
    cout << endl;
    return 0;
}
相关标签: y