SCANNER类的实现
扫描器的类图
两个关键函数:
#include<stdlib.h>
字符串转double
double strtod(const char *nptr, char **endptr);
char* p;
number_ = strtod(&buf_[curPos_], &p);
strtod()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,(所以a435无法识别,必须要先出现数字才可以)到出现非数字或字符串结束时('\0')才结束转换,并将结果返回。若endptr不为NULL,则会将遇到不合条件而终止的nptr中的字符指针由endptr传回。参数nptr字符串可包含正负号、小数点或E(e)来表示指数部分。如123.456或123e-2。
#include<ctype.h>
函数说明
检查参数c是否为空格字符,也就是判断是否为空格(' ')、水平定位字符
('\t')、归位键('\r')、换行('\n')、垂直定位字符('\v')或翻页('\f')的情况。
返回值
若参数c为空格字符,则返回TRUE,否则返回NULL(0)。
#include <ctype.h>
#include <stdio.h>
int main()
{
int i;
char str[]="123c @# FD\tsP[e?\n";
for(i=0;str[i]!=0;i++)
{
if(isspace(str[i]))
printf("str[%d] is a white-space character:%d\n",i,str[i]);
}
}
scanner.h:
#ifndef _SCANNER_H_
#define _SCANNER_H_
#include <string>
enum EToken
{
TOKEN_END,
TOKEN_ERROR,
TOKEN_NUMBER,
TOKEN_PLUS,
TOKEN_MINUS,
TOKEN_MULTIPLY,
TOKEN_DIVIDE,
TOKEN_LPARENTHESIS,
TOKEN_RPARENTHESIS,
TOKEN_IDENTIFIER,
TOKEN_ASSIGN
};
class Scanner
{
public:
Scanner(const std::string& buf);
void Accept();
double Number() const;
EToken Token() const;
private:
void SkipWhite();
const std::string buf_;
unsigned int curPos_;
EToken token_;
double number_;
};
#endif // _SCANNER_H_
#include "Scanner.h"
#include <cctype>
Scanner::Scanner(const std::string& buf) : buf_(buf), curPos_(0)
{
Accept();
}
double Scanner::Number() const
{
return number_;
}
EToken Scanner::Token() const
{
return token_;
}
void Scanner::SkipWhite()
{
while (isspace(buf_[curPos_]))
++curPos_;
}
void Scanner::Accept()
{
SkipWhite();
switch (buf_[curPos_])
{
case '+':
token_ = TOKEN_PLUS;
++curPos_;
break;
case '-':
token_ = TOKEN_MINUS;
++curPos_;
break;
case '*':
token_ = TOKEN_MULTIPLY;
++curPos_;
break;
case '/':
token_ = TOKEN_DIVIDE;
++curPos_;
break;
case '(':
token_ = TOKEN_LPARENTHESIS;
++curPos_;
break;
case ')':
token_ = TOKEN_RPARENTHESIS;
++curPos_;
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case '.':
token_ = TOKEN_NUMBER;
char* p;
number_ = strtod(&buf_[curPos_], &p);
curPos_ = p - &buf_[0];
break;
case '\0': case '\n': case '\r': case EOF:
token_ = TOKEN_END;
break;
default:
token_ = TOKEN_ERROR;
break;
}
}