Ⅰ 编译原理文法分析
改完了,能文法分析出来了!!
大概 跟你说下 你的错误吧:
出错地点:
1.声明的stack[50]没有初始化;
2.stack的入栈是错误的,按照你的方式,如果原来有TM,再加入T->FN,则M就被挤出来了.(这里很关键,你对照我给你改的再看看)
3.s指针在你入栈操作以后并没有指向栈顶,而是保持了不变,这肯定是有问题的.(传入push函数的时候直接传参数s就好了.)
4.if(*s==*p){***}else{}的else的右括号管辖的范围 有错误
不嫌弃的话,可以去http://blog.csdn.net/fangguanya,我的BLOG,不怎么充实,呵呵,有这个程序的运行结果的. 谢谢 呵呵.
总之你对照我给你改的再看看吧. 我把我的测试输出 也给保留了.你好对照点.
(PS.我用的vs2005,用的时候你改下头申明,其他一样)
// grammar.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include<iostream>
using namespace std;
char * spush(char *stack,char *pt);
bool analyse(char *p);
void main()
{
//将分析串存放在二维数组中
char input[5][10]={"i+i#",
"i*(i+i)#",
"i*i+i#",
"i+*#",
"+i*i#"};
bool flag; //定义一个布尔型的标记量
for(int h=0;h<5;++h)
{
flag=analyse(input[h]);
if(flag) cout<<"恭喜你!"<<input[h]<<"语法分析成功,合法!"<<endl;
else cout<<"对不起!"<<input[h]<<"语法分析失败,非法!"<<endl;
}
int aaa;
cin>>aaa;
}
//定义各一将串逆序入栈的函数
char * spush(char *stack,char *pt)
{
int l=0;
//while循环的作用是将指针指向字符串的末尾,然后再由后向前入栈,从而实现逆序
while(*pt!='\0')
{
pt++;
l++;
}
if (*stack == '#')
{
stack++;
}
while(l)
{
pt--;
char cTempIntoStack = (*pt);
*stack=cTempIntoStack;
stack++;
l--;
}
stack--; //由于前面向前加了一位,要返回
////////////////
return stack;
///////////////////////////////////
}
/*LL(1)分析表
i + * ( ) #
E TM +TM
F i (E)
M TM e e
N e *FN e e
T FN FN
*/
//分析函数
bool analyse(char *p){
char analyseTable[5][6][4]={
"TM", "", "", "TM", "", "",
"i", "", "", "(E)", "", "",
"", "+TM", "", "", "e", "e",
"", "e", "*FN", "", "e", "e",
"FN", "", "", "TN", "", ""
};
char *stack = new char[50]; //定义一个栈空间
for (int iStack = 0;iStack<50 ;iStack++)
{
stack[iStack] = 0;
}
char *s=stack; //用指针*s指向栈的起始地址
*s='#'; //将“#”入栈
s++; //指针加1
*s='E'; //将“E”入栈
//下面的while循环实现字符串的词法分析操作
int count = 0;
while(*s!='#' || *p!='#'){
count++;
char * temp = s;
cout<<"NO."<<count<<endl;
cout<<"STACK"<<endl;
while (*temp != '#')
{
cout<<*temp<<" ";
temp--;
}
cout<<endl;
int x,y;
//若果栈顶数据和分析串的字符匹配,则将符号栈的栈顶数据出栈(即将栈顶指针减1)
if(*s==*p){
cout<<"Before :"<<*s<<endl;
s--;
p++;
cout<<"After :"<<*s<<endl;
}
//当符号栈和分析串的字符不匹配时,查分析表
else {
switch(*s){
case 'E':x=0;break;
case 'F':x=1;break;
case 'M':x=2;break;
case 'N':x=3;break;
case 'T':x=4;break;
default:return false;
}
switch(*p){
case 'i':y=0;break;
case '+':y=1;break;
case '*':y=2;break;
case '(':y=3;break;
case ')':y=4;break;
case '#':y=5;break;
default:return false;
}
//若果对应的为空,则分析串非法,退出
if(analyseTable[x][y][0]=='\0') return false;
//若查表所对应的为'e',则将符号栈的栈顶数据出栈
else if(analyseTable[x][y][0]=='e') s--;
//其它,这时将查表所得的项逆序入符号栈
else {
s=spush(s,analyseTable[x][y]);
}
}
}
return true; //分析成功,返回
}
Ⅱ 编译原理正则表达式化简
你好,语言L={a}{a,b}∗({ϵ}∪({.,_}{a,b}{a,b}∗))L={a}{a,b}
∗
({ϵ}∪({.,_}{a,b}{a,b}
∗
))
这个语言是指,由a开头,后接任意长度的a、b串,然后再接空串(代表结束)。或者是接以.或_开头的,后接长度大于等于1的a、b串。
正则表达式(Regular Expression, RE)是一种用来描述正则语言的更紧凑的表示方法。
Ⅲ 什么是编译原理
编译原理是计算机专业的一门重要专业课,旨在介绍编译程序构造的一般原理和基本方法。内容包括语言和文法、词法分析、语法分析、语法制导翻译、中间代码生成、存储管理、代码优化和目标代码生成。 编译原理是计算机专业设置的一门重要的专业课程。虽然只有少数人从事编译方面的工作,但是这门课在理论、技术、方法上都对学生提供了系统而有效的训练,有利于提高软件人员的素质和能力。
这门课程关注的是编译器方面的产生原理和技术问题,似乎和计算机的基础领域不沾边,可是编译原理却一直作为大学本科的 必修课程,同时也成为了研究生入学考试的必考内容。编译原理及技术从本质上来讲就是一个算法问题而已,当然由于这个问题十分复杂,其解决算法也相对复杂。 我们学的数据结构与算法分析也是讲算法的,不过讲的基础算法,换句话说讲的是算法导论,而编译原理这门课程讲的就是比较专注解决一种的算法了。在20世纪 50年代,编译器的编写一直被认为是十分困难的事情,第一Fortran的编译器据说花了18年的时间才完成。在人们尝试编写编译器的同时,诞生了许多跟 编译相关的理论和技术,而这些理论和技术比一个实际的编译器本身价值更大。就犹如数学家们在解决着名的哥德巴赫猜想一样,虽然没有最终解决问题,但是其间 诞生不少名着的相关数论。
Ⅳ 编译原理的文法是什么
文法是描述语言规则的形式规则。实际上就是用一个四元组G=(VT,VN,S,P)定义的一个推理方式。其中VT是终结符,VN是非终结符,S是开始符号,P是一组产生规则。
Ⅳ 编译原理 文法
构造LR(1)语法分析表,没有冲突就是了。
Ⅵ 编译原理文法问题,急急急
第一题
S->AB
A->aA'b
A'->aA'b|ε
B->B'
B'->dB'|ε
----------------------
第二题
S->aS'b
S'->aS'b|D
D->dD|ε
----------------------
第三题
最左推导的话,我认为要先消除左递归才行(把左递归转成右递归),消除之后:
N->DN'
N'->DN'|ε
D->0|1|2|...|9
最左推导为 N->DN'->2N'->2DN'->25N'->25DN'->258N'->258
规范推导(最右推导)为N->ND->N8->ND8->N58->D58->258
----------------------
第四题
构造一下语法树就知道了。直接短语是深度为2的节点(根节点是深度0)。短语是深度为2的节点代入深度为1的产生式中。句柄是所有直接短语中最左的那个。
1.baaa
>>>
_________S
_______/___\
______A_____B
_____/__\____|
____A___a___a
___/__\
__b___B
_______|
______a
直接短语为 Aa、a
短语为 Aaa
句柄为 Aa
2.bBaa
>>>
_________S
_______/___\
______A_____B
_____/__\____|
____A___a___a
___/__\
__b___B
直接短语为 Aa、a
短语为 Aaa
句柄为 Aa
Ⅶ 编译原理,为文法添加语义规则,求图片上题的详细解答过程,越细越好,完全不会啊,求大神指导。。
每个产生式后面{ }中的内容即语义子程序。
给每个非终结符设计一个语义值VAL,表示该非终结符对应的值
Ⅷ 编译原理, 写一个简单文法的词法/语法分析器有简单的方法吗
那就用 lex 和 yacc 写
不过实验课程就是让你手算一次
如果你用工具直接生成了意义不大
Ⅸ 编译原理中的语法和文法一样吗
编译原理中的语法和文法是不一样的,但却融会贯通。
在计算机科学中,文法是编译原理的基础,是描述一门程序设计语言和实现其编译器的方法。
文法分成四种类型,即0型、1型、2型和3型。这几类文法的差别在于对产生式施加不同的限制。
形式语言,这种理论对计算机科学有着深刻的影响,特别是对程序设计语言的设计、编译方法和计算复杂性等方面更有重大的作用。
多数程序设计语言的单词的语法都能用正规文法或3型文法(3型文法G=(VN,VT,P,S)的P中的规则有两种形式:一种是前面定义的形式,即:A→aB或A→a其中A,B∈VN ,a∈VT*,另一种形式是:A→Ba或A→a,前者称为右线性文法,后者称为左线性文法。正规文法所描述的是VT*上的正规集)来描述。
四个文法类的定义是逐渐增加限制的,因此每一种正规文法都是上下文无关的,每一种上下文无关文法都是上下文有关的,而每一种上下文有关文法都是0型文法。称0型文法产生的语言为0型语言。上下文有关文法、上下文无关文法和正规文法产生的语言分别称为上下文有关语言、上下文无关语言和正规语言。