学完编译原理这门课,用c语言或者c++语言,编一个预测分析的程序,对预测分析也至少测试三个句子(含错误
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学完编译原理这门课,用c语言或者c++语言,编一个预测分析的程序,对预测分析也至少测试三个句子(含错误相关的知识,希望对你有一定的参考价值。
我写好的.scan.h
/*
* scan.h
* ccompiler
*
* Created by on 09-10-12.
* Copyright 2009 __MyCompanyName__. All rights reserved.
*
*/
#ifndef _SCAN_H_
#define _SCAN_H_
#include <string>
#include <fstream>
using namespace std;
typedef enum
ENDFILE,ERROR,
ELSE,IF,INT,RETURN,VOID,WHILE,
ID,NUM,
ASSIGN,EQ,LT,GT,LE,GE,NE,ADD,SUB,MUL,DIV,SEMI,LPAREN,RPAREN,LZK,RZK,LDK,RDK,COMMA
TokenType;
class Scan
private:
string tokenStr;
string linebuffer;
ifstream * in;
int linepos;
int lineno;
bool EOF_Flag;
bool traceScan;
void printToken(TokenType tt,const string &tok);
public:
Scan(ifstream * in)
this->in=in;
linepos=0;
linebuffer="";
lineno=0;
EOF_Flag=false
traceScan=true;
char getNextChar();
void ungetNextChar();
TokenType reservedLookup(string &s);
void setTraceScan(bool f);
bool getTraceScan();
TokenType getToken();
string getTokenStr();
;
#endif
scan.cpp
/*
* scan.cpp
* ccompiler
*
* Created by on 09-10-12.
* Copyright 2009 __MyCompanyName__. All rights reserved.
*
*/
#include <string>
#include <fstream>
#include <iostream>
using namespace std;
#include "scan.h"
typedef enum
StateType;
static struct
string str;
TokenType tok;
reservedWords[6]
=,,,,,;
char Scan::getNextChar()
if(linepos>=linebuffer.size())
if(getline(*in,linebuffer))
linebuffer+="\n";
lineno++;
linepos=0;
return linebuffer[linepos++];
else
EOF_Flag=true;
return EOF;
else
return linebuffer[linepos++];
void Scan::ungetNextChar()
if(!EOF_Flag) linepos--;
TokenType Scan::reservedLookup(string &s)
for(int i=0;i<6;i++)
if(s==reservedWords[i].str)
return reservedWords[i].tok;
return ID;
void Scan::setTraceScan(bool f)
traceScan=f;
bool Scan::getTraceScan()
return traceScan;
TokenType Scan::getToken()
tokenStr="";
TokenType currentToken;
StateType state=START;
while(state!=DONE)
bool save=false;
char c=getNextChar();
switch (state)
case START:
if(c>='0'&&c<='9')
state=INNUM;
save=true;
else if((c>='a'&&c<='z')||(c>='A'&&c<='Z'))
state=INID;
save=true;
else if(c==' '||c=='\t'||c=='\n')
state=START;
else if(c=='/')
state=SLASH;
else if(c=='=')
state=TEMPE;
else if(c=='>')
state=TEMPG;
else if(c=='<')
state=TEMPL;
else if(c=='!')
state=INNOTEQ;
else
state=DONE;
switch (c)
case EOF:
currentToken=ENDFILE;
break;
case '+':
currentToken=ADD;
break;
case '-':
currentToken=SUB;
break;
case '*':
currentToken=MUL;
break;
case '(':
currentToken=LPAREN;
break;
case ')':
currentToken=RPAREN;
break;
case '[':
currentToken=LZK;
break;
case ']':
currentToken=RZK;
break;
case '':
currentToken=LDK;
break;
case '':
currentToken=RDK;
break;
case ';':
currentToken=SEMI;
break;
case ',':
currentToken=COMMA;
break;
default:
currentToken=ERROR;
break;
break;
case INNUM:
if(c<'0'||c>'9')
ungetNextChar();
state=DONE;
currentToken=NUM;
else
save=true;
break;
case INID:
if(!((c>='a'&&c<='z')||(c>='A'&&c<='Z')))
ungetNextChar();
state=DONE;
currentToken=ID;
else
save=true;
break;
case SLASH:
if (c!='*')
state=DONE;
currentToken=DIV;
else
state=INCOMMENT1;
break;
case INCOMMENT1:
if (c!='*')
state=INCOMMENT1;
else if(c==EOF)
state=DONE;
currentToken=ENDFILE;
else
state=INCOMMENT2;
break;
case INCOMMENT2:
if (c=='*')
state=INCOMMENT2;
else if(c=='/')
state=START;
else if(c==EOF)
state=DONE;
currentToken=ENDFILE;
else
state=INCOMMENT1;
break;
case TEMPE:
if (c=='=')
state=DONE;
currentToken=EQ;
else
state=DONE;
ungetNextChar();
currentToken=ASSIGN;
break;
case TEMPG:
if (c=='=')
state=DONE;
currentToken=GE;
else
state=DONE;
ungetNextChar();
currentToken=GT;
break;
case TEMPL:
if (c=='=')
state=DONE;
currentToken=LE;
else
state=DONE;
ungetNextChar();
currentToken=LT;
break;
case INNOTEQ:
if (c=='=')
state=DONE;
currentToken=NE;
else
state=DONE;
ungetNextChar();
currentToken=ERROR;
break;
default:
cerr<<"Scanner Bug: state= "<<state<<endl;
state=DONE;
currentToken=ERROR;
break;
if(save)
string newChar(1,c);
tokenStr+=newChar;
if (state==DONE&¤tToken==ID)
currentToken=reservedLookup(tokenStr);
if (traceScan)
cout<<"Scan at line "<<lineno<<" token: ";
printToken(currentToken, tokenStr);
cout<<endl;
return currentToken;
string Scan::getTokenStr()
return tokenStr;
void Scan::printToken(TokenType tt,const string &tok)
string type;
switch (tt)
case ENDFILE:
type="EOF";
break;
case ERROR:
type="ERROR";
break;
case ELSE:
case IF:
case INT:
case RETURN:
case VOID:
case WHILE:
type="reserved word";
break;
case ID:
type="ID";
break;
case NUM:
type="NUM";
break;
case ASSIGN:
type="=";
break;
case EQ:
type="==";
break;
case LT:
type="<";
break;
case GT:
type=">";
break;
case LE:
type="<=";
break;
case GE:
type=">=";
break;
case NE:
type="!=";
break;
case ADD:
type="+";
break;
case SUB:
type="-";
break;
case MUL:
type="*";
break;
case DIV:
type="/";
break;
case SEMI:
type=";";
break;
case LPAREN:
type="(";
break;
case RPAREN:
type=")";
break;
case LZK:
type="[";
break;
case RZK:
type="]";
break;
case LDK:
type="";
case RDK:
type="";
break;
case COMMA:
type=",";
break;
default:
break;
cout << type<<": "<<tok;
main.cpp
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
#include "scan.h"
int main (int argc, char * const argv[])
string fileName="/Users/huanglongyin/scan_in.txt";
//cout<< "File name: ";
//cin>>fileName;
ifstream in(fileName.c_str());
if(!in)
cerr<<"Error occurs when openning file "<<fileName<<endl;
return -1;
Scan scan(&in);
while(scan.getToken()!=ENDFILE);
return 0;
参考技术A 没写过预测分析程序,只写过一个词法分析程序,有需要的话 http://wenku.baidu.com/view/aa9fdc5e804d2b160b4ec0bc.html 这是我共享的
编译原理随笔
最近初步接触到了编译原理这门课程,通过老师提供的一些链接,以及课上的知识,对这门课有了一些认识与了解。
编译原理旨在介绍编译程序构造的一般原理和基本方法。内容包括语言和文法、词法分析、语法分析、语法制导翻译、中间代码生成、存储管理、代码优化和目标代码生成。从源语言提取需要的信息;把源语言翻译成目标语言;自动生成满足一定规范的文本...
学习编译原理可以更加容易的理解在一个语言种哪些写法是等价的,哪些是有差异的可以更加客观的比较不同语言的差异,更不容易被某个特定语言的宣扬者忽悠,学习新的语言是效率也会更高。
学过编译原理这门课程,各种文法、各种词法语法分析算法,非常消磨人的耐心和兴致;因此除了课上听讲,课外看书等途径之外,也应该多和人探讨交流,多在网站上查阅资料。将龙虎鲸三大宝书翻阅一下,也能提高学习效率。
以上是关于学完编译原理这门课,用c语言或者c++语言,编一个预测分析的程序,对预测分析也至少测试三个句子(含错误的主要内容,如果未能解决你的问题,请参考以下文章