编译原理 词法分析
实验目的:
通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理 解。并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法 分析方法。 编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词, 即基本保留字、标识符、常数、运算符、分隔符五大类。并依次输出各个单词的 内部编码及单词符号自身值。
实验环境:
Microsoft Visual Studio 2019 Community
思路:
首先忽略空格读取第一个字符,判断字符的类型:如果是下划线,则该单词一定是标识符;如果是数字,则该单词一定是常数;如果是运算符,则该单词一定是运算符;如果是分隔符,则该单词一定是分隔符;如果是字母,则需要进一步判断是标识符还是保留字。
为了提高可读性,单词的类型使用了枚举表示。
为了便于增加保留字、运算符和分隔符,将其都存储在外部文件中,同时因为后期可能会增加新的保留字、运算符和分隔符,数量无法确定,所以在程序中使用链表存储这些数据,可以不受数量限制。
标识符表与常数表也因为事先无法确定数量所以选择了链表存储。
采用最长匹配也确保了遇见形如int01这样的标识符能准确识别为标识符,而不会被分开识别为保留字int和01。
保留字:
int char float double bool void
if else for while do return break continue true false
static const enum class struct interface
private protected public this
new delete template
运算符:
:+ - * / % = += -= ++ – > < >= <= == != & && | || ~ ^ ! << >> . ->
分隔符:
, ; { } ( )
测试用代码:
class Class
{
char ch;
int int01, int02;
public:
char getCh();
void setCh(char ch);
};
int main()
{
int a, b;
a = 10;
b = a + 20;
while (true)
{
a = b + 1;
if (a <= 100)
{
continue;
}
a = b + 3;
if (a > 300)
break;
}
Class c;
for (int i = 0; i < 50; i++)
{
a += c.getCh();
c.setCh(b);
b -= a;
}
return 0;
}
下面的代码有点多。。。
//KeyString.h
#pragma once
#include <iostream>
#include "KeyStringReader.h"
using namespace std;
//存放运算符表,保留字表,分隔符表
class KeyString
{
public:
static KeyStringReader Operators;
static KeyStringReader ReservedWords;
static KeyStringReader Separators;
};
//KeyString.cpp
#include "KeyString.h"
KeyStringReader KeyString::Operators("Operators.txt");
KeyStringReader KeyString::ReservedWords("ReservedWords.txt");
KeyStringReader KeyString::Separators("Separators.txt");
//KeyStringReader.h
#pragma once
#include <iostream>
#include "LinkList.h"
using namespace std;
//从文件读取并保存已定义字符
class KeyStringReader
{
public:
LinkList<string> data;
KeyStringReader(string fileName);
};
//KeyStringReader.cpp
#include <fstream>
#include "KeyStringReader.h"
KeyStringReader