设计一个小语言的词法分析程序
上学时候写的恶心东西,如果你能忍受的话。。。
在“getsource.txt”中输入要分析的小程序,保存后放到和EXE一个目录。“savedsource.txt”和“bastable.txt”将自动生成。
例如“getsource.txt”内容为:
#include "Stdio.h"
#include "Conio.h"
int main(void)
{
char *p="ab";
printf("%d",sizeof(*p));
getch();
return 0;
}
源程序:
#include
#include
#include
#include
//#include
//#include
//#include
//词法分析方法的头文件//
/*#define
undefine 0
keyword 1
divsymbol 2
symbol 3
num 4
id 5
*/
double value;
int evalue;
int token;
int pp=0;
int line=0;
int basicp=0;
int nump=0;
int idp=0;
int nullp=0;
//存放关键字(共26个)
struct keyword
{
char g[20];
}key[]={"int","char","float","long","double","if","else","break","case","#include","#define","continue","do","for","goto","return","short","struct","switch","typedef","static","void","while","unsigned","true","false"};
//存放界符(以ASC码的形式,共10个)
struct div_symbol
{
char j;
}divsym[]={40,41,91,93,123,125,39,34,44,59};
//存放运算符号(共24个)
struct symbol
{
char f[3];
}sym[]={"+","-","*","/","%","","==",">=",">"};
//词法分析总表(初始为空)
struct bastable
{
int type;
int location;
}basic[8192];
//存放常数(初始为空)
struct num_table
{
double constant;
}num[1024];
//存放标识符(初始为空)
struct id_table
{
char name[50];
}id[1024];
//存放无类型(初始为空)
struct null_table
{
char str[50];
}null[1024];
/*************************************************************************************************/
//以下为各种类型判断的函数//
//界符判断
int if_divsymbol(char aa[])
{
int i;
int len=strlen(aa);
for(i=0;i<=9;i++)
{
if(aa[0]==divsym[i].j&&len==1)
return i+1;
}
return 0;
}
//运算符号判断
int if_symbol(char aa[])
{
int i;
for(i=0;i<=23;i++)
{
if(strcmp(aa,sym[i].f)==0)
return i+1;
}
return 0;
}
//关键字判断
int if_keyword(char aa[])
{
int i;
for(i=0;i<=25;i++)
{
if(strcmp(aa,key[i].g)==0)
return i+1;
}
return 0;
}
//e后面数字的判断
int if_enum(int k,char aa[])
{
int i,len=strlen(aa),ezf=1;
evalue=0;
if(aa[k+1]=='+')
{
k++;
ezf=1;
}
else if(aa[k+1]=='-')
{
k++;
ezf=-1;
}
for(i=k+1;i<=len-1;i++)
{
if(isdigit(aa[i]))
evalue=evalue*10+aa[i]-'0';
else return 0;
}
evalue=evalue*ezf;
return 1;
}
//数字判断
int if_num(char aa[])
{
int k=0,zf=1,len=strlen(aa),dian=0,elen=len,i;
int m=0;
int n=0;
value=0;
evalue=0;
if(aa[0]=='+')
{
k=1;
zf=1;
}
else if(aa[0]=='-')
{
k=1;
zf=-1;
}
for(i=k;i<=len-1;i++)
{
if(aa[i]=='e'||aa[i]=='E')
elen=i;
}
for(i=k;i<=len-1;i++)
{
if(aa[i]=='.'&&dian==0)
{
dian=1;
m=(elen-i-1)*(-1);
}
else if((aa[i]=='e'||aa[i]=='E')&&i!=len-1&&i!=k)
{
n=if_enum(i,aa);
if(n)
{
value=value*pow(10,m)*pow(10,evalue)*zf;
return 1;
}
else return 0;
}
else if(isdigit(aa[i]))
value=value*10+aa[i]-'0';
else return 0;
}
value=value*pow(10,m)*pow(10,evalue)*zf;
return 1;
}
//标识符判断
int if_id(char aa[])
{
int i;
int len=strlen(aa);
if(isalpha(aa[0])||(aa[0]=='_'&&len!=1))
{
for(i=1;i<=len-1;i++)
{
if(isalpha(aa[i])||isdigit(aa[i])||aa[i]=='_')
;
else return 0;
}
return 1;
}
else return 0;
}
//存入各表
void write_table(char aa[])
{
token=0;
int flag;
int i;
int t;
if(t=if_keyword(aa))
{
token=1;
basic[basicp].type=token;
basic[basicp].location=t-1;
basicp++;
}
else if(t=if_symbol(aa))
{
token=2;
basic[basicp].type=token;
basic[basicp].location=t-1;
basicp++;
}
else if(t=if_divsymbol(aa))
{
token=3;
basic[basicp].type=token;
basic[basicp].location=t-1;
basicp++;
}
else if(if_num(aa))
{
token=4;
num[nump].constant=value;
basic[basicp].type=token;
basic[basicp].location=nump;
nump++;
basicp++;
}
else if(if_id(aa))
{
flag=0;
token=5;
for(i=0;i<idp;i++)
{
if(strcmp(aa,id[i].name)==0)
{
basic[basicp].type=token;
basic[basicp].location=i;
basicp++;
flag=1;
break;
}
}
if(!flag)
{
strcpy(id[idp].name,aa);
basic[basicp].type=token;
basic[basicp].location=idp;
basicp++;
idp++;
}
}
else if(pp==1&&token==0)
{
flag=0;
for(i=0;i<nullp;i++)
{
if(strcmp(aa,null[i].str)==0)
{
basic[basicp].type=token;
basic[basicp].location=i;
basicp++;
flag=1;
break;
}
}
if(!flag)
{
strcpy(null[nullp].str,aa);
basic[basicp].type=token;
basic[basicp].location=nullp;
nullp++;
basicp++;
}
}
}
//判断是否有分割符
void divide_2nd(char aa[])
{
pp=1;
char bb[50];
int i=0;
int g=0;
int k=0;
int l=0;
int q=0;
int len=strlen(aa);
while(k<=len-1)
{
if((aa[k]=='&'&&aa[k+1]=='&')||(aa[k]=='|'&&aa[k+1]=='|')||(aa[k]=='='&&aa[k+1]=='=')||(aa[k]=='!'&&aa[k+1]=='=')||(aa[k]=='>'&&aa[k+1]=='=')||(aa[k]==''&&aa[k+1]=='>'))
{
q=0;
for(i=l;i<=k-1;i++)
{
bb[q]=aa[i];
q++;
}
if(q!=0)
{
bb[q]='\0';
write_table(bb);
}
bb[0]=aa[k];
bb[1]=aa[k+1];
bb[2]='\0';
write_table(bb);
l=k+2;
k++;
}
else if((aa[k]=='=')||aa[k]=='+'||aa[k]=='-'||aa[k]=='*'||aa[k]=='/'||aa[k]=='!'||aa[k]=='%'||aa[k]=='~'||aa[k]=='|'||aa[k]=='^'||aa[k]=='&'||aa[k]=='')
{
q=0;
for(i=l;i<=k-1;i++)
{
bb[q]=aa[i];
q++;
}
if(q!=0)
{
bb[q]='\0';
write_table(bb);
}
bb[0]=aa[k];
bb[1]='\0';
write_table(bb);
l=k+1;
}
for(g=0;g<=9;g++)
{
if(aa[k]==divsym[g].j)
{
q=0;
for(i=l;i<=k-1;i++)
{
bb[q]=aa[i];
q++;
}
if(q!=0)
{
bb[q]='\0';
write_table(bb);
}
bb[0]=aa[k];
bb[1]='\0';
write_table(bb);
l=k+1;
}
}
k++;
}
if(l!=len)
{
q=0;
for(i=l;i<=k-1;i++)
{
bb[q]=aa[i];
q++;
}
bb[q]='\0';
write_table(bb);
}
}
//分割单词
void divide_1st(char bb[])
{
char aa[512];
int i=0,l=0,k=0,q=0;
line=1;
int len=strlen(bb);
while(k<=len)
{
if(bb[k]==' '||bb[k]=='
'||bb[k]=='\0'||bb[k]=='')
{
q=0;
if(bb[k]=='
')
line=line+1;
for(i=l;i<k;i++)
{
aa[q]=bb[i];
q++;
}
if(q!=0)
{
aa[q]='\0';
pp=0;
write_table(aa);
if(token==0)
divide_2nd(aa);
}
l=k+1;
}
k++;
}
}
//保存源代码
void savesource(char bb[])
{
FILE * fp;
if((fp=fopen("savedsource.txt","w"))==NULL)
{
cout<<"Open file "<<"savedsource.txt"<<" failed!"<<endl;
exit(0);
}
if(fwrite(bb,strlen(bb),1,fp)!=1)
cout<<"File "<<"savedsource.txt"<<" write error!"<<endl;
fclose(fp);
}
//输出总表到文本中
void read_table_to_txt()
{
FILE * fp;
int i;
if((fp=fopen("bastable.txt","w"))==NULL)
{
cout<<"Open file "<<"bastable.txt"<<" failed!"<<endl;
exit(0);
}
fputs(" 类型索引 子表索引 (真值)
===================================================================
",fp);
for(i=0;i<basicp;i++)
{
switch(basic[i].type)
{
case 1:fputs("(关键字)",fp);break;
case 2:fputs("(运算符)",fp);break;
case 3:fputs("(分隔符)",fp);break;
case 4:fputs("(常数型)",fp);break;
case 5:fputs("(标识符)",fp);break;
default:fputs("(无类型)",fp);
}
fprintf(fp,"%d",basic[i].type);
fputs("__________________",fp);
fprintf(fp,"%d",basic[i].location);
fputc('',fp);
switch(basic[i].type)
{
case 1:fputs(key[basic[i].location].g,fp);break;
case 2:fputs(sym[basic[i].location].f,fp);break;
case 3:fputc(divsym[basic[i].location].j,fp);break;
case 4:fprintf(fp,"%f",num[basic[i].location].constant);break;
case 5:fputs(id[basic[i].location].name,fp);break;
default:fputs(null[basic[i].location].str,fp);fputc('
',fp);
}
fputc('
',fp);
}
fclose(fp);
}
void display()
{
char bb[524288];
char ch;
int i=0;
FILE * fp;
if((fp=fopen("getsource.txt","r"))==NULL)
{
cout<<"Open file "<<"getsource.txt"<<" failed!"<<endl;
exit(0);
}
ch=fgetc(fp);
while(ch!=EOF)
{
bb[i]=ch;
ch=fgetc(fp);
i++;
}
fclose(fp);
bb[i]='\0';
savesource(bb);
divide_1st(bb);
read_table_to_txt();
cout<<"分析结束!"<<endl;
cout<<"源代码保存成功!"<<''<<"(查看savedsource.txt)"<<endl;
cout<<"总表保存成功!"<<''<<"(查看bastable.txt)"<<endl;
cout<<"总行数="<<line<<endl;
printf("Press any key to continue");
getch();
}
void main()
{
display();
}
#include
#include
#include
#define _KEY_WORD_END "waiting for your expanding"
typedef struct
{
int typenum;
char * word;
} WORD;
char input[255];
char token[255]="";
int p_input;
int p_token;
char ch;
char* KEY_WORDS[]={"main","int","char","if","else","for","while",_KEY_WORD_END};
WORD* scaner();
void main()
{
int over=1;
WORD* oneword=new WORD;
printf("Enter Your words(end with $):");
scanf("%[^$]s",input);
p_input=0;
printf("Your words:
%s
",input);
while(over<1000&&over!=-1){
oneword=scaner();
if(oneword->typenum<1000)
printf("(%d,%s)",oneword->typenum,oneword->word);
over=oneword->typenum;
}
printf("
press # to exit:");
scanf("%[^#]s",input);
}
char m_getch(){
ch=input[p_input];
p_input=p_input+1;
return (ch);
}
void getbc(){
while(ch==' '||ch==10){
ch=input[p_input];
p_input=p_input+1;
}
}
void concat(){
token[p_token]=ch;
p_token=p_token+1;
token[p_token]='\0';
}
int letter(){
if(ch>='a'&&ch='A'&&ch<='Z')return 1;
else return 0;
}
int digit(){
if(ch>='0'&&ch<='9')return 1;
else return 0;
}
int reserve(){
int i=0;
while(strcmp(KEY_WORDS[i],_KEY_WORD_END)){
if(!strcmp(KEY_WORDS[i],token)){
return i+1;
}
i=i+1;
}
return 10;
}
void retract(){
p_input=p_input-1;
}
char* dtb(){
return NULL;
}
WORD* scaner(){
WORD* myword=new WORD;
myword->typenum=10;
myword->word="";
p_token=0;
m_getch();
getbc();
if(letter()){
while(letter()||digit()){
concat();
m_getch();
}
retract();
myword->typenum=reserve();
myword->word=token;
return(myword);
}
else if(digit()){
while(digit()){
concat();
m_getch();
}
retract();
myword->typenum=20;
myword->word=token;
return(myword);
}
else switch(ch){
case '=': m_getch();
if (ch=='='){
myword->typenum=39;
myword->word="==";
return(myword);
}
retract();
myword->typenum=21;
myword->word="=";
return(myword);
break;
case '+': myword->typenum=22;
myword->word="+";
return(myword);
break;
case '-': myword->typenum=23;
myword->word="-";
return(myword);
break;
case '*': myword->typenum=24;
myword->word="*";
return(myword);
break;
case '/': myword->typenum=25;
myword->word="/";
return(myword);
break;
case '(': myword->typenum=26;
myword->word="(";
return(myword);
break;
case ')': myword->typenum=27;
myword->word=")";
return(myword);
break;
case '[': myword->typenum=28;
myword->word="[";
return(myword);
break;
case ']': myword->typenum=29;
myword->word="]";
return(myword);
break;
case '{': myword->typenum=30;
myword->word="{";
return(myword);
break;
case '}': myword->typenum=31;
myword->word="}";
return(myword);
break;
case ',': myword->typenum=32;
myword->word=",";
return(myword);
break;
case ':': myword->typenum=33;
myword->word=":";
return(myword);
break;
case ';': myword->typenum=34;
myword->word=";";
return(myword);
break;
case '>': m_getch();
if (ch=='='){
myword->typenum=37;
myword->word=">=";
return(myword);
}
retract();
myword->typenum=35;
myword->word=">";
return(myword);
break;
case '<': m_getch();
if (ch=='='){
myword->typenum=38;
myword->word="<=";
return(myword);
}
retract();
myword->typenum=36;
myword->word="<";
return(myword);
break;
case '!': m_getch();
if (ch=='='){
myword->typenum=40;
myword->word="!=";
return(myword);
}
retract();
myword->typenum=-1;
myword->word="ERROR";
return(myword);
break;
case '\0': myword->typenum=1000;
myword->word="OVER";
return(myword);
break;
default: myword->typenum=-1;
myword->word="ERROR";
return(myword);
}
}
源程序设计语言 G[<程序>]
<程序>→<变量说明><BEGIN> <语句表> <END>.
<变量说明>→VAR<变量表>:<类型>;|<空>
<变量表>→<变量表>,<变量>|<变量>
<类型>→INTEGER
<语句表>→<语句> | <语句>;<语句表>
<语句>→<赋值语句>|<条件语句>|<WHILE语句>|<复合语句>
<赋值语句>→<变量>:=<算术表达式>
<条件语句>→IF<关系表达式>THEN<语句>ELSE<语句>
<WHILE语句>→WHILE<关系表达式>DO<语句>
<复合语句>→BEGIN<语句表>END
<算术表达式>→<项>|<算术表达式>+<项>|<算术表达式>-<项>
<项>→<因式>|<项>*<因式>|<项>/<因式>
<因式>→<变量>|<整数>|(<算术表达式>)
<关系表达式>→<算术表达式><关系符><算术表达式>
<变量>→<标识符>
<标识符>→<标识符><字母>|<标识符><数字>|<字母>
<整数>→0|<非零数字><泛整数>
<泛整数>→<数字>|<数字><泛整数>|ε
<关系符>→<|<=|==|>|>=|<>
<字母>
→A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z
<非零数字>→1|2|3|4|5|6|7|8|9
<数字>→<非零数字>|0
<空>→
要求和提示:
词法分析阶段,可以打开任意位置和名称的源文件进行词法分析,可以进行非法字符和数字后边跟字母的错误判断,如果没有错误则提示“词法分析正确完成!”,并且可以选择输出token.txt(token文件)string.txt(符号表)两个文件;
1.词法分析程序的主要任务如下:
① 组织源程序的输入,识别出源程序中的各个基本语法单位(也称为单词或语法符号),按规则转换成二元式的形式;
② 删除无用的空白字符、回车符、及其它非实质性符号;
③ 删除注解行;
④ 为后面的语法和语义分析提供二元式链表;
单词 编码 单词 编码
标识符 1 < 15
正整数 2 <= 16
BEGIN 3 > 17
END 4 >= 18
IF 5 <> 19
THEN 6 == 20
ELSE 7 ; 21
WHILE 8 . 22
DO 9 := 23
INTEGER 10 , 24
+ 11 ( 25
- 12 ) 26
* 13
/ 14
1) 对标识符的长度控制在8个字符(包括8个)以内,超过的做截断处理;
2) 数字不大于65535,否则报错;
3) 能跳过源程序中的空白格:两个单词之间的任何空格,制表符,回车,换行都是白空格,除了用来分隔单词以外,没有意义;
4) 能跳过注释:
a) 接连出现的/*到下一次接连出现的*/之间的任何文字都是注释(多行);
b) 从某行接连出现的//到该行的结尾的任何文字都是注释(单行)。
3.怎样编写词法分析程序:
1) 预处理:把源文件一个字符一个字符的读入词法分析程序设置的输入字符结构体数组中(输入缓冲区),读入过程要删除注释,删除多余的白空格;
2) 从源程序字符数组中获得单词, 编码为二元式.:
二元式采用结构体数组存储, 把单词类型和词元记录下来。
分解单词的方法:
1) Case多路转换语句根据单词的特点直接编写;
2) 通过描述单词的正规文法得到相应的有穷自动机,通过case多路转换语句完成有穷自动机的处理流程。
3.编写词法分析程序要注意的问题:
1) 检查词法是否有错误
检查是否有非法字符:如 @, &, !
检查标志符和数字是否满足限制条件
检查注释符号是否配对
2) 符分隔单词
能够区分两个单词的符号为界符
有些界符不是单词:如白空格
有些界符仅仅用来分隔:如;
有些界符本身还是源程序不可缺少的单词,如(, ), +, /, 等等
有些界符包含两个字符:如<>, >=等等
3) 输出词法错误
如果有错误,需要报告词法错误的原因。并且要能够越过错误,分解下一个单词,直到源程序结束。
4) 输出的二元式流保存在二元式结构体数组中。
你好,希望采纳!
面试官:MySQL是如何执行一条查询语句的?
词法解析 词法分析就是把一个完整的SQL语句打碎成一个个的单词。 比如一个简单的SQL语句:selectnamefromuserwhereid=1andage>20; 它会将select识别出来,这是一个查询语句,接下来会将user也识别出来,你是想要在这个表中做查询,然后将where后面的条件也识别出来,原来我需要去查找这些内容。语法分析 语法分析会对...
(转)设计一个语音交互界面(Voice User Interface)
理解自然语言,即系统通过对词法、句法、语义的分析,识别(identify)用户的意图(intent)或者用户言语所涉及的领域(domain)、实体(entities),生成一个结构化的 语义表示*, 包括语言类型(陈述需求,询问属性,否定,选择疑问,等等)和条件信息(有什么条件、值是多少)。比如,“帮我查深圳的天气”这句话对应的语义表示为“in...
有穷自动机接受的语言是正则语言
形式语言理论中最简单的语言类,是上下文无关语言类的一个真子类,在乔姆斯基语言分层中处于最低层。又称3型语言。正则语言有两种描述方法文法描述;正则表达式与接受器。正则语言已应用于计算机程序语言编译的词法分析、开关电路设计等方面。正则表达式与接受器正则语言是正则集,可以用称为正则表达式的简单...
怎样学好一门语言?
前一种人学习不得法,事倍功半;后一种人学习得法,则事半功倍。学习词汇时,要“词不离句,句不离文”,这样才能正确理解词义。还要经常按词义、词性、读音或构词法等将所学单词归类,成串地记忆单词,如:care,careful,carefully,careless,carelessly,carelessness等。可把分类的单词记在小本子...
python有多少种语法(2023年最新整理)
词法是组成这个语言的基本字母和单词规范,对于python就是掌握标识符命名规则,以及保留字;句法就是这个语言的句子有哪些形式和结构,对于python就是掌握def、class、if等各种语句的规则;文法是句子组成文章的规则,对于python来说就是程序一般分几部分,开头的标题有什么规定等等。 上面只是分类总结,一个语句的语法内容还是很...
词法分析器的主要特点
本算法主要利用状态转换图生成一个词法分析器,对输入的程序进行词法分析,并将分析得到的单词造表。其中关键字表和界限符表的大小是由高级语言的子集决定的,可以用数组装载;而标识符表和常数表的大小取决于输入的待分析程序中的变量、过程名、常数的个数,所以要用指针组成动态链表来装载。当然为了方便...
请问学习时注意什么?
在当你学会了一门语言的时候(也就是说,你记住了该语言的语法,词法,还有一些常用的函数),就意味着你已经掌握了编写程序的基本工具。无论你用的是啥语言,都差不多。只是工具之间有长有短。比如说,Delphi,VB之类做windows环境的应用程序很方便;用Java开发基于网络的程序很轻松;C,C++适合开发...
如何帮助小学生巧计单词
关键词:记忆 正文: 小学生学习英语本就是一件困难的事情, 特别是在一些欠发达地 区,因为学习语言是需要语言环境的,而我们的英语教学只局限在课 堂上,大多学校每周也只开设三节课,因此,如何帮学生找到高效的 学习方法是每个英语老师必须探索的课题。笔者认为,学习英语的基 础是单词, 它是构成语...
构词法的成语 构词法的成语是什么
构词法的成语有:知法犯法,骊山北构,向壁虚构。2:拼音是、gòu cí fǎ。3:结构是、构(左右结构)词(左右结构)法(左右结构)。4:注音是、ㄍㄡ_ㄘ_ㄈㄚˇ。构词法的具体解释是什么呢,我们通过以下几个方面为您介绍:一、词语解释【点此查看计划详细内容】构词法gòucífǎ。(1)一种语言...
现代汉语是怎样的一种语言呢?
现代汉语语法特点:1、词形没有形态变化。一个词不管作主语、还是作宾语,它的发音和词形都没有什么变化。一些语法范畴和功能都不像有些英语、俄语那样通过词形的变化来表现。2、复合词为主。现代汉语的词法以词根复合构词法为主。这种方法具有很强的能产性,可以满足言语交际对词汇量的需求。而且,也...
牢径安捷: 主函数我在用消息发给你,不过消息能发的内容太少了.我就多分几次发/***************************************************************************** * 程序名:词法分析器 * * 功能:从program.txt读入一段完整c++代码,根据原有的关键字表(keyword)...
西青区19632987981: 用c++语言编写词法分析器希望有详细说明谢谢 - ?
牢径安捷: →字母| 字母| 数字 →数字| 数字 →+ |- |* |; |(|) →=|=|>|=|* →< →= →> →: →/ 该语言的保留字 :begin end if then else for do while and or not 说明: 1 该语言大小写不敏感. 2 字母为a-z A-Z,数字为0-9. 3可以对上述文法进行扩充和改造. 4 '/*……*/'为程序的注释部分. [设计要求] 1、 给出各单词符号的类别编码. 2、 词法分析程序应能发现输入串中的错误. 3、 词法分析作为单独一遍编写,词法分析结果为二元式序列组成的中间文件. 4、设计两个测试用例(尽可能完备),并给出测试结果.
西青区19632987981: C语言程序设计C++编写程序.简易词法分析器2 - ?
牢径安捷: char c; FILE* fp = fopen("xxx.c","r"); while(c = fgetc() != EOF) { if(c>='0'&&c { } }
西青区19632987981: 用C或C++写一个简单的词法分析程序,程序可以满足下列要求: - ?
牢径安捷: 用Java做就简单了,他的string类型有个match方法可以直接匹配正则表达式,你只要把你需要识别的token的正则表达式写出来就ok了.
西青区19632987981: 怎样用C++编写计算器的测试程序 - ?
牢径安捷: 1、使用C/C++程序设计语言和递归下降子程序的方法编写该函数绘图语言的词法分析器.并要求设计一个词法分析器的测试小程序来调用自己编写的词法分析器测试各种不同的输入. 2、词法分析的任务是对输入的字符串形式的源程序按顺序进...
西青区19632987981: 词法分析的词法分析程序 - ?
牢径安捷: 组织输入、扫描、分析、输出; 接收字符串形式的源程序,按照源程序输入的次序依次扫描源程序,在扫描的同时根据语言的词法规则识别出具有独立意义的单词,并产生与源程序等价的属性字(Token)流 . (1) 只要不修改接口,则词法分析器所作的修改不会影响整个编译器,且词法分析器易于维护; (2) 整个编译器结构简捷、清晰; (3) 可以采用有效的方法和工具进行处理.
西青区19632987981: c语言词法分析器 - ?
牢径安捷: 任务1:识别小型语言所有单词的词法分析程序设计 源程序设计语言 G[<程序>] <程序>→<变量说明><BEGIN> <语句表> <END>. <变量说明>→VAR<变量表>:<类型>;|<空> <变量表>→<变量表>,<变量>|<变量> <类型>→INTEGER <语句表>→...
西青区19632987981: 如何用JAVA编写词法分析器程序 - ?
牢径安捷: 我也做过这个作业 package source; import java.util.LinkedList; public class LexicalAnalysis { //私有变量声明 private LinkedList<Word> optr = new LinkedList<Word>(); private String exp; //词法分析 public LinkedList<Word> lexical_analysis(String ...
西青区19632987981: 编译原理实验做一个词法分析程序,是要做什么?求简单易懂的说明!~ - ?
牢径安捷:[答案] 1)定义 所有token或者叫单词的有限自动机. 2)将有限自动机用代码实现. 3)写分析程序,利用你定义的有限自动机来识别所有的“单词”.并将识别出来的单词的相关信息,如名称,位置,类别等记录在相关的数据结构中.
西青区19632987981: 词法分析器是什么 - ?
牢径安捷: 词法分析器又称扫描器.词法分析是指将我们编写的文本代码流解析为一个一个的记号,分析得到的记号以供后续语法分析使用.词法分析器的工作是低级别的分析:将字符或者字符序列转化成记号..在谈论词法分析时,使用术语“词法记号”(简称记号)、“模式”和“词法单元”表示特定的含义. 在分析时,一是把词法分析器当成语法分析的一部分,另一种是把词法分析器当成编译程序的独立部分.在前一种情况下,词法分析器不断地被语法分析器调用,每调用一次词法分析器将从源程序的字符序列拼出一个单词,并将其Token值返回给语法分析器.后一种情况则不同,词法分析器不是被语法分析器不断地调用,而是一次扫描全部单词完成编译器的独立一遍任务.