词法分析往往是编译程序的第一步,词法分析器会把程序代码的输入流切分为token,然后语法分析器会接受这些token,并且去把token流构建成AST(抽象语法树),一般来说,被解析成token的语言是基于上下文无关语法的,一个token可以是一个字符串,由一个或者多个同一范畴的字符组成
输入字符流构成token的过程称为符号化,我们如果要把输入的字符分组成token,还需要有特定的分界符
下面就来看下一个简易的词法分析程序去分解出token,这里主要做的判断只是去做了标识符以及自定义的def关键字、左括号、右括号、逗号、数字这些
#include<cstdio>
#include<iostream>
#include <cctype>
static int Numeric_Val;
static std::string Identifier_string;
enum Token_Type {
EOF_TOKEN = 0,
NUMERIC_TOKEN,
IDENTIFIER_TOKEN,
LEFT_PARAN_TOKEN,
RIGHT_PARAN_TOKEN,
DEF_TOKEN,
COMMA_TOKEN
};
static int get_token(FILE * file){
static int LastChar = ' ';
//判断是不是空格
while (isspace(LastChar)) {
LastChar = fgetc(file);
}
//先判断是不是字符
if(isalpha(LastChar))
{
Identifier_string = LastChar;
while(isalnum((LastChar=fgetc(file))))
Identifier_string+=LastChar;
if(Identifier_string=="def")
{
return DEF_TOKEN;
}
return IDENTIFIER_TOKEN;
}
//判断是不是数字
if(isdigit(LastChar))
{
std::string NumStr;
do{
NumStr+=LastChar;
LastChar = fgetc(file);
}while(isdigit(LastChar));
//strtod是C语言及C++中的重要函数,功能是将字符串转换成浮点数,表头文件是#include <stdlib.h>,相关函数有atoi,atol,strtod,strtol。
Numeric_Val = strtod(NumStr.c_str(), 0);
return NUMERIC_TOKEN;
}
if(LastChar == '(')
{
LastChar = fgetc(file);
return LEFT_PARAN_TOKEN;
}
if(LastChar == ')')
{
LastChar = fgetc(file);
return RIGHT_PARAN_TOKEN;
}
if(LastChar==',')
{
LastChar = fgetc(file);
return COMMA_TOKEN;
}
if(LastChar=='#')
{
LastChar = fgetc(file);
while (LastChar!=EOF && LastChar !='\n' &&LastChar != '\r');
if(LastChar!=EOF)
return get_token(file);
}
if(LastChar==EOF)
return EOF_TOKEN;
int ThisChar = LastChar;
LastChar = fgetc(file);
return ThisChar;
}
int main()
{
FILE * fp;
fp = fopen("a.txt", "r");
int a;
while ((a=get_token(fp))!=EOF_TOKEN)
{
switch (a) {
case 1:
printf("NUMERIC_TOKEN\n");
break;
case 2:
printf("IDENTIFIER_TOKEN\n");
break;
case 3:
printf("LEFT_PARAN_TOKEN\n");
break;
case 4:
printf("RIGHT_PARAN_TOKEN\n");
break;
case 5:
printf("DEF_TOKEN\n");
break;
case 6:
printf("COMMA_TOKEN\n");
break;
default:
printf("DEFAULT\n");
break;
}
}
}
下面来看看输入文件的内容
def foo (x,y)
x + y * 16
看下结果输出是什么,下面的default代表的就是乘号和加号