#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include <iostream>
//===----------------------------------------------------------------------===//
// Lexer
//===----------------------------------------------------------------------===//
//1 词法分析。把一个一个的词读出来,看看是否和规定的语言一样
// The lexer returns tokens [0-255] if it is an unknown character, otherwise one
// of these for known things.
enum Token {
tok_eof = -1,
// commands
tok_def = -2,
tok_extern = -3,
// primary
tok_identifier = -4,//标识符
tok_number = -5
};
//枚举类型 用字符串代表常量
//std::命名空间 没有使用using namespace std;
static std::string IdentifierStr; // Filled in if tok_identifier
static double NumVal; // Filled in if tok_number
/// gettok - Return the next token from standard input.
static int gettok() {
static int LastChar = ' ';
//xxxx xxxx 这种,判断第一个字符 字母 数字..
//首先使用while循环去除输入的空格和换行
// Skip any whitespace.
while (isspace(LastChar))
LastChar = getchar();
//分析是否是字母,当字母后面的字符是数字或者字母的时候,将其加到 IdentifierStr
//这一步是保存声明变量或者函数名的关键字的。一起生成一个identifier,再与已有的关键字对比,检查是否是关键字
if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
IdentifierStr = LastChar;
//首字符是字母,后面跟数字或者字母,得到IdentifierStr ,判断这个是否是标识符
while (isalnum((LastChar = getchar())))
IdentifierStr += LastChar;
//def
if (IdentifierStr == "def")
return tok_def;
//extern
if (IdentifierStr == "extern")
return tok_extern;
//如果不是上面两个 那就返回这是个标识符
return tok_identifier;
}
//检查是否是数字,后面的判断 LastChar == '.'是检查小数点。如果是数字将其保存NumVal
//返回的tok_number代表当前返回的是数字
if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+
//字符串 Numstr
std::string NumStr;
//后面是数字或者小数点 加上,按理来说判断首字符不需要判断是不是小数点,emmm姑且先这样吧
do{
NumStr += LastChar;
LastChar = getchar();
} while (isdigit(LastChar) || LastChar == '.');
//strtod 将字符串转换成浮点数,NumStr.c_str()返回一个指向正规C字符串的指针常量
NumVal = strtod(NumStr.c_str(), nullptr);
return tok_number;
}
//这里代表是注释
if (LastChar == '#') {
// Comment until end of line.
do
LastChar = getchar();
while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');
//注释行读完,继续调用gettok()
if (LastChar != EOF)
return gettok();
}
// Check for end of file. Don't eat the EOF.
if (LastChar == EOF)
return tok_eof;
// Otherwise, just return the character as its ascii value.这个字符或者是&之类的..
int ThisChar = LastChar;
LastChar = getchar();
return ThisChar;
}
int main(){
while(true){
int tok = gettok();
std::cout<<"got token:"<<tok<<std::endl;
}
return 0;
}
测试这个词法分析器