当前位置:首页 » 编程软件 » 编译原理中词法分析程序

编译原理中词法分析程序

发布时间: 2022-03-14 13:50:33

⑴ 求 编译原理 语法分析程序

可以参考我的空间,我在三年前写过类似代码。
http://hi..com/逄韶华/ihome/myblog

⑵ 编译原理中词法分析和语法分析的任务分别是什么

在编译原理中,语法规则和词法规则不同之处在于:规则主要识别单词,而语法主要识别多个单词组成的句子。
词法分析和词法分析程序:
词法分析阶段是编译过程的第一个阶段。这个阶段的任务是从左到右一个字符一个字符地读入源程序,即对构成源程序的字符流进行扫描然后根据构词规则识别单词(也称单词符号或符号)。词法分析程序实现这个任务。词法分析程序可以使用lex等工具自动生成。
语法分析(Syntax analysis或Parsing)和语法分析程序(Parser)
语法分析是编译过程的一个逻辑阶段。语法分析的任务是在词法分析的基础上将单词序列组合成各类语法短语,如“程序”,“语句”,“表达式”等等.语法分析程序判断源程序在结构上是否正确.源程序的结构由上下文无关文法描述.
语义分析(Syntax analysis)
语义分析是编译过程的一个逻辑阶段. 语义分析的任务是对结构上正确的源程序进行上下文有关性质的审查, 进行类型审查.语义分析将审查类型并报告错误:不能在表达式中使用一个数组变量,赋值语句的右端和左端的类型不匹配.

⑶ 编译原理语法分析器程序

#include #include #include #include #include using namespace std; struct Node1 { char vn; char vt; char s[10]; }MAP[20];//存储分析预测表每个位置对应的终结符,非终结符,产生式 int k; //用R代表E',W代表T',e代表空 char G[10][10]={"...

⑷ 如何通俗易懂地解释编译原理中语法分析的过程

语法分析(Syntax analysis或Parsing)和语法分析程序(Parser)
语法分析是编译过程的一个逻辑阶段。语法分析的任务是在词法分析的基础上将单词序列组合成各类语法短语,如“程序”,“语句”,“表达式”等等.语法分析程序判断源程序在结构上是否正确.源程序的结构由上下文无关文法描述.

⑸ 求C语言编译原理语法分析程序

一继承的词法来自

http://blog.sina.com.cn/s/blog_67c9fc300100srad.html
二语法

用扩充的BNF表示如下:

⑴<程序>::=begin<语句串>end

⑵<语句串>::=<语句>{;<语句>}

⑶<语句>::=<赋值语句>

⑷<赋值语句>::=ID:=<表达式>

⑸<表达式>::=<项>{+<项> | -<项>}

⑹<项>::=<因子>{*<因子> | /<因子>

⑺<因子>::=ID | NUM | (<表达式>)

三要求

输入单词串,以“#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出“error”。

例如:

输入 begin a:=9; x:=2*3; b:=a+x end #

输出 success!

输入 x:=a+b*c end #

输出 error!

⑹ 编译原理语法分析器程序,用C语言或C++

你可以去看看《高级编译器设计与实现(Steven.S.Muchnick).(中文版)》。

⑺ 怎样较容易理解编译原理中词法分析的原理即实现过程,最好配上图文解说

词法分析的本质是让计算机程序理解词法规则。例如,在我们平时用的语言里,“你”是指一个人,当“你们”出现的时候就是一个词是指多个人,这就是一种规则,但是是人能理解的规则,词法分析要用数学的表达方式让计算机理解,计算机的做法是对每个遇到的字先判断是不是“你”,如果不是,那么不符合这条规则;如果是,就要记下现在这个状态---即已经看到一个“你”字,然后判断下一个字是不是“们”,是则这条规则成立,也就是让计算机理解了这一个词,而不是单个的两个字。词法分析不是编译原理才有的,在搜索、数据挖掘等领域都用到。编译原理中的词法分析就是把源程序中的字符按顺序一个一个输入给计算机,计算机对每个字符按照所有规则进行判断,例如输入了一个“a”,要判断它是不是“and“的开头,是不是一个变量名,函数名,还是字符串等等,每个可能性都是一条规则决定的。根据规则的复杂性,可以用多种数学方法描述,比如基本的方法是状态机、正则表达式。

⑻ 编译原理词法分析程序

(一)Block子程序分析

procere enter(k: object1); //填写符号表
begin {enter object into table}
tx := tx + 1; //下标加1,tx的初始值为零,零下标不地址不填写标志符,用于查找失败使用
with table[tx] do //填入内容,保存标志符名和类型
begin name := id; kind := k;
case k of //根据类型判断是否正确
constant: begin if num > amax then //如果是常量,判断是否大于最大值,若是则报30号错
begin error(30); num :=0 end;
val := num //否则保存数值
end;
varible: begin level := lev; adr := dx; dx := dx + 1; //如果是变量,填写变量内部表示,LEVEl是变量的层次,adr为地址
end;
proc: level := lev //如果是过程,保存过程的层次
end
end
end {enter};

//查找符号表的位置
function position(id: alfa): integer;
var i: integer;
begin {find indentifier id in table} //从后向前查找
table[0].name := id; i := tx; //找到保存类型
while table[i].name <> id do i := i-1;
position := i //返回标志符在符号表中的位置
end {position};

procere block(lev,tx: integer; fsys: symset);
var dx: integer; {data allocation index} //数据分配索引
tx0: integer; {initial table index} //初始符号表索引
cx0: integer; {initial code index} //初始代码索引
procere enter(k: object1); //填写符号表,下次分析
begin {enter object into table}
tx := tx + 1;
with table[tx] do
begin name := id; kind := k;
case k of
constant: begin if num > amax then
begin error(30); num :=0 end;
val := num
end;
varible: begin level := lev; adr := dx; dx := dx + 1;
end;
proc: level := lev
end
end
end {enter};

function position(id: alfa): integer; //查找符号表,下次分析
var i: integer;
begin {find indentifier id in table}
table[0].name := id; i := tx;
while table[i].name <> id do i := i-1;
position := i
end {position};

procere constdeclaration; //常量声明
begin if sym = ident then //如果是标志符,读入一个TOKEN
begin getsym;
if sym in [eql, becomes] then //读入的是等号或符值号继续判断
begin if sym = becomes then error(1); //如果是“=”报1号错
getsym; //读入下一个TOKEN
if sym = number then //读入的是数字,填写符号表
begin enter(constant); getsym
end
else error(2) //如果不是数字,报2号错
end else error(3) //不是等号或符值号,报3号错
end else error(4) //如果不是标志符,报4号错
end {constdeclaration};

procere vardeclaration; //变量声明
begin if sym = ident then //读入的是标志符,填写符号表
begin enter(varible); getsym
end else error(4) //不是标志符,报4号错
end {vardeclaration};

procere listcode;
var i: integer;
begin {list code generated for this block}
for i := cx0 to cx-1 do
with code[i] do
writeln(i:5, mnemonic[f]:5, 1:3, a:5)
end {listcode};

procere statement(fsys: symset);
var i, cx1, cx2: integer;
procere expression(fsys: symset); //表达式分析
var addop: symbol;
procere term(fsys: symset); //项分析
var mulop: symbol;
procere factor(fsys: symset); //因子分析
var i: integer;
begin test(facbegsys, fsys, 24); //读入的是“(”,标志符或数字
while sym in facbegsys do
begin
if sym = ident then //是标志符,查表
begin i:= position(id);
if i = 0 then error(11) else //未找到,报11号错
with table[i] do //找到,读入标志符类型
case kind of
constant: gen(lit, 0, val); //写常量命令
varible: gen(lod, lev-level, adr);//写变量命令
proc: error(21) //过程名,报21号错
end;
getsym //读入下一个TOKEN
end else
if sym = number then //读入的是数字
begin if num > amax then //如果数字大于最大数,报30号错误
begin error(30); num := 0
end;
gen(lit, 0, num); getsym //调用数字命令,读入下一个TOKEN
end else
if sym = lparen then //读入的是“(”
begin getsym; expression([rparen]+fsys); //调用表达式分析函数
if sym = rparen then getsym else error(22) //如果“(”后无“)”,报22号错
end;
test(fsys, [lparen], 23)
end
end {factor};//因子分析结束

//项分析
begin {term} factor(fsys+[times, slash]); //调用因子分析程序
while sym in [times, slash] do //取得是乘、除号循环
begin mulop:=sym;getsym;factor(fsys+[times,slash]); //记录符号,调用因子分析
if mulop=times then gen(opr,0,4) else gen(opr,0,5) //写乘除指令
end
end {term};
begin {expression}
if sym in [plus, minus] then //如果是加减号
begin addop := sym; getsym; term(fsys+[plus,minus]); //记录符号,调用项分析程序
if addop = minus then gen(opr, 0,1) //写加减指令
end else term(fsys+[plus, minus]);
while sym in [plus, minus] do //如果是加减号循环
begin addop := sym; getsym; term(fsys+[plus,minus]);
if addop=plus then gen(opr,0,2) else gen(opr,0,3)
end
end {expression};

//条件过程
procere condition(fsys: symset);
var relop: symbol;
begin
if sym = oddsym then //如果是判奇符
begin getsym; expression(fsys); gen(opr, 0, 6) //取下一个TOKEN,调用expression,填指令
end else
begin expression([eql, neq, lss, gtr, leq, geq]+fsys);
if not(sym in [eql, neq, lss, leq, gtr, geq]) then //如果不是取到逻辑判断符号,出错.20
error(20) else
begin relop := sym; getsym; expression(fsys);
case relop of
eql: gen(opr, 0, 8); // =,相等
neq: gen(opr, 0, 9); // #,不相等
lss: gen(opr, 0, 10); // <,小于
geq: gen(opr, 0, 11); // ],大于等于
gtr: gen(opr, 0, 12); // >,大于
leq: gen(opr, 0, 13); // [,小于等于
end
end
end
end {condition};

begin {statement}
if sym = ident then //如果是标识符
begin i := position(id); //查找符号表
if i = 0 then error(11) else //未找到,标识符未定义,报11号错
if table[i].kind <> varible then //如果标识符不是变量,报12号错
begin {assignment to non-varible} error(12); i := 0
end;
getsym; if sym = becomes then getsym else error(13); //如果是变量读入下一个TOKEN,不是赋值号,报13好错;是则读入一个TOKEN
expression(fsys); //调用表达是过程
if i <> 0 then //写指令
with table[i] do gen(sto, lev-level, adr)
end else
if sym = callsym then //如果是过程调用保留字,读入下一个TOKEN
begin getsym;
if sym <> ident then error(14) else //不是标识符报14号错
begin i := position(id);
if i = 0 then error(11) else //是标识符,未定义,报13号错
with table[i] do // 已定义的标识符读入类型
if kind=proc then gen(cal, lev-level, adr) //是过程名写指令
else error(15); //不是过程名,报15号错
getsym
end
end else
if sym = ifsym then //如果是IF
begin getsym; condition([thensym, dosym]+fsys); //读入一个TOKEN,调用条件判断过程
if sym = thensym then getsym else error(16); //如果是THEN,读入一个TOKEN,不是,报16号错
cx1 := cx; gen(jpc, 0, 0); //写指令
statement(fsys); code[cx1].a := cx
end else
if sym = beginsym then //如果是BEGIN
begin getsym; statement([semicolon, endsym]+fsys); //读入一个TOKEN
while sym in [semicolon]+statbegsys do
begin
if sym = semicolon then getsym else error(10); //如果读入的是分号
statement([semicolon, endsym]+fsys)
end;
if sym = endsym then getsym else error(17) //如果是END 读入一个TOKEN,不是,报17号错
end else
if sym = whilesym then //如果是WHILE
begin cx1 := cx; getsym; condition([dosym]+fsys); //调用条件过程
cx2 := cx; gen(jpc, 0, 0); //写指令
if sym = dosym then getsym else error(18); //如果是DO读入下一个TOKEN,不是报18号错
statement(fsys); gen(jmp, 0, cx1); code[cx2].a := cx
end;
test(fsys, [], 19)
end {statement};

begin {block}
dx:=3;
tx0:=tx;
table[tx].adr:=cx;
gen(jmp,0,0);
if lev > levmax then error(32);
repeat
if sym = constsym then //如果是CONST
begin getsym; //读入TOKEN
repeat constdeclaration; //常量声明
while sym = comma do
begin getsym; constdeclaration
end;
if sym = semicolon then getsym else error(5) //如果是分号读入下一个TOKEN,不是报5号错
until sym <> ident //不是标志符常量声明结束
end;
if sym = varsym then 如果是VAR
begin getsym; 读入下一个TOKEN
repeat vardeclaration; //变量声明
while sym = comma do
begin getsym; vardeclaration
end;
if sym = semicolon then getsym else error(5) //如果是分号读入下一个TOKEN,不是报5号错
until sym <> ident; //不是标志符常量声明结束
end;
while sym = procsym do //过程声明
begin getsym;
if sym = ident then
begin enter(proc); getsym
end
else error(4); //不是标志符报4号错
if sym = semicolon then getsym else error(5); //如果是分号读入下一个TOKEN,不是报5号错
block(lev+1, tx, [semicolon]+fsys);
if sym = semicolon then //如果是分号,取下一个TOKEN,不是报5号错
begin getsym;test(statbegsys+[ident,procsym],fsys,6)
end
else error(5)
end;
test(statbegsys+[ident], declbegsys, 7)
until not(sym in declbegsys); //取到的不是const var proc结束
code[table[tx0].adr].a := cx;
with table[tx0] do
begin adr := cx; {start adr of code}
end;
cx0 := 0{cx}; gen(int, 0, dx);
statement([semicolon, endsym]+fsys);
gen(opr, 0, 0); {return}
test(fsys, [], 8);
listcode;
end {block};

⑼ 急求!!!编译原理词法分析器代码

#include <stdio.h>
#include <string.h>
#include <conio.h>
#define norw 13 /* 关键字个数 */
#define nmax 14 /* number的最大位数 */
#define al 10 /* 符号的最大长度 */
#define cn 11
#define IDENT "ident"
#define NUM "number"
#define SYM "sym"
#define ISLETTER(c) ((c)>='A'&&(c)<='Z'||(c)>='a'&&(c)<='z')
#define ISNUMBER(c) ((c)>='0'&&(c)<='9')
void letter();void number();
char ch; /* 获取字符的缓冲区,getch使用 */
char a[al+1]; /* 临时符号,多出的一个字节用于存放0 */
FILE *fin;
char fname[al];
char *word[] = {
"begin", "call" , "const" , "do" , "end" ,
"if" , "odd" , "procere" , "read" , "then" ,
"var" , "while" , "write"
};
int k=0,i=0;
char ssym[][10]={"plus","minus","times","slash","lparen", "rparen","eql","comma","neq","semicolon"};
char csym[]={'+','-','*','/','(',')','=',',','#',';'};

void main() {
do{
printf("Input pl/0 filename:");
gets(fname);
fin=fopen(fname,"r");
}while(!fin);
ch=fgetc(fin);
while(ch!='.'){
for(;' '==ch;ch=fgetc(fin));
if(ISLETTER(ch)){
k=0;
letter();
}else if(ISNUMBER(ch)){
k=0;
number();
}else{
switch(ch){
case ':':
if('='==(ch=fgetc(fin))){
printf("(\":=\",eql)\n");
ch=fgetc(fin);
}break;
case '>':
if('='==(ch=fgetc(fin))){
printf("(\">=\",gtr)\n");
ch=fgetc(fin);
break;
}else
printf("(\">\",geq)\n");break;
case '<':
if('='==(ch=fgetc(fin))){
printf("(\"<=\",leq)\n");
ch=fgetc(fin);break;
}
else
printf("(\"<\",lss)\n");break;
default:
for(i=0;i<norw && ch!=csym[i];i++);
if(i<norw)
printf("(\"%c\",%s)\n",ch,ssym[i]);
ch=fgetc(fin);
}
}
}printf("(\"%c\",period)\n",ch);
}

void letter(){
do{
if(al>k) {
a[k]=ch;
k+=1;
}
ch=fgetc(fin);
}while(ISLETTER(ch));
a[k]='\0';
for(i=0;i<norw && strcmp(a,word[i]);i++);
if(i<norw)
printf("(\"%s\",%s%s)\n",a,a,SYM);
else
printf("(\"%s\",%s)\n",a,IDENT);
}

void number(){
do{
if(nmax>k) {
a[k]=ch;
k+=1;
}
ch=fgetc(fin);
}while(ISNUMBER(ch));
a[k]='\0';
printf("(\"%s\",%s)\n",a,NUM);
}

⑽ 求C写的编译原理词法分析程序

#include <iostream>
#include <vector>
#include <utility>
#include <string>
#include <fstream>
#include <algorithm>
#include <cstdlib>
using namespace std;

//用来存储目标文件名
string file_name;

//提取文本文件中的信息。
string GetText();

//获得一个单词符号,从位置i开始查找。
//并且有一个引用参数j,用来返回这个单词最后一个字符在str的位置。
string GetWord(string str,int i,int& j);

//这个函数用来除去字符串中连续的空格和换行
//第一个参数为目标字符串,第二个参数为开始位置
//返回值为连续的空格和换行后的第一个有效字符在字符串的位置
int DeleteNull(string str,int i);

//判断i当前所指的字符是否为一个分界符,是的话返回真,反之假
bool IsBoundary(string str,int i);

//判断i当前所指的字符是否为一个运算符,是的话返回真,反之假
bool IsOperation(string str,int i);

//此函数将一个pair数组输出到一个文件中
void OutFile(vector <pair <int,string> > v);

//此函数接受一个字符串数组,对它进行词法分析,返回一个pair型数组
vector <pair <int,string> > analyst(vector <string> vec);

//此函数判断传递的参数是否为关键字,是的话,返回真,反之返回假
bool IsKey(string str);

int main()
{
cout < < "###########################\n ";
cout < < "###right: Giftedbird###\n ";
cout < < "###########################\n ";
string com1= " ";
string com2= "\n ";
string fileline=GetText();
int begin=0,end=0;
vector <string> array;
do
{
begin=DeleteNull(fileline,begin);
string nowString;
nowString=GetWord(fileline,begin,end);
if(end==-1)
break;
if(nowString.compare(com1)&&nowString.compare(com2))
array.push_back(nowString);
begin=end+1;
}while(true);
vector <pair <int,string> > mid_result;
mid_result=analyst(array);
OutFile(mid_result);
cout < < "**********************************************************************\n ";
cout < < "***程序已完成词法分析,分析结果已经存储在文件 " < <file_name < < "中!!!***\n ";
cout < < "**********************************************************************\n ";
system( "pause ");
return 0;
}

//提取文本文件中的信息
string GetText()
{
string file_name1;
cout < < "请输入源文件名(包括路径和后缀名): ";
cin> > file_name1;
ifstream infile(file_name1.c_str(),ios::in);
if (!infile)
{
cerr < < "哦!无法打开文件 " < <file_name1.c_str() < < " !!! " < <endl;
exit(-1);
}
cout < <endl;
char f[1000];
infile.getline(f,1000,EOF);
infile.close();
return f;
}

//获得一个单词符号,从位置i开始查找。
//并且有一个引用参数j,用来返回这个单词最后一个字符在原字符串的位置。
string GetWord(string str,int i,int& j)
{
string no_use( "(){} , ; \n+=*/- <> \ " ");
j=str.find_first_of(no_use,i);
if(j==-1)
return " ";
if(i!=j)
j--;
return str.substr(i,j-i+1);
}

//这个函数用来除去字符串中连续的空格和换行
//第一个参数为目标字符串,第二个参数为开始位置
//返回值为连续的空格和换行后的第一个有效字符在字符串的位置
int DeleteNull(string str,int i)
{
for(;;i++)
if(str[i]!= ' '&&str[i]!= '\n ')
return i;
}

//判断i当前所指的字符是否为一个分界符,是的话返回真,反之假
bool IsBoundary(string str,int i)
{
int t;
char arr[7]={ ', ', '; ', '{ ', '} ', '( ', ') ', '\ " '};
for (t=0;t <7;t++)
if(str[i]==arr[t])
return true;
return false;
}

//判断i当前所指的字符是否为一个运算符,是的话返回真,反之假
bool IsOperation(string str,int i)
{
int t;
char arr[7]={ '+ ', '- ', '* ', '/ ', '= ', ' < ', '> '};
for (t=0;t <7;t++)
if(str[i]==arr[t])
return true;
return false;
}

//此函数将一个个字符串数组输出到一个文件中
void OutFile(vector <pair <int,string> > v)
{
cout < < "请输入目标文件名(包括路径和后缀名): ";
cin> > file_name;
ofstream outfile(file_name.c_str(),ios::out);
if (!outfile)
{
cerr < < "哦!无法打开文件 " < <file_name.c_str() < < " !!! " < <endl;
exit(-1);
}
cout < <endl;
int i;
outfile < < "###########################\n ";
outfile < < "###right: Giftedbird###\n ";
outfile < < "###########################\n\n ";
for(i=0;i <v.size();i++)
outfile < < " < " < <v[i].first < < " , \ " " < <v[i].second < < "\ "> " < <endl;
outfile < < "\n\n*********************************\n ";
outfile.close();
return;
}

//此函数接受一个字符串数组,对它进行词法分析,返回一个pair型数组
vector <pair <int,string> > analyst(vector <string> vec)
{
vector <pair <int,string> > temp;
int i;
for(i=0;i <vec.size();i++)
{
if(vec[i].size()==1)
{
if((vec[i]== "> "||vec[i]== " < "||vec[i]== "! ")&&vec[i+1]== "= ")
{
string jk=vec[i];
jk.append(vec[++i],0,1);
pair <int,string> pp(4,jk);
temp.push_back(pp);
continue;
}
if((vec[i]== "+ "&&vec[i+1]== "+ ")||(vec[i]== "- "&&vec[i+1]== "- "))
{
string jk=vec[i];
jk.append(vec[++i],0,1);
pair <int,string> pp(4,jk);
temp.push_back(pp);
continue;
}
if(IsBoundary(vec[i],0))
{
pair <int,string> pp(5,vec[i]);
temp.push_back(pp);
}
else if(IsOperation(vec[i],0))
{
pair <int,string> pp(4,vec[i]);
temp.push_back(pp);
}
else if(vec[i][0] <= '9 '&&vec[i][0]> = '0 ')
{
pair <int,string> pp(3,vec[i]);
temp.push_back(pp);
}
else
{
pair <int,string> pp(2,vec[i]);
temp.push_back(pp);
}
}
else if(vec[i][0] <= '9 '&&vec[i][0]> = '0 ')
{
pair <int,string> pp(3,vec[i]);
temp.push_back(pp);
}
else if(IsKey(vec[i]))
{
pair <int,string> pp(1,vec[i]);
temp.push_back(pp);
}
else
{
pair <int,string> pp(2,vec[i]);
temp.push_back(pp);
}
}
return temp;
}

//此函数判断传递的参数是否为关键字,是的话,返回真,反之返回假
bool IsKey(string str)
{
string p[16]={ "char ", "double ", "int ", "long ", "double ", "float ", "for ", "while ", "do ", "break ", "continue ", "switch ", "short ", "case ", "return ", "if "};
vector <string> ppp(p,p+16);
int u;
for(u=0;u <ppp.size();u++)
if(!str.compare(ppp[u]))
return true;
return false;
}
//finished

热点内容
腾讯云cos云服务器 发布:2025-01-23 00:46:47 浏览:63
如何给安卓平板刷上MIUI系统 发布:2025-01-23 00:45:51 浏览:73
2开方算法 发布:2025-01-23 00:27:21 浏览:16
如何看自己steam服务器 发布:2025-01-23 00:07:21 浏览:710
armlinux命令 发布:2025-01-23 00:01:08 浏览:137
战地4亚洲服务器为什么被攻击 发布:2025-01-22 23:45:42 浏览:671
javascript反编译 发布:2025-01-22 23:37:57 浏览:432
夏天来了你的巴氏奶存储对吗 发布:2025-01-22 23:37:56 浏览:206
求最大值c语言 发布:2025-01-22 23:22:35 浏览:250
一键清理系统脚本 发布:2025-01-22 23:21:10 浏览:62