编译原理语法分析器程序设计,用C语言或C++,哪里有这个程序
1.文法简略,没有实现的部分,可以在此文法的基础上进行扩充,本程序的采用自顶向下的LL(1)文法。
2.可以自动实现求First 集和 Follow 集。
3.处终结符外(有些硬编码的成分),终结符的文法可以自定义,也就是说读者可以自定义文法。
4.为方便理解,C语言的文法描述写成中文。
5.程序将词法分析和语法分析结合起来,词法分析的结果作为语法分析的输入。
6.最终结果在控制台显示的有:词法分析、First集、Follow集、Select集,在preciateResult.txt 中写入了语法分析结果,在preciateTable.txt 中写入了预测分析表。
7.文法的词素之间必须有空格分开。
...............................................................................难难难,难于上青天
我写好的.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
{START,INNUM,INID,INNOTEQ,TEMPE,TEMPG,TEMPL,SLASH,INCOMMENT1,INCOMMENT2,DONE}
StateType;
static struct
{
string str;
TokenType tok;
} reservedWords[6]
={{"else",ELSE},{"if",IF},{"int",INT},{"return",RETURN},{"void",VOID},{"while",WHILE}};
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;
}
http://www.pudn.com/downloads31/sourcecode/editor/detail99820.html
http://www.popuni.com/article.asp?id=117
这两个都可以,后面这个还有词法分析器,可以下载……
读书笔记 | 编译原理 ——一个简单的语法制导翻译器(上)
语法制导翻译 语法制导翻译是编译器前端中的重要环节,它结合语义分析生成中间代码。例如,处理中缀表达式到后缀表示的翻译,需要通过属性计算来表示。分析方法与预测分析 自顶向下分析(包括最左和最右推导)和预测分析是实现语法分析的不同策略,如预测分析器的伪代码展示了简单文法的处理过程。FIRST和FOLLOW...
编译原理中是如何进行「词法分析」的
接下来,我们将探讨编译原理中是如何进行语法分析的。在这个过程中,我们会遇到正则表达式、正规文法、有限自动机、正规文法、正规集与正规式等概念。正规文法是一种3型文法,在之前的编译器基础中已有介绍。正则文法可以用来描述正规集,从而描述程序涉及语言的语法部分。例如,我们可以用以下规则描述标识符...
编译原理学了有什么用?
词法分析器是通过词法分析程序对构成源程序的字符串从左到右的扫描, 逐个字符地读, 识别出每个单词符号, 识别出的符号一般以二元式形式输出, 即包含符号种类的编码和该符号的值。词法分析器一般以函数的形式存在, 供语法分析器调用。当然也可以一个独立的词法分析器程序存在。完成词法分析任务的程序称...
编译原理
编译原理):利用编译程序从源语言编写的源程序产生目标程序的过程; 用编译程序产生目标程序的动作。 编译就是把高级语言变成计算机可以识别的2进制语言,计算机只认识1和0,编译程序把人们熟悉的语言换成2进制的。编译程序把一个源程序翻译成目标程序的工作过程分为五个阶段:词法分析;语法分析;语...
编译原理第三版清华大学
编译器:编译器是计算机程序中应用比较多的工具,在对编译器进行前端设计时,一定要充分考虑影响因素,还要对词法、语法、语义进行分析。过程分析:将高级程序设吾言,如C、C++、Java等,翻译成计算机可以执行的机器指令代码流的过程,即是编译的过程。编译过程一般分为6个步骤,即词法分析、语法分析、语...
编译原理习题精选与解析目录
下面是一份编译原理习题精选与解析的详细目录,涵盖了编译过程中的关键环节:第1章:深入理解编译器的基础概念,为后续学习奠定基础。第2章:词法分析,探索源代码的词汇和结构,是编译的第一步。第3章:语法分析,解析语句结构,构建抽象语法树。第4章:语法制导的翻译,将语法结构转化为中间代码。第5...
循环语句的语法分析及语义分析程序设计
1.目的通过设计、编制、调试一个语法及语义分析程序,加深对语法及语义分析原理的理解。2.设计内容及要求WHILE〈布尔表达式〉DO〈赋值语句〉其中用递归下降法完成以上任务,中间代码... 1.目的通过设计、编制、调试一个语法及语义分析程序,加深对语法及语义分析原理的理解。2.设计内容及要求WHILE〈布尔表达式〉DO〈赋值...
翻译程式和编译程式的区别?
大多数翻译程式是将高阶语言编写的程式翻译为机器语言形式的可执行程式。但是也有些翻译程式将源程式翻译成其他高阶语言或者位元组码等中间形式。翻译程式不是语言处理程式。任何一种高阶程式都有一个与之对应的编译器来完成对源程式的翻译。一个编译器至少要包含三个部分的程序。词法分析器、语法...
编译原理
1 词法分析[3]词法分析是编译器前端设计的基础阶段, 在这一阶段, 编译器会根据设定的语法规则, 对源程序进行标记, 在标记的过程中, 每一处记号都代表着一类单词, 在做记号的过程中, 主要有标识符、关键字、特殊符号等类型, 编译器中包含词法分析器、输入源程序、输出识别记号符, 利用这些功能可...
编译原理内容简介
本书深入探讨了编译器构造的核心原理和基本构建技术,其中包括词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成等关键环节。它不仅涵盖了命令式编程语言的编译方法,还涵盖了面向对象语言和函数式编程语言的实现策略,为读者提供了全面的编程语言处理技术视野。在理论层面,本书强调了相关...
钭喻妇科: 1.文法简略,没有实现的部分,可以在此文法的基础上进行扩充,本程序的采用自顶向下的LL(1)文法.2.可以自动实现求First 集和 Follow 集.3.处终结符外(有些硬编码的成分),终结符的文法可以自定义,也就是说读者可以自定义文法.4.为方便理解,C语言的文法描述写成中文.5.程序将词法分析和语法分析结合起来,词法分析的结果作为语法分析的输入.6.最终结果在控制台显示的有:词法分析、First集、Follow集、Select集,在preciateResult.txt 中写入了语法分析结果,在preciateTable.txt 中写入了预测分析表.7.文法的词素之间必须有空格分开.
蕉岭县18818382084: 急求!!!用C语言编写一个编译原理实验的简单优先分析法程序 - ?
钭喻妇科: 编译原理IF条件语句的翻译程序设计—简单优先法、输出四元式通过设计、编制、调试一个条件语句的语法及语义分析程序,加深对语法及语义分析原理的理解,并实现词法分析程序对单词序列的词法检查和分析.具体做到以下几点:①对输入...
蕉岭县18818382084: 求C语言编译原理语法分析程序 - ?
钭喻妇科: 一继承的词法来自 http://blog.sina.com.cn/s/blog_67c9fc300100srad.html 二语法 用扩充的BNF表示如下:⑴<程序>::=begin<语句串>end ⑵<语句串>::=<语句>{;<语句>} ⑶<语句>::=<赋值语句> ⑷<赋值语句>::=ID:=<表达式> ⑸<...
蕉岭县18818382084: 急(高悬赏 帮个忙) 求编译原理课程设计 - --c语言实现c - 的语法分析,在线等 - ?
钭喻妇科: 语法规则及函数模块如下所示:int do_stat() { int es=0;fscanf(fp,"%s %s\n",&token,&token1); printf("%s %s\n",token,token1); es=statement(); if (es>0) return(es); fscanf(fp,"%s %s\n",&token,&token1); printf("%s %s\n",token,...
蕉岭县18818382084: C语言的语法分析器 - ?
钭喻妇科: 先做个LL(1)或者LALR的语法分析器,然后先把教材上的几个LL(1)的例子调通过.然后网上有C语言子集的文法,有人做了转成大小写这样的表述.通过那个的测试就差不多了....其实做语法分析也没多大用 编译器的难点在于语法制导、代码优化之类的,真要做C语言的完整编译器,普通的学生都几乎不可能实现....就不多说了 你可以动手开始做了 如果你有较强的程序设计能力,做个漂亮的LR(1)分析器还是可以的,实在不会就做SLR(1)这样的分析器,如果程序设计能力比较差,建议先做LL(1),那个比较好做.码字不易,望采纳!
蕉岭县18818382084: 编译原理课设实现C/C++语言词法分析器 - ?
钭喻妇科: 词法分析很简单的,就是把输入文件的字符串组合成为一个个单词就可以了.比如 void main(){} ,本来都是一个个字符,你要做的是:把它转换为 "void" , "main" , "(" , ")" , "{" , "}"等,相当于是单词了,原来的只是单个字符...当然真正的词法分析还需要有一定的语义分析和纠错功能,但是估计你暂时是用不到的...
蕉岭县18818382084: 编译原理词法分析程序怎么写 C语言或C++ - ?
钭喻妇科: #include #include #include #include using namespace std; ifstream fp("source.txt",ios::in); char cbuffer; char *key[13]={"if","else","for","while","do","return","break","continue","int","void","main","const","printf"}...
蕉岭县18818382084: 用c语言编写一个词法分析器用来识别:由任意个a或b开始后接aa再自加或自减1的字符串 - ?
钭喻妇科: 我们通过这个正规式可以知道,最后4个字符是确定的,即aa+1或aa-1.然后再判断前面的字符是否为a或b.我的想法是从后往前判断,只有当前的条件符合时再进行下面的判断. 我们可以将正规式分为4部分,于是得到一下几个判断的原则: ...
蕉岭县18818382084: C语言编译原理 - ?
钭喻妇科: C语言编译过程详解 C语言的编译链接过程是要把我们编写的一个C程序(源代码)转换成可以在硬件上运行的程序(可执行代码),需要进行编译和链接.编译就是把文本形式源代码翻译为机器语言形式的目标文件的过程.链接是把目标文件...
蕉岭县18818382084: 求帮助,编译原理语法分析实验 - ?
钭喻妇科: I found it here. 递归下降分析器的设计 递归下降分析器的设计 递归下降分析器的设计http://wenku.baidu.com/view/ee03a521dd36a32d737581b9.html there are many http://wenku.baidu.com/search?word=%B5%DD%B9%E9%CF%C2%BD%B5%B7%D6%CE%F6&lm=1&od=0