编译原理预测分析法
❶ 求助!编译原理练习题
1、编译方法中自底向上的语法分析算法有:简单优先分析算法、算符优先分析算法、SLR方法、LR(K)方法、LALR(K)方法,自顶向下的语法分析算法有:递归子程序法、LL(K)分析算、预测分析方法。
2、词法分析器的输入是源程序的字符流,输出是词法记号流。
3、等价
4、(a|b)*(aa|bb)(a|b)*
❷ 编译原理实现判断是不是一个文法的句子
构造LL(1)语法分析程序,任意输入一个文法符号串,并判断它是否为文法的一个句子。程序要求为该文法构造预测分析表,并按照预测分析算法对输入串进行语法分析,判别程序是否符合已知的语法规则,如果不符合(编译出错),则输出错误信息。
❸ 编译原理语法分析中消除左递归的问题。比如A→Ab|c中为什么说它是左递归呢,明明是A定义为Ab或者
A->Ab|c为什么是左递归,和为什么要消除左递归:
定义,就无需争辩了。至于为什么自顶向下文法不能处理左递归,解释如下:
c∈FIRST(A),所以当预测分析的栈顶出现非终结符A,而输入字符串最左边为c时,就不知道用产生式A->Ab还是A->c了。无法构造预测分析表。比如输入字符串为cbb,我们人当然容易知道是A->Ab->Abb->cbb了,但是电脑没那么聪明,如果不消除左递归,只有回溯了。
❹ 怎样理解编译原理
如果你在学编译原理的话,你可以把它理解为一个编写《编译器》的时间课程~
当然,事实上,编译原理的老师也是这么要求的~
编译器就是把你编写的源程序代码变成程序可理解的二进制代码的过程。
而把这个过程细化之后就可以归纳为:1、预处理过程(例如去掉不需要的空格、注释之类的~)、2、词法分析(就是把你写的程序从头到尾扫描一遍,识别出你的程序中所有的“单词”,并编号记录,按顺序放在一张大的二维表中,一遍下一个处理过程用到~,当然,如果你的单词有错的话,还要做相应的出错处理哈~)、3、语法分析(处理的是第二部中得到的单词二维表,经过一定的算法处理,可以得到一张成为预测分析表的东东~简单的说就是按照预测分析表对一个个句子进行检查,全部通过就进入下一关节,否则出错处理)、4、语义分析、5、目标代码的生成(这部分生成基本的与机器无关的单步执行的代码)
之后的步骤就是与机器有关的东西了~目标代码优化>汇编代码生成>生成二进制代码~
恩,差不多就是这么个流程,你可以再去针对自己感兴趣的部分网络一下哈~
❺ 编译原理语法分析器程序设计,用c语言或C++,哪里有这个程序
1.文法简略,没有实现的部分,可以在此文法的基础上进行扩充,本程序的采用自顶向下的LL(1)文法。
2.可以自动实现求First
集和
Follow
集。
3.处终结符外(有些硬编码的成分),终结符的文法可以自定义,也就是说读者可以自定义文法。
4.为方便理解,C语言的文法描述写成中文。
5.程序将词法分析和语法分析结合起来,词法分析的结果作为语法分析的输入。
6.最终结果在控制台显示的有:词法分析、First集、Follow集、Select集,在preciateResult.txt
中写入了语法分析结果,在preciateTable.txt
中写入了预测分析表。
7.文法的词素之间必须有空格分开。
❻ 编译原理单选题,求助!!!急!!!
西交《数字逻辑电路》在线作业免费答案
算符优先分析法每次都是对( )进行归约:
A.句柄
B.最左素短语
C.素短语
D.简单短语
正确答案:B
表达式-a+b*(-c+d)的逆波兰式是( )。
A.ab+-cd+-*
B.a-b+c-d+*
C.a-b+c-d+*
D.a-bc-d+*+
正确答案:D
以( )作为输出,允许自程序单独编译。
A.绝对机器代码
B.可再定位机器语言
C.汇编语言程序
D.中间语言
正确答案:B
太多了,不打字了,剩下的加好友发给你剩下的吧。
❼ 学完编译原理这门课,用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;
}
❽ 在从上到下的语法分析中,预测分析法与递归下降法各有什么优点和缺点
你说的应该是编译原理吧。 递归下降分析程序的实现思想是:识别程序由一组子程序组成。每个子程序对应于一个非终结符号。 每一个子程序的功能是:选择正确的右部,扫描完相应的字。在右部中有非终结符号时,调用该非终结符号对应的子程序来完成。 所以,当有左递归出现时,递归下降分析程序就会出现回朔,将可能产生无限的循环,所以递归下降分析的前提条件之一就是消除左递归。
❾ 编译原理:预测分析法判断输入串i*i+i是否是文法G3的句子
不管什么法,有表就是查表。 分析自顶向下,搞个栈 ,再搞个输入:
#E i*i+i$
#E'T i*i+i$
#E'T'F i*i+i$
#E'T'i i*i+i$ 匹配i
#E'T' *i+i$
#E'T'F* *i+i$ 匹配*
#E'T'F i+i$
#E'T'i i+i$ 匹配i
#E'T' +i$
#E' +i$
#E'T+ +i$ 匹配+
#E'T i$
#E'T'F i$
#E'T'i i$ 匹配i
#E'T' $
#E' $
# $ 接受
这样OK?
❿ 求 编译原理 语法分析程序
可以参考我的空间,我在三年前写过类似代码。
http://hi..com/逄韶华/ihome/myblog