编译原理中词法分析有几种方式
1. 如何通俗易懂地解释编译原理中语法分析的过程
语法分析(Syntax analysis或Parsing)和语法分析程序(Parser)
语法分析是编译过程的一个逻辑阶段。语法分析的任务是在词法分析的基础上将单词序列组合成各类语法短语,如“程序”,“语句”,“表达式”等等.语法分析程序判断源程序在结构上是否正确.源程序的结构由上下文无关文法描述.
2. 如何通俗易懂地解释编译原理中语法分析的过程
分成词法分析,语法分析(LL算法,递归下降算法,LR算法),语义分析,运行时环境,中间代码,代码生成,代码优化这些部分。其实现在很多编译原理的教材都是按照85,86出版的那本龙书来安排教学内容的,所以那本龙书的内容格式几乎成了现在编译原理教材的定式,包括国内的教材也是如此。一般来说,大学里面的本科教学是不可能把上面的所有部分都认真讲完的,而是比较偏重于前面几个部分。像代码优化那部分东西,就像个无底洞一样,如果要认真讲,就是单独开一个学期的课也不可能讲得清楚。所以,一般对于本科生,对词法分析和语法分析掌握要求就相对要高一点了。
词法分析相对来说比较简单。可能是词法分析程序本身实现起来很简单吧,很多没有学过编译原理的人也同样可以写出各种各样的词法分析程序。不过编译原理在讲解词法分析的时候,重点把正则表达式和自动机原理加了进来,然后以一种十分标准的方式来讲解词法分析程序的产生。这样的做法道理很明显,就是要让词法分析从程序上升到理论的地步。
语法分析部分就比较麻烦一点了。现在一般有两种语法分析算法,LL自顶向下算法和LR自底向上算法。LL算法还好说,到了LR算法的时候,困难就来了。很多自学编译原理的都是遇到LR算法的理解成问题后就放弃了自学。其实这些东西都是只要大家理解就可以了,又不是像词法分析那样非得自己写出来才算真正的会。像LR算法的语法分析器,一般都是用工具Yacc来生成,实践中完全没有比较自己来实现。对于LL算法中特殊的递归下降算法,因为其实践十分简单,那么就应该要求每个学生都能自己写。当然,现在也有不少好的LL算法的语法分析器,不过要是换在非C平台,比如Java,Delphi,你不能运用YACC工具了,那么你就只有自己来写语法分析器。
3. 编译原理这科里词法分析器的主要任务是什么单词常分为哪几类识别出的单词在编译程序中如何表示
1、识别出源程序中的各个单词符号,并转换成内部编码形式
2、删除无用的空白字符回车字符以及其他非实质性字符
3、删除注释
4、进行词法检查,报告所发现的错误。
4. 编译原理词法分析
编译的词法分析,一般是先画一个状态转换图,一般是有多少分支,就有多少if语句,分支里面再分(可能有循环语句)。注意记住词的类别和词的字符串,请以以下代码为例,理会一下词法分析的大致过程。
while(s[i]!='#')
{
while(s[i]==' '||s[i]=='\t'||s[i]=='\n')
{
if(s[i]=='\n')
line++;
i++;
}
if(s[i]=='#')
break;
j=i;
if(s[i]>='a'&&s[i]<='z'||s[i]>='A'&&s[i]<='Z')
{
i++;
while(s[i]>='a'&&s[i]<='z'||s[i]>='A'&&s[i]<='Z'||s[i]>='0'&&s[i]<='9')
i++;
if((i-j)==2&&s[j]=='i'&&s[j+1]=='f')
{
strcpy(dancishuzu[dancigeshu].name,"if");
dancishuzu[dancigeshu].bianhao=4;
dancigeshu++;
}
else if((i-j)==3&&s[j]=='i'&&s[j+1]=='n'&&s[j+2]=='t')
{
strcpy(dancishuzu[dancigeshu].name,"int");
dancishuzu[dancigeshu].bianhao=2;
dancigeshu++;
}
else if((i-j)==3&&s[j]=='f'&&s[j+1]=='o'&&s[j+2]=='r')
{
strcpy(dancishuzu[dancigeshu].name,"for");
dancishuzu[dancigeshu].bianhao=6;
dancigeshu++;
}
else if((i-j)==4&&s[j]=='m'&&s[j+1]=='a'&&s[j+2]=='i'&&s[j+3]=='n')
{
strcpy(dancishuzu[dancigeshu].name,"main");
dancishuzu[dancigeshu].bianhao=1;
dancigeshu++;
}
else if ((i-j)==4&&s[j]=='c'&&s[j+1]=='h'&&s[j+2]=='a'&&s[j+3]=='r')
{
strcpy(dancishuzu[dancigeshu].name,"char");
dancishuzu[dancigeshu].bianhao=3;
dancigeshu++;
}
else if ((i-j)==4&&s[j]=='e'&&s[j+1]=='l'&&s[j+2]=='s'&&s[j+3]=='e')
{
strcpy(dancishuzu[dancigeshu].name,"else");
dancishuzu[dancigeshu].bianhao=5;
dancigeshu++;
}
else if ((i-j)==5&&s[j]=='w'&&s[j+1]=='h'&&s[j+2]=='i'&&s[j+3]=='l'&&s[j+4]=='e')
{
strcpy(dancishuzu[dancigeshu].name,"while");
dancishuzu[dancigeshu].bianhao=7;
dancigeshu++;
}
else{
dancishuzu[dancigeshu].bianhao=10;
count=0;
while(j<i)
{
dancishuzu[dancigeshu].name[count++]=s[j];
j++;
}
dancishuzu[dancigeshu].name[count]='\0';
dancigeshu++;
}
}
else if(s[i]>='0'&&s[i]<='9')
{
while(s[i]>='0'&&s[i]<='9')
i++;
dancishuzu[dancigeshu].bianhao=11;
count=0;
while(j<i)
{
dancishuzu[dancigeshu].name[count++]=s[j];
j++;
}
dancishuzu[dancigeshu].name[count]='\0';
dancigeshu++;
}
else if(s[i]=='=')
{
if(s[i+1]=='=')
{
dancishuzu[dancigeshu].bianhao=30;
strcpy(dancishuzu[dancigeshu].name,"==");
dancigeshu++;
i+=2;
}
else
{
dancishuzu[dancigeshu].bianhao=12;
strcpy(dancishuzu[dancigeshu].name,"=");
dancigeshu++;
i++;
}
}
else if(s[i]=='+')
{
dancishuzu[dancigeshu].bianhao=13;
strcpy(dancishuzu[dancigeshu].name,"+");
dancigeshu++;
i++;
}
else if(s[i]=='-')
{
dancishuzu[dancigeshu].bianhao=14;
strcpy(dancishuzu[dancigeshu].name,"-");
dancigeshu++;
i++;
}
else if(s[i]=='*')
{
dancishuzu[dancigeshu].bianhao=15;
strcpy(dancishuzu[dancigeshu].name,"*");
dancigeshu++;
i++;
}
else if(s[i]=='/')
{
dancishuzu[dancigeshu].bianhao=16;
strcpy(dancishuzu[dancigeshu].name,"/");
dancigeshu++;
i++;
}
else if(s[i]=='(')
{
i++;
dancishuzu[dancigeshu].bianhao=17;
strcpy(dancishuzu[dancigeshu].name,"(");
dancigeshu++;
}
else if(s[i]==')')
{
i++;
dancishuzu[dancigeshu].bianhao=18;
strcpy(dancishuzu[dancigeshu].name,")");
dancigeshu++;
}
else if(s[i]=='[')
{
i++;
dancishuzu[dancigeshu].bianhao=19;
strcpy(dancishuzu[dancigeshu].name,"[");
dancigeshu++;
}
else if(s[i]==']')
{
i++;
dancishuzu[dancigeshu].bianhao=20;
strcpy(dancishuzu[dancigeshu].name,"]");
dancigeshu++;
}
else if(s[i]=='{')
{
i++;
dancishuzu[dancigeshu].bianhao=21;
strcpy(dancishuzu[dancigeshu].name,"{");
dancigeshu++;
}
else if(s[i]=='}')
{
i++;
dancishuzu[dancigeshu].bianhao=22;
strcpy(dancishuzu[dancigeshu].name,"}");
dancigeshu++;
}
else if(s[i]==',')
{
i++;
dancishuzu[dancigeshu].bianhao=23;
strcpy(dancishuzu[dancigeshu].name,",");
dancigeshu++;
}
else if(s[i]==':')
{
i++;
dancishuzu[dancigeshu].bianhao=24;
strcpy(dancishuzu[dancigeshu].name,":");
dancigeshu++;
}
else if(s[i]==';')
{
i++;
dancishuzu[dancigeshu].bianhao=25;
strcpy(dancishuzu[dancigeshu].name,";");
dancigeshu++;
}
else if(s[i]=='>')
{
if(s[i+1]=='=')
{
dancishuzu[dancigeshu].bianhao=28;
strcpy(dancishuzu[dancigeshu].name,">=");
dancigeshu++;
i+=2;
}
else
{
i++;
dancishuzu[dancigeshu].bianhao=26;
strcpy(dancishuzu[dancigeshu].name,">");
dancigeshu++;
}
}
else if(s[i]=='<')
{
if(s[i+1]=='=')
{
dancishuzu[dancigeshu].bianhao=29;
strcpy(dancishuzu[dancigeshu].name,"<=");
dancigeshu++;
i+=2;
}
else
{
i++;
dancishuzu[dancigeshu].bianhao=27;
strcpy(dancishuzu[dancigeshu].name,"<");
dancigeshu++;
}
}
else if(s[i]=='!'&&s[i+1]=='=')
{
dancishuzu[dancigeshu].bianhao=31;
strcpy(dancishuzu[dancigeshu].name,"!=");
dancigeshu++;
i+=2;
}
else
{
printf("\nline:%derror!",line);
i++;
return;
}
}
5. 编译的哪个阶段(词法分析,语法分析,语义分析
在编译原理中,语法规则和词法规则不同之处在于:规则主要识别单词,而语法主要识别多个单词组成的句子。词法分析和词法分析程序:词法分析阶段是编译过程的第一个阶段。这个阶段的任务是从左到右一个字符一个字符地读入源程序,即对构成源程序的字符流进行扫描然后根据构词规则识别单词(也称单词符号或符号)。词法分析程序实现这个任务。词法分析程序可以使用lex等工具自动生成。语法分析(Syntax analysis或Parsing)和语法分析程序(Parser) 语法分析是编译过程的一个逻辑阶段。语法分析的任务是在词法分析的基础上将单词序列组合成各类语法短语,如“程序”,“语句”,“表达式”等等.语法分析程序判断源程序在结构上是否正确.源程序的结构由上下文无关文法描述.语义分析(Syntax analysis) 语义分析是编译过程的一个逻辑阶段. 语义分析的任务是对结构上正确的源程序进行上下文有关性质的审查, 进行类型审查.语义分析将审查类型并报告错误:不能在表达式中使用一个数组变量,赋值语句的右端和左端的类型不匹配.
6. 编译原理关于语法分析
这都五年,这个问题还没有解决吗?我们现在也急需要答案啊,实在是无能为力了。
7. 请问编译原理中什么叫完成词法分析,语法分析
以你说的SQL语句为例,词法分析是将语句中的单词流识别出来,比如create table Student 词法分析是分析出 这句的单词流是 “create” “table” “identifier”(前提是你给它们编号 比如用宏或者枚举),然后语法分析 是通过单词流 判断 非逻辑错误 比如 有不能识别的符号 create table后面不是标示符等等 语义分析是分析语句的逻辑关系 比如字段长度越界什么的如 vchar(2) 你赋值为“啊啊啊啊啊啊”这种错误的识别是语义分析阶段完成的 希望能帮到你
8. 编译原理 词法分析
C语言词法分析器
#include<iostream>
#include<stdio.h>
#include<string>
using namespace std;
FILE *f; //定义一个文件变量
static int line = 1; //表示光标所在的行数
struct ID{ char *name; int count;}id[100];//用于存放ID号码
static int I = 0; //用于记录ID存放的数量
int Number[100]; //用于存放数字
static int P = 0; //用于记录存放数字的个数
int error[100] = {0}; //用于记录错误所在的行数
static int K = 0; //记录错误次数
void Error(); //记录错误
void loginID(char *); //注册ID号
void loginNumber(int &); //记录数字
void noteLine(char &); //记录光标所在的行数
void print(); //输出分析结果
int same(char *chr); //判断单词是否已经存在
void Error()
{ error[K++] = line; }
void loginID(char *chr) //注册ID号
{
int k = 0;
int h = 0;
for(int i = 0; i < I; i++)
{
if(!strcmp(chr,id.name)) //如果单词已经存在
{
id.count++;
k = 1;
}
}
if(k == 0) //该单词不存在
{
h = I + 1;
//I = h;
id[h].count++;
id[h].name = chr;
//strcpy(id[h].name ,chr);
}
}
void loginNumber(int &nu)
{ Number[P++] = nu; }
void noteLine(char &ch)
{
if ( ch == ' ' )
++line;
}
void print()//输出部分
{
//cout << "关键字以及变量:" << endl;
//for(int i = 0; i < 100; i++)
//cout << i <<" " << id.name << " " << id.count << endl;
cout << "数字:" << endl;
for(int i = 1; i <= P; i++)
cout << i << ": " << Number[i-1] << endl;
if(error[0] != 0)
{
cout << "出现的错误!" << endl;
for(int i = 1; i <= K; i++)
cout << "第" << i << "个错误: " << "第" << error[i-1] << "行" << endl;
}
else cout << "没有错误!" << endl;
}
//文件处理部分
void noblank( char &ch) //跳过空格,回车
{
noteLine(ch);
while(ch == ' ' || ch == ' ')
ch = fgetc(f);
}
void identifier(char name[],char &ch)//字母变量
{
int i;
for(i = 0; i < 20; i++)
name = '';
i = 0;
while (('0'<= ch && ch <= '9')||('a'<= ch&&ch <= 'z')||('A'<= ch&&ch <='Z'))
{
name = ch;
i++;
ch = fgetc(f);
}
loginID(name);
//for(int j = 0; j < i; j++)
//{cout << name[j];}
// cout << ' ';
}
int number(char &ch)//数字
{
int num=0;
while('0'<= ch && ch <= '9')
{
num = num* 10 + (ch-'0');
ch = fgetc(f);
}
if( ('a'<= ch&&ch <= 'z')||('A'<= ch&&ch <='Z'))
{
Error();
}
else if( ch == '.')
{;}
loginNumber(num); //记录数字
return num;
}
void test(char &ch)//符号
{
char str[2]={'0/'};
if(ch == '*')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '.')
{ str[0] = ch; ch = fgetc(f);}
if(ch == ',')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '"')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '/')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '%')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '^')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '-')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '{')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '}')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '[')
{ str[0] = ch; ch = fgetc(f);}
if(ch == ']')
{ str[0] = ch; ch = fgetc(f);}
if(ch == ';')
{str[0] = ch; ch = fgetc(f);}
if(ch == ':')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '?')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '(')
{ str[0] = ch; ch = fgetc(f);}
if(ch == ')')
{str[0] = ch; ch = fgetc(f);}
if(ch =='+')
{
str[0] = ch;
if((ch = fgetc(f)) == '+' )
{
str[1] = ch;
ch = fgetc(f);
//cout << str[0] << str[1] << endl;
}
//cout << str[0]<< endl;
}
if(ch == '-')
{
str[0] = ch;
if((ch = fgetc(f)) == '-' )
{
str[1] = ch;
ch = fgetc(f);
//cout << str[0] << str[1] << endl;
}
//cout << str[0]<< endl;
}
if(ch == '&')
{
str[0] = ch;
if((ch = fgetc(f)) == '&' )
{
str[1] = ch;
ch = fgetc(f);
//cout << str[0] << str[1] << endl;
}
//cout << str[0]<< endl;
}
if(ch == '|')
{
str[0] = ch;
if((ch = fgetc(f)) == '|' )
{
str[1] = ch;
ch = fgetc(f);
//cout << str[0] << str[1] << endl;
}
//cout << str[0]<< endl;
}
if(ch == '!')
{
str[0] = ch;
if((ch = fgetc(f)) == '=' )
{
str[1] = ch;
ch = fgetc(f);
//cout << str[0] << str[1] << endl;
}
//cout << str[0]<< endl;
}
if(ch == '=')
{
str[0] = ch;
if((ch = fgetc(f)) == '=' )
{
str[1] = ch;
ch = fgetc(f);
//cout << str[0] << str[1] << endl;
}
}
if(ch == '>')
{
str[0] = ch;
if((ch = fgetc(f)) == '=' )
{
str[1] = ch;
ch = fgetc(f);
//cout << str[0] << str[1] << endl;
}
else
if(ch == '>' )
{
str[1] = ch;
ch = fgetc(f);
//cout << str[0] << str[1] << endl;
}
}
if(ch == '<')
{
str[0] = ch;
if((ch = fgetc(f)) == '=' )
{
str[1] = ch;
ch = fgetc(f);
}
else
if(ch == '<' )
{
str[1] = ch;
ch = fgetc(f);
}
}
}
int main()
{
char ch;
char name[30];
for(int i = 0; i < 30; i++)
name = '/0';
f = fopen("c.txt","r"); //打开指定输入文件
if (f == NULL)
cout<<"文件不存在!"<<endl;
ch = fgetc(f);
while(!feof(f))
{
noblank( ch ); //跳过回车,空格
if( ( ch >= 'a' && ch <= 'z' )||( ch >= 'A' && ch <= 'Z' ))
{ identifier(name,ch); } //处理字母
else if( ch >= '0'&& ch <= '9')
{ number(ch); } //处理数字
else
{ test(ch); } //处理符号
}
print(); //打印词法分析结果
fclose(f); //关闭文件
system("pause");
return 0;
}
9. 怎样较容易理解编译原理中词法分析的原理即实现过程,最好配上图文解说
词法分析的本质是让计算机程序理解词法规则。例如,在我们平时用的语言里,“你”是指一个人,当“你们”出现的时候就是一个词是指多个人,这就是一种规则,但是是人能理解的规则,词法分析要用数学的表达方式让计算机理解,计算机的做法是对每个遇到的字先判断是不是“你”,如果不是,那么不符合这条规则;如果是,就要记下现在这个状态---即已经看到一个“你”字,然后判断下一个字是不是“们”,是则这条规则成立,也就是让计算机理解了这一个词,而不是单个的两个字。词法分析不是编译原理才有的,在搜索、数据挖掘等领域都用到。编译原理中的词法分析就是把源程序中的字符按顺序一个一个输入给计算机,计算机对每个字符按照所有规则进行判断,例如输入了一个“a”,要判断它是不是“and“的开头,是不是一个变量名,函数名,还是字符串等等,每个可能性都是一条规则决定的。根据规则的复杂性,可以用多种数学方法描述,比如基本的方法是状态机、正则表达式。
10. 编译原理 词法分析
你收到了吗,能给我发一份吗