定义控制台应用程序的入口点

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。


// Lexer.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "Lexer.h"

/*******************************************************************************************************/
class Tag
{//Tag类定义各个此法单元对应的常量
public :
const static int
MAIN=101, WHILE=102, DO=103, IF=104, //关键字
ELSE=105, FOR=106, AND=107, OR=108, //关键字
ADD=109, SUB=110, MULTI=111, DIV=112, //运算符+|-|*|/
EQ=113, GRET=114, LESS=115, GORE=116, //运算符||= =|>|<|>=
LORE=117, NEQ=118, EVL=119, ID=120, //运算符<=|<>,赋值,标识符
NUM=121, REAL=122, LBRK=123, RBRK=124, //整数,浮点数,左括号,右括号
LBRC=125, RBRC=126, END=127, SEMI=128, //左花括号,右花括号,终结符,分号
BRS=0001, ERID=0002, ERR=0003; //不完整的符号,错误的标识符,其他错误

public:
Tag(void){ };
~Tag(void){ };
};
/*******************************************************************************************************/


/*class Token
{
public:
int tag;
public:
Token(int t){tag=t;};
string ToString(){return ""+(char)tag; }
~Token(void){};
};*/


/*class Num:public Token
{
public:
int value;
public:
Num(int v):Token(Tag::NUM){value=v;};
~Num(void){};
};

class Real :
public Token
{
public:
float value;
public:
Real(float v):Token(Tag::REAL){value=v;};
~Real(void){};
};*/


/*******************************************************************************************************/

class Word
{//Word 定义了识别符
public:
string lexeme; //存放词
int tag; //对应的类型值
public:
Word(string s,int _tag){lexeme=s;tag=_tag;};
Word(){lexeme="";tag=0;};
~Word(void){ };
};

/*******************************************************************************************************/

class Symble:public Word
{//Symble类定义了能识别的符号,它是Word的子类
public:
static Word
and, or , add, sub, multi, // &&,||,+,-.*
div, eq, gret, less, ge, // /,==,>,<,>=
le, evl, lbrk, rbrk, lbrc, // <=,=,(,),{
rbrc, semi; //},;
public:
Symble(void);
~Symble(void);
};


Word Symble::and =Word("&&",Tag::AND);
Word Symble::or =Word("||",Tag::OR);
Word Symble::add=Word("+",Tag::ADD);
Word Symble::sub=Word("-",Tag::SUB);
Word Symble::multi=Word("*",Tag::MULTI);
Word Symble::div=Word("/",Tag::DIV);
Word Symble::eq=Word("==",Tag::EQ);
Word Symble::gret=Word(">",Tag::GRET);
Word Symble::less=Word("<",Tag::LESS);
Word Symble::ge=Word(">=",Tag::GORE);
Word Symble::le=Word("<=",Tag::LORE);
Word Symble::evl=Word("=",Tag::EVL);
Word Symble::lbrk=Word("(",Tag::LBRK);
Word Symble::rbrk=Word(")",Tag::RBRK);
Word Symble::lbrc=Word("{",Tag::LBRC);
Word Symble::rbrc=Word("}",Tag::RBRC);
Word Symble::semi=Word(";",Tag::SEMI);
Symble::Symble(void)
{

}

Symble::~Symble(void)
{

}
/************

*******************************************************************************************/


class Lexer
{//词法分析器
public:
static int line; //记录行数

char peek; //存放每次读取的一个字符
string program; //程序
string::size_type ix; //program上的一个索引
std::map words; //词法分析表
public:
void reserve(Word &w){ //将词汇写到词法表中
words.insert(std::map::value_type(w.lexeme,w.tag));
}

/*构造函数
*除了对各个成员变量赋初值外,还将关键字存入表中
*因为使用了map<>,后续读到的关键字将不会填入
*自然将关键字与标识符区分开
*/
Lexer::Lexer(string s){
line=1;
ix=0;
program=s;
//事先将关键字存到放到词法表中
reserve(Word("if",Tag::IF));
reserve(Word("main",Tag::MAIN));
reserve(Word("for",Tag::FOR));
reserve(Word("while",Tag::WHILE));
reserve(Word("do",Tag::DO));
reserve(Word("else",Tag::ELSE));
};
void readchar(); //读一个字符
bool readchar(char c); //读一个字符并与给定字符比较
int scan(Word & word);
Word scan(); //读一个单词
bool analyse(); //分析函数
~Lexer(void);
};

int Lexer::line=1;

void Lexer::readchar(){
if(ixpeek=program[ix];
ix++;
}
else{
peek='$';
ix=0;
}
};

bool Lexer:: readchar(char c)
{
readchar();
if(peek!=c) //所读字符与预测不同,返回false
return false;
else
return true; //否则返回true
}

int Lexer::scan(Word & word){

//词汇读取函数,文件结束返回1,错误返回-1,正确返回0
for(;;readchar()){ //过滤空格符,制表符,换行符
if(peek==' '||peek=='\t') continue;
else if(peek=='\n') line=line+1;
else break;
}

//判断是否为运算符或其它合法符号
switch(peek){
case '&':
if(readchar('&')) {word=Symble::and; return 0;}
else {word.lexeme="&";word.tag=Tag::BRS; return -1;}//是否是&&
case '|':
if(readchar('|')) {word=Symble::or; return 0;}
else {word.lexeme="|";word.tag=Tag::BRS; return -1;}//是否是||
case '=':
if(readchar('=')) {word=Symble::eq; return 0;}
else {word=Symble::evl; return 0;} //是'=='还是'='

case '>':
if(readchar('=')) {word=Symble::ge; return 0;}
else {word=Symble::gret; return 0;}

case '<':
if(readchar('=')) {word=Symble::le; return 0;}
else {word=Symble::less; return 0;}

case '+':
{word=Symble::add; readchar(); return 0;}

case '-':
{word=Symble::sub; readchar(); return 0;}

case '*':
{word=Symble::multi; readchar(); return 0;}

case '/':
{word=Symble::div; readchar(); return 0;}

case '(':
{word=Symble::lbrk; readchar(); return 0;}
case ')':
{word=Symble::rbrk; readchar(); return 0;}
case '{':
{word=Sym

ble::lbrc; readchar(); return 0;}
case '}':
{word=Symble::rbrc; readchar(); return 0;}
case ';':
{word=Symble::semi; readchar(); return 0;}
}

//判断是否是标识符
if((peek>='a'&&peek<='z')||(peek>='A'&&peek<='Z')){
string buffer("");
do{
buffer.append(1,peek);
readchar();
}while((peek>='a'&&peek<='z')||(peek>='A'&&peek<='Z'));
if(peek>='0'&&peek<='9'){//标识符结尾可以是数字
do{
buffer.append(1,peek);
readchar();
}while(peek>='0'&&peek<='9');
}
word.lexeme=buffer;
if(buffer=="main")
word.tag=Tag::MAIN;
else
word.tag=Tag::ID;
return 0;
}
//判断是否为整数或浮点数
if(peek>='0'&&peek<='9'){
string buffer("");
do{
buffer.append(1,peek);
readchar();
}while(peek>='0'&&peek<='9');
if(peek!='.') //是否跟有小数点
{
word.lexeme=buffer;
word.tag=Tag::NUM;
return 0;
}
else{
do{
buffer.append(1,peek);
readchar();
}while(peek>='0'&&peek<='9');
word.lexeme=buffer;
word.tag=Tag::REAL;
return 0;
}
}
//是否为文件结束
if(peek=='$'){
word.lexeme="$";
word.tag=Tag::END;
return 1;
}
//其它情况视为非法
word.lexeme=peek;
word.tag=Tag::ERR;
readchar();
return -1;
};
Word Lexer::scan(){//scan()的一个重载版本
Word word=Word("",Tag::ERR);
scan(word);
return(word);
}
bool Lexer::analyse(){
//词法分析函数,有错则返回false
bool result=true;
int isok=0;
Word word=Word("",0);
map::const_iterator map_it=words.begin();//words上的迭代器
readchar(); //预先读一个字符
do{
isok=scan(word); //读一个词
if(isok==-1) result=false;
reserve(word); //将词填到表中
}while(isok!=1); //直到读到文件结尾
map_it=words.begin(); //输出分析结果
std::cout<<"词法分析结果 \n"<<<"词汇 值 异常分析\n"<while(map_it!=words.end()){
if(map_it->second==Tag::BRS)
std::cout<first<<" "<second<<" 不完整的符号"<else if(map_it->second==Tag::ERR)
std::cout<first<<" "<second<<" 不可识别的词"<else
std::cout<first<<" "<second<++map_it;
}
if(result==false)
cout<<"词法错误!"<else
cout<<"词法正确!"<return result;
};

Lexer::~Lexer(void)
{

}

/*******************************************************************************************************/

class Parser
{//语法分析器
public:

Word newword;
int result; //语法分析结果
public:
Lexer lex; //词法分析器
Parser(string s);
~Parser(void){

};
bool program(); //程序分析函数
bool block(); //块分析函数
bool decles(); //语句串分析函数
bool statement(); //语句分析函数
bool expression(); //表达式分析函数
bool term(); //想分析函数

bool factor(); //因子分析
//void error(){};
};

Parser::Parser(string s):lex(s),newword("",0),result(1)
{

}


bool Parser:: program()
{ /*程序必须为 main{block} 的形式*/
bool flag=true; //出错标识
lex.readchar(); //预先读一个字符
cout<<"\n\n语法分析: "<if(((result=lex.scan(newword))==-1)||(newword.tag!=Tag::MAIN)){ //第一个单词必须是 "main"
cout<<"error : line "<flag=false;
}
if(!block()) //调用块分析
flag=false;
if(((result=lex.scan(newword))==-1)||(newword.tag!=Tag::END)){ //判文件结尾
cout<<"error : line "<flag=false;
}
return flag;

}

bool Parser:: block()
{
/*block 为{语句串}的形式*/
bool flag=true;
if(((result=lex.scan(newword))==-1)||(newword.tag!=Tag::LBRC)){ //判左花括号
cout<<"error : line "<flag=false;
}
if(!decles()) //调用语句串分析
flag=false;
if(newword.tag!=Tag::RBRC){ //判右花括号
cout<<"error : line "<flag=false;
}
return flag;
}

bool Parser:: decles()//yujuchuan
{

while(statement()) { //调用语句分析 直到最后一个语句结束

}
if(newword.tag!=Tag::RBRC) //如果下一个词是"}" 语句串分析正确,否则判错
return false;
else
return true;
}

bool Parser:: statement()
{
//语句必须是赋值语句 即 变量=表达式 ; 的形式
bool flag=true;
if((result=lex.scan(newword))==-1){ //读一个词
cout<<"error : line "<flag=false;
}
if(newword.tag==Tag::RBRC) //遇到"}" ,说明到了块结尾 ,返回
return false;
if(newword.tag!=Tag::ID){ //判变量,即标识符
cout<<"error : line "<flag=false;
}
if(((result=lex.scan(newword))==-1)||(newword.tag!=Tag::EVL)){ //判等号
cout<<"error : line "<flag=false;
}
return flag;
}

bool Parser:: expression()
{
//表达式只涉及四则运算 ,可以看成是多项式
bool flag=true;
if(!term()){ //必须有一个项
cout<<"error : line "<flag=false;
}
while((newword.tag==Tag::SUB)||(newword.tag==Tag::ADD)){ //遇到"+","-"说明多项式未完
if(!term()){ //继续调用项分析
flag=false;
}

}
return flag;
}


bool Parser:: term()
{
bool flag=true;
if(!factor()){ //调用因子分析
flag=false;
}
result=lex.scan(newword); //向后预读一个词
while

((newword.tag==Tag::MULTI)||(newword.tag==Tag::DIV)){ //遇到"*","/"说明项未完
if(!factor()){ //继续调用因子分析
flag=false;
}
result=lex.scan(newword);
}
return flag;
}
bool Parser:: factor()
{
bool flag=true;
if(((result=lex.scan(newword))==-1)){
cout<<"error : line "<flag=false;
}
if((newword.tag==Tag::ID)||(newword.tag==Tag::NUM)||(newword.tag==Tag::REAL)) //标识符,整数,浮点数都为合法因子
return flag;
if(newword.tag==Tag::LBRK){ //遇到"(" 说明因子为带括号的表达式
if(!expression()) //调用表达式分析
{
cout<<"error : line "<flag=false;
}

if(((result=lex.scan(newword))==-1)||(newword.tag!=Tag::RBRK)) //判")"
//cout<<"error : line "<flag=false;;
}
else{
cout<<"error : line "<}
flag=false;
return flag;
}


/*******************************************************************************************************/
int _tmain(int argc, _TCHAR* argv[])
{//主函数
string file("test.c"); //文件名
string s,str;
char c;
std::ifstream input; //标准文件输入流
input.close();
input.clear();
input.open(file.c_str()); //打开文件
if(!input){ //未打开报错退出
cerr<<"error:unble to open file:"
<return -1;
}
while(input>>str){
s.append(str); //每次读一行
s.append("\n"); //换行
};

Lexer lexer(s); //构造一个词法分析器
lexer.analyse(); //词法分析
Parser par(s); //构造一个语法分析器

if(par.program()) //语法分析
cout<<"\n\n"<else
cout<<"\n\n"<return 0;
}


相关文档
最新文档