西安邮电大学编译原理语法分析器的制作

合集下载

编译原理中的词法分析器设计

编译原理中的词法分析器设计

编译原理中的词法分析器设计编译原理是计算机科学中的一门重要学科,其研究的主要方向是将高级语言转化为计算机能够执行的指令。

编译器是实现这种转化的程序,其中的词法分析器是编译器的核心组成部分之一。

本文将讨论词法分析器的设计。

概述词法分析器是编译器中的第一个阶段,它的主要任务是将输入的字符序列转化为有意义的单词序列(记号)。

单词序列是语法分析器后继处理的输入,因此词法分析器的正确性对于编译器的正确性至关重要。

词法分析器一般采用有限状态自动机(Finite State Automaton,FSA)作为基本的表示和实现模型。

有限状态自动机是一种对于有限的输入序列作出有限反应的计算模型,其在自然语言处理、文本解析、数据库搜索等领域都有广泛应用。

设计过程书写正规表达式词法分析器设计过程的第一步是书写正规表达式。

正规表达式是一种描述字符串模式的方式,它由字母表中的字符和元字符(用于表示特定语义)组成。

例如,用于匹配任意非负整数的正规表达式为``\d+'',其中``\d''表示数字字符,``+''表示前面字符的1次或多次重复。

正规表达式描述的语言可以通过正则语言的原理实现成有限状态自动机。

有限状态自动机可以由确定性有限状态自动机(Deterministic Finite Automaton,DFA)和非确定性有限状态自动机(Nondeterministic Finite Automaton,NFA)来实现。

DFA是状态转移函数为完全定义的FSA,也就是说,对于任何状态和输入字符,DFA都能确定一个下一状态;NFA是状态转移函数可能不完全定义的FSA。

从正规表达式到FSA将正规表达式转化为FSA是词法分析器设计中的一项重要工作。

具体实现中,可以采用Thompson构造算法或者子集构造算法。

Thompson构造算法是一种将正规表达式直接转化为等价NFA的算法,其基本思想是对正规表达式进行递归分解。

编译原理实验报告词法分析器语法分析器

编译原理实验报告词法分析器语法分析器

编译原理实验报告词法分析器语法分析器集团档案编码:[YTTR-YTPT28-YTNTL98-UYTYNN08]编译原理实验报告实验一一、实验名称:词法分析器的设计二、实验目的:1,词法分析器能够识别简单语言的单词符号2,识别出并输出简单语言的基本字.标示符.无符号整数.运算符.和界符。

三、实验要求:给出一个简单语言单词符号的种别编码词法分析器四、实验原理:1、词法分析程序的算法思想算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。

2、程序流程图(1)主程序(2)扫描子程序3五、实验内容:1、实验分析编写程序时,先定义几个全局变量a[]、token[](均为字符串数组),c,s( char型),i,j,k(int型),a[]用来存放输入的字符串,token[]另一个则用来帮助识别单词符号,s用来表示正在分析的字符。

字符串输入之后,逐个分析输入字符,判断其是否‘#’,若是表示字符串输入分析完毕,结束分析程序,若否则通过int digit(char c)、int letter(char c)判断其是数字,字符还是算术符,分别为用以判断数字或字符的情况,算术符的判断可以在switch语句中进行,还要通过函数int lookup(char token[])来判断标识符和保留字。

2 实验词法分析器源程序:#include <>#include <>#include <>int i,j,k;char c,s,a[20],token[20]={'0'};int letter(char s){if((s>=97)&&(s<=122)) return(1);else return(0);}int digit(char s){if((s>=48)&&(s<=57)) return(1);else return(0);}void get(){s=a[i];i=i+1;}void retract(){i=i-1;}int lookup(char token[20]){if(strcmp(token,"while")==0) return(1);else if(strcmp(token,"if")==0) return(2);else if(strcmp(token,"else")==0) return(3);else if(strcmp(token,"switch")==0) return(4);else if(strcmp(token,"case")==0) return(5);else return(0);}void main(){printf("please input string :\n");i=0;do{i=i+1;scanf("%c",&a[i]);}while(a[i]!='#');i=1;j=0;get();while(s!='#'){ memset(token,0,20);switch(s){case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':case 'g':case 'h':case 'i':case 'j':case 'k':case 'l':case 'm':case 'n':case 'o':case 'p':case 'q':case 'r':case 's':case 't':case 'u':case 'v':case 'w':case 'x':case 'y':case 'z':while(letter(s)||digit(s)){token[j]=s;j=j+1;get();}retract();k=lookup(token);if(k==0)printf("(%d,%s)",6,token);else printf("(%d,-)",k);break;case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':while(digit(s)){token[j]=s;j=j+1;get();}retract();printf("%d,%s",7,token);break;case '+':printf("('+',NULL)");break;case '-':printf("('-',null)");break; case '*':printf("('*',null)");break;case '<':get();if(s=='=') printf("(relop,LE)");else{retract();printf("(relop,LT)");}break;case '=':get();if(s=='=')printf("(relop,EQ)");else{retract();printf("('=',null)");}break;case ';':printf("(;,null)");break;case ' ':break;default:printf("!\n");}j=0;get();} }六:实验结果:实验二一、实验名称:语法分析器的设计二、实验目的:用C语言编写对一个算术表达式实现语法分析的语法分析程序,并以四元式的形式输出,以加深对语法语义分析原理的理解,掌握语法分析程序的实现方法和技术。

编译原理 词法分析器

编译原理 词法分析器

一、实验目的和要求:设计并实现一个PL/0语言(或其它语言,如C语言)的词法分析程序,加深对词法分析原理的理解。

二、实验原理:词法分析是从左向右扫描每行源程序的符号,拼成单词,换成统一的机内表示形式——TOKEN字,送给语法分析程序。

TOKEN字是一个二元式:(单词种别码,自身值)。

PL/0语言单词的种别码参见教材(或自行设定),单词自身值按如下规则给出:1 标识符的自身值是它在符号表的入口地址。

2常数的自身值是常数本身(或它的二进制数值)。

3关键字和界限符的自身值为本身。

三、实验步骤与要求1、设计的词法分析器符合软件工程的要求。

2、编制程序,此程序应具有如下功能:1)输入:字符串(待进行词法分析的源程序),输出:由(种别码,自身值)所组成的二元组序列。

2)功能:a.滤空格b.识别保留字c.识别标识符d.拼数e.拼复合单词: 例如:>=、 <=、 :=3)检查如下错误:a.程序语言的字符集以外的非法字符b.单词拼错,如9A88,而对于将begin拼写成begon的错误,只须把begon当成标识符即可3、请指导教师检查程序和运行结果,评定成绩。

4、撰写并上交实验报告。

四、试验设计和算法分析:实验原理:程序流程:置初值→调用扫描子程序→输出串结束→输出单词二元组→是→否→结束词法分析主程序示意图待分析的简单语言的词法(1) 关键字:begin if then while do end所有关键字都是小写。

(2)运算符和界符::= + - * / < > <= <> >= ; ( ) #(3):其他单词是标识符(ID)和整型常数(NUM),通过以下正规式定义:ID=letter(letter | digit)*NUM=digit digit*(4)空格由空白、制表符和换行符组成。

空格一般用来分隔ID、NUM、运算符、界符和关键字,词法分析阶段通常被忽略。

、设计的词法分析器符合软件工程的要求。

编译原理词法分析器语法分析课程设计范本

编译原理词法分析器语法分析课程设计范本

《编译原理词法分析器语法分析课程设计-《编译原理》课程设计院系信息科学与技术学院专业软件工程年级级学号 2723姓名林苾湲西南交通大学信息科学与技术学院12月目录课程设计1 词法分析器 (2)设计题目 (2)设计内容 (2)设计目的 (2)设计环境 (2)需求分析 (2)概要设计 (2)详细设计 (4)编程调试 (5)测试 (11)结束语 (13)课程设计2 赋值语句的解释程序设计 (14)设计题目 (14)设计内容 (14)设计目的 (14)设计环境 (14)需求分析 (15)概要设计 (16)详细设计 (16)编程调试 (24)测试 (24)结束语 (25)课程设计一词法分析器设计一、设计题目手工设计c语言的词法分析器(能够是c语言的子集)。

二、设计内容处理c语言源程序,过滤掉无用符号,判断源程序中单词的合法性,并分解出正确的单词,以二元组形式存放在文件中。

三、设计目的了解高级语言单词的分类,了解状态图以及如何表示并识别单词规则,掌握状态图到识别程序的编程。

四、设计环境该课程设计包括的硬件和软件条件如下:.硬件(1)Intel Core Duo CPU P8700(2)内存4G.软件(1)Window 7 32位操作系统(2)Microsoft Visual Studio c#开发平台.编程语言C#语言五、需求分析.源程序的预处理:源程序中,存在许多编辑用的符号,她们对程序逻辑功能无任何影响。

例如:回车,换行,多余空白符,注释行等。

在词法分析之前,首先要先剔除掉这些符号,使得词法分析更为简单。

.单词符号的识别并判断单词的合法性:将每个单词符号进行不同类别的划分。

单词符号能够划分成5中。

(1)标识符:用户自己定义的名字,常量名,变量名和过程名。

(2)常数:各种类型的常数。

(3) 保留字(关键字):如if、else、while、int、float 等。

(4) 运算符:如+、-、*、<、>、=等。

西安邮电大学编译原理词法分析

西安邮电大学编译原理词法分析
46
void
KEYWORD
6
catch
KEYWORD
47
volatile
KEYWORD
7
char
KEYWORD
48
while
KEYWORD
8
class
KEYWORD
49
+
OPERATOR
9
const
KEYWORD
50
++
OPERATOR
10
continue
KEYWORD
51
-
OPERATOR
11
default
WordType [id=0, entity=, type=5, content=Test]
WordType [id=77, entity={, type=4, content={]
WordType [id=0, entity=, type=5, content=private]
WordType [id=37, entity=static, type=1, content=static]
}
}
KeyWordTable.java
package .zc.ca.db;
import java.util.HashMap;
import java.util.Map;
import .zc.ca.model.WordType;
public class KeyWordTable {
public static Map<String,WordType> db= new HashMap<String,WordType>();
35
strictfp

编译原理实验二-语法分析器的设计

编译原理实验二-语法分析器的设计

班级:学号: 实验集美大学计算机工程学院实验报告课程名称:编译原理指导教师:实验项目编号:实验二实验项目名称:语法分析器的设计 一、 实验目的通过完成预测分析法的语法分析程序,了解预测分析法和递归子程序法的区 别和联系。

使了解语法分析的功能,掌握语法分析程序设计的原理和构造方法, 训练掌握开发应用程序的基本方法。

二、 实验容♦根据某一文法编制调试LL ( 1 )分析程序,以便对任意输入的符号串 进行分析。

♦构造预测分析表,并利用分析表和一个栈来实现对上述程序设计语言的分 析程序。

♦分析法的功能是利用LL (1)控制程序根据显示栈栈顶容、向前看符号以 及LL (1)分析表,对输入符号串自上而下的分析过程。

三、 实验要求1、 编程时注意编程风格:空行的使用、注释的使用、缩进的使用等。

2、 如果遇到错误的表达式,应输出错误提示信息。

四、 实验设计方案1、设计思想(1)、LL (1)文法的定义LL(1)分析法属于确定的自顶向下分析方法。

LL(1)的含义是:第一个L 表明 自顶向下分析是从左向右扫描输入串,第2个L 表明分析过程中将使用最左推导, 1表明只需向右看一个符号便可决定如何推导,即选择哪个产生式(规则)进行推 导。

LL(1)文法的判别需要依次计算FIRST 集、FOLLOW 集和SELLECT 集,然后判 断是否为LL(1)文法,最后再进行句子分析。

需要预测分析器对所给句型进行识别。

即在LL(1)分析法中,每当在符号栈 的栈顶出现非终极符时,要预测用哪个产生式的右部去替换该非终极符;当出现 终结符时,判断其与剩余输入串的第一个字符是否匹配,如果匹配,则继续分析, 否则报错。

LL(1)分析方法要求文法满足如下条件:对于任一非终极符A 的两个 不同产生式都要满足下面条件:SELECT(A->a) ASELECT(A->p)=0(2)、预测分析表构造LL(1)分析表的作用是对当前非终极符和输入符号确定应该选择用哪个产生式进行推导。

语法分析程序的设计与实现

语法分析程序的设计与实现

1 从语言定义中整理出语法规则
//程序体由begin和end界定 • <program>→$begin <statements> $end //每条语句以分号(;)结束 • <statements> →<stmt> $semicolon <statements>|ε • <stmt> →<declare_smt> | <assign_smt>|<read_smt> | <write_smt> | ε
}
问题:左递归 回溯 解决:对语法规则加以限制 自上而下的语法要求:LL(1)文法
自上而下语法分析器的实现
micro语言定义
整理 (手动)
语法规则
改造(手动或程序实现)
LL(1)文法
2 将语法规则改造为LL(1)文法
LL(1)文法的条件
1)文法不含左递归
2)对于文法中每个非终结符A的各产生式的候选首符集不 相交。即若A 1 | 2 |…| n 则 FIRST(i) FIRST(j) = (i j ) 3)对文法中每一个终结符A,若它存在某个候选首符集包 含,则FIRST(A) FLLOW(A)=
错误处理机制(ch4.6)
• 目的
遇到错误时,使语法分析程序可以继续下去。
• 思想
栈顶为非终结符:跳过输入符号至同步符号/… 栈顶为终结符号:弹出该终结符 / 跳过输入串/…
• 同步符号
FOLLOW集 …
自上而下语法分析器的实现
整理 (手动)
文档存储
micro语言定义
语法规则
源程序
输入字符 单词序列
LL(1)文法——消除左递归

编译原理实验报告(语法分析器)

编译原理实验报告(语法分析器)

.编译原理实验专业:13级网络工程语法分析器1一、实现方法描述所给文法为G【E】;E->TE’E’->+TE’|空T->FT’T’->*FT’|空F->i|(E)递归子程序法:首先计算出五个非终结符的first集合follow集,然后根据五个产生式定义了五个函数。

定义字符数组vocabulary来存储输入的句子,字符指针ch指向vocabulary。

从非终结符E函数出发,如果首字符属于E的first集,则依次进入T函数和E’函数,开始递归调用。

在每个函数中,都要判断指针所指字符是否属于该非终结符的first集,属于则根据产生式进入下一个函数进行调用,若first集中有空字符,还要判断是否属于该非终结符的follow集。

以分号作为结束符。

二、实现代码头文件shiyan3.h#include<iostream>#include<cstdio>#include<string>using namespace std;#define num 100char vocabulary[num];char *ch;void judge_E();void judge_EE();void judge_T();void judge_TT();void judge_F();源文件#include"shiyan3.h"void judge_E(){if(*ch==';'){cout<<"该句子符合此文法!"<<endl;int a=0;cout<<"按1结束程序"<<endl;cin>>a;if(a==1)exit(0);}elseif(*ch=='('||*ch=='i'){judge_T();judge_EE();}else{cout<<"该句子不匹配此文法!"<<endl;int a=0;cout<<"按1结束程序"<<endl;cin>>a;if(a==1)exit(0);}}void judge_EE(){if(*ch==';'){cout<<"该句子符合此文法!"<<endl;int a=0;cout<<"按1结束程序"<<endl;cin>>a;if(a==1)exit(0);}if(*ch=='+'){ch++;judge_T();judge_EE();}elseif(*ch=='#'||*ch==')')return;else{cout<<"该句子不匹配此文法!"<<endl;int a=0;cout<<"按1结束程序"<<endl;cin>>a;if(a==1)exit(0);}}void judge_T(){if(*ch==';'){cout<<"该句子符合此文法!"<<endl;int a=0;cout<<"按1结束程序"<<endl;cin>>a;if(a==1)exit(0);}if(*ch=='('||*ch=='i'){judge_F();judge_TT();}else{cout<<"该句子不匹配此文法!"<<endl;int a=0;cout<<"按1结束程序"<<endl;cin>>a;if(a==1)exit(0);}}void judge_TT(){if(*ch==';'){cout<<"该句子符合此文法!"<<endl;int a=0;cout<<"按1结束程序"<<endl;cin>>a;if(a==1)exit(0);}if(*ch=='*'){ch++;judge_F();judge_TT();}elseif(*ch==')'||*ch=='+'||*ch=='#')return;else{cout<<"该句子不匹配此文法!"<<endl;int a=0;cout<<"按1结束程序"<<endl;cin>>a;if(a==1)exit(0);}}void judge_F(){if(*ch==';'){cout<<"该句子符合此文法!"<<endl;int a=0;cout<<"按1结束程序"<<endl;cin>>a;if(a==1)exit(0);}if(*ch=='('){ch++;judge_E();if(*ch==')'){ch++;}else{cout<<"该句子不匹配此文法!"<<endl;int a=0;cout<<"按1结束程序"<<endl;cin>>a;if(a==1)exit(0);}}elseif(*ch=='i'){ch++;//cout<<*ch;}else{cout<<"该句子不匹配此文法!"<<endl;int a=0;cout<<"按1结束程序"<<endl;cin>>a;if(a==1)exit(0);}}void main(){//char *ch;cout<<"**********************欢迎使用语法分析器************************"<<endl;cout<<"请输入一个句子:"<<endl;cin.getline(vocabulary,15);ch=vocabulary;judge_E();cout<<endl;cout<<"************************结束使用,再见!**************************"<<endl;}三、运行结果四、心得体会此次实验使用的是递归子程序法,用这个方法最大的问题就是函数里的递归调用,一不小心就把人绕糊涂了。

编译原理词法分析器语法分析课程设计

编译原理词法分析器语法分析课程设计

《编译原理》课程设计院系信息科学与技术学院专业软件工程年级 2011级学号 20112723姓名林苾湲西南交通大学信息科学与技术学院2013年 12月目录课程设计1 词法分析器 (2)1.1 设计题目 (2)1.2 设计内容 (2)1.3 设计目的 (2)1.4 设计环境 (2)1.5 需求分析 (2)1.6 概要设计 (2)1.7 详细设计 (4)1.8 编程调试 (5)1.9 测试 (11)1.10 结束语 (13)课程设计2 赋值语句的解释程序设计 (14)2.1 设计题目 (14)2.2 设计内容 (14)2.3 设计目的 (14)2.4 设计环境 (14)2.5 需求分析 (15)2.6 概要设计 (16)2.7 详细设计 (16)2.8 编程调试 (24)2.9 测试 (24)2.10 结束语 (25)课程设计一词法分析器设计一、设计题目手工设计c语言的词法分析器(可以是c语言的子集)。

二、设计内容处理c语言源程序,过滤掉无用符号,判断源程序中单词的合法性,并分解出正确的单词,以二元组形式存放在文件中。

三、设计目的了解高级语言单词的分类,了解状态图以及如何表示并识别单词规则,掌握状态图到识别程序的编程。

四、设计环境该课程设计包括的硬件和软件条件如下:4.1.硬件(1)Intel Core Duo CPU P8700(2)内存4G4.2.软件(1)Window 7 32位操作系统(2)Microsoft Visual Studio c#开发平台4.3.编程语言C#语言五、需求分析5.1.源程序的预处理:源程序中,存在许多编辑用的符号,他们对程序逻辑功能无任何影响。

例如:回车,换行,多余空白符,注释行等。

在词法分析之前,首先要先剔除掉这些符号,使得词法分析更为简单。

5.2.单词符号的识别并判断单词的合法性:将每个单词符号进行不同类别的划分。

单词符号可以划分成5中。

(1)标识符:用户自己定义的名字,常量名,变量名和过程名。

编译原理语法分析器实验报告

编译原理语法分析器实验报告

编译原理语法分析器实验报告西安邮电大学编译原理实验报告学院名称:计算机学院****:***实验名称:语法分析器的设计与实现班级:计科1405班学号:04141152时间:2017年5月12日把SELECT (i)存放到temp中结果返回1;1.构建好的预测分析表2.语法分析流程图一.实验结果正确运行结果:错误运行结果:二.设计技巧和心得体会这次实验编写了一个语法分析方法的程序,但是在LL(1)分析器的编写中我只达到了最低要求,就是自己手动输入的select集,first集,follow集然后通过程序将预测分析表构造出来,然后自己编写总控程序根据分析表进行分析。

通过本次试验,我能够设计一个简单的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。

还能选择最有代表性的语法分析方法,如LL(1) 语法分析程序、算符优先分析程序和LR分析分析程序。

三.源代码package com.LL1;import java.util.ArrayDeque;import java.util.Deque;/*** LL1文法分析器,已经构建好预测分析表,采用Deque实现* Created by HongWeiPC on 2017/5/12.*/public class LL1_Deque {//预测分析表private String[][] analysisTable = new String[][]{{"TE'", "", "", "TE'", "", ""},{"", "+TE'", "", "", "ε", "ε"},{"FT'", "", "", "FT'", "", ""},{"", "ε", "*FT'", "", "ε", "ε"},{"i", "", "", "(E)", "", ""}};//终结符private String[] VT = new String[]{"i", "+", "*", "(", ")", "#"};//非终结符private String[] VN = new String[]{"E", "E'", "T", "T'", "F"};//输入串strTokenprivate StringBuilder strToken = new StringBuilder("i*i+i");//分析栈stackprivate Deque<String> stack = new ArrayDeque<>();//shuru1保存从输入串中读取的一个输入符号,当前符号private String shuru1 = null;//X中保存stack栈顶符号private String X = null;//flag标志预测分析是否成功private boolean flag = true;//记录输入串中当前字符的位置private int cur = 0;//记录步数private int count = 0;public static void main(String[] args) {LL1_Deque ll1 = new LL1_Deque();ll1.init();ll1.totalControlProgram();ll1.printf();}//初始化private void init() {strToken.append("#");stack.push("#");System.out.printf("%-8s %-18s %-17s %s\n", "步骤", "符号栈", "输入串", "所用产生式");stack.push("E");curCharacter();System.out.printf("%-10d %-20s %-20s\n", count, stack.toString(), strToken.substring(cur, strToken.length()));}//读取当前栈顶符号private void stackPeek() {X = stack.peekFirst();}//返回输入串中当前位置的字母private String curCharacter() {shuru1 = String.valueOf(strToken.charAt(cur));return shuru1;}//判断X是否是终结符private boolean XisVT() {for (int i = 0; i < (VT.length - 1); i++) {if (VT[i].equals(X)) {return true;}}return false;}//查找X在非终结符中分析表中的横坐标private String VNTI() {int Ni = 0, Tj = 0;for (int i = 0; i < VN.length; i++) {if (VN[i].equals(X)) {Ni = i;}}for (int j = 0; j < VT.length; j++) {if (VT[j].equals(shuru1)) {Tj = j;}}return analysisTable[Ni][Tj];}//判断M[A,a]={X->X1X2...Xk}//把X1X2...Xk推进栈//X1X2...Xk=ε,不推什么进栈private boolean productionType() {return VNTI() != "";}//推进stack栈private void pushStack() {stack.pop();String M = VNTI();String ch;//处理TE' FT' *FT'特殊情况switch (M) {case "TE'":stack.push("E'");stack.push("T");break;case "FT'":stack.push("T'");stack.push("F");break;case "*FT'":stack.push("T'");stack.push("F");stack.push("*");break;case "+TE'":stack.push("E'");stack.push("T");stack.push("+");break;default:for (int i = (M.length() - 1); i >= 0; i--) {ch = String.valueOf(M.charAt(i));stack.push(ch);}break;}System.out.printf("%-10d %-20s %-20s %s->%s\n", (++count), stack.toString(), strToken.substring(cur, strToken.length()), X, M);}//总控程序private void totalControlProgram() {while (flag) {stackPeek(); //读取当前栈顶符号令X=栈顶符号if (XisVT()) {if (X.equals(shuru1)) {cur++;shuru1 = curCharacter();stack.pop();System.out.printf("%-10d %-20s %-20s \n", (++count), stack.toString(), strToken.substring(cur, strToken.length()));} else {ERROR();}} else if (X.equals("#")) {if (X.equals(shuru1)) {flag = false;} else {ERROR();}} else if (productionType()) {if (VNTI().equals("")) {ERROR();} else if (VNTI().equals("ε")) {stack.pop();System.out.printf("%-10d %-20s %-20s %s->%s\n", (++count), stack.toString(), strToken.substring(cur, strToken.length()), X, VNTI());} else {pushStack();}} else {ERROR();}}}//出现错误private void ERROR() {System.out.println("输入串出现错误,无法进行分析");System.exit(0);}//打印存储分析表private void printf() {if (!flag) {System.out.println("****分析成功啦!****");} else {System.out.println("****分析失败了****");}}}。

编译原理_语法分析器

编译原理_语法分析器

编译原理实验报告语法分析器一.实验目的及内容实验目的:编制一个语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析。

实验内容:在上机(一)词法分析的基础上,采用递归子程序法或其他适合的语法分析方法,实现其语法分析程序。

要求编译后能检查出语法错误。

已知待分析的C语言子集的语法,用EBNF表示如下:<程序>→main()<语句块><语句块> →‘{’<语句串>‘}’<语句串> → <语句> {; <语句> };<语句> → <赋值语句> |<条件语句>|<循环语句><赋值语句>→ID=<表达式><条件语句>→if‘(‘条件’)’<语句块><循环语句>→while’(‘<条件>’)‘<语句块><条件> → <表达式><关系运算符> <表达式><表达式> →<项>{+<项>|-<项>}<项> → <因子> {* <因子> |/ <因子>}<因子> →ID|NUM| ‘(’<表达式>‘)’<关系运算符> →<|<=|>|>=|==|!=二、实验原理及基本技术路线图(方框原理图或程序流程图)三、所用仪器、材料(设备名称、型号、规格等或使用软件)1台PC以及VISUAL C++6.0软件四、实验方法、步骤(或:程序代码或操作过程)#include <iostream>#include <string>using namespace std;char prog[80],token[8];char ch;int syn,p,m,n,sum,k=0;char *key[6]={"main","int","char","if","else","while"};void scaner();void lrparser();void yucu();void statement();void expression();void term();void factor();void main(){p=0;cout<<"语法分析"<<endl;cout<<"请输入字符串,以“@”结尾:"<<endl;do {ch = getchar(); prog[p++]=ch;}while(ch!='@');p=0;scaner();lrparser();}void scaner(){sum=m=0;for(n=0;n<8;n++) token[n]=NULL;ch=prog[p++];while(ch==' ') ch=prog[p++];if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){while((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||(ch>='0'&&ch<='9')) {token[m++]=ch; ch=prog[p++];}token[m++]='\0';p--;syn=10;for(n=0;n<6;n++)if(strcmp(token,key[n])==0){syn=n+1; break;}}else if(ch>='0'&&ch<='9'){while(ch>='0'&&ch<='9'){sum=sum*10+ch-'0';ch=prog[p++];}p--;syn=20;}elseswitch(ch){case '<': m=0;token[m++]=ch;ch=prog[p++];if(ch=='<') {syn=33; token[m++]=ch;}else if(ch=='=') {syn=35; token[m++]=ch;}break;case '>': m=0;token[m++]=ch;ch=prog[p++];if(ch=='=') {syn=34; token[m++]=ch;}else {syn=32; p--;}break;case '=':token[m++]=ch;ch=prog[p++];if(ch=='='){ syn=36;token[m++]=ch;}else{ syn=21;p--;}break;case ':': m=0;token[m++]=ch;ch=prog[p++];if(ch=='=') {syn=18; token[m++]=ch;}else {syn=17; p--;}break;case '+': syn=22; token[0]=ch; break;case '-': syn=23; token[0]=ch; break;case '*': syn=24; token[0]=ch; break;case '/': syn=25; token[0]=ch; break;case ';': syn=31; token[0]=ch; break;case '(': syn=26; token[0]=ch; break;case ')': syn=27; token[0]=ch; break;case '@': syn=0; token[0]=ch; break;default : syn=-1;}}void lrparser(){if(syn==1){scaner();yucu();if(syn=6){scaner();if(syn==0 && (k==0))cout<<"\nsuccess\n"<<endl;}else{if(k!=1)cout<<"\nwhile error\n"<<endl;k=1;}}else{cout<<"\nmain error\n"<<endl;k=1;}return;}void yucu(){statement();while(syn==31){scaner();statement();}return;}void statement(){if(syn==10){scaner();if(syn==18){scaner();expression();}else{cout<<"\nscentence error\n"<<endl;k=1;}}return;}void expression(){term();while(syn==22||syn==23){scaner();term();}return;}void term(){factor();while(syn==24||syn==25){scaner();factor();}return;}void factor(){if(syn==10||syn==20)scaner();else if(syn==26){scaner();expression();if(syn==27)scaner();else{cout<<"( error"<<endl;k=1;}}else{cout<<"expression error"<<endl;k=1;}return;}五、实验过程原始记录( 测试数据、图表、计算等)六、实验结果、分析和结论(误差分析与数据处理、成果总结等。

编译原理词法分析器

编译原理词法分析器

编译原理词法分析器编译原理是计算机科学中的重要领域,而词法分析器则是编译器的第一个阶段。

它的主要任务是将源代码转化为一个个词法单元,以便接下来的语法分析和语义分析等阶段进行处理。

在本文中,我们将深入探讨词法分析器的原理和实现。

一、什么是词法分析器词法分析器(Lexical Analyzer)是编译器中实现词法分析的部分。

它负责从源代码中提取出各个合法的词法单元,并进行分类和标记。

词法单元通常包括关键字、标识符、运算符、分隔符和常量等。

二、词法分析器的原理词法分析器的工作原理可以概括为以下几个步骤:1. 预处理:词法分析器首先会对源代码进行预处理,去除注释、替换宏定义等。

2. 分割:将预处理后的源代码分割成一个个字符。

3. 匹配:根据预定义的词法规则,将字符序列匹配到对应的词法单元上。

4. 标记:对每个词法单元都打上相应的标记,以便后续的语法分析。

三、词法分析器的实现1. 正则表达式:词法分析器通常使用正则表达式定义词法规则,用以匹配词法单元。

例如,使用正则表达式"\d+"可以匹配一个或多个数字。

2. 有限自动机:词法分析器可以通过构造有限自动机来进行词法分析。

有限自动机可以根据当前状态和输入字符进行状态转移,最终得到一个词法单元的序列。

3. 符号表:词法分析器使用符号表来存储已经识别出的标识符和关键字,并为每个标识符分配一个唯一的标识符号。

四、应用举例以C语言为例,假设我们要编写一个词法分析器来分析C源代码。

下面是一个简单的示例代码:```c#include <stdio.h>int main() {int a = 10;printf("Hello, World!\n");return 0;}```我们可以使用词法分析器将其分解为以下词法单元序列:1. 关键字:include、stdio、int、main、return2. 标识符:a3. 运算符:=4. 常量:105. 分隔符:()、{}6. 函数名:printf7. 字符串常量:"Hello, World!\n"通过词法分析器的处理,我们可以将源代码转化为一个个词法单元,为后续的语法分析提供准备。

编译原理实验词法分析器与语法分析器实现

编译原理实验词法分析器与语法分析器实现

编译原理实验词法分析器与语法分析器实现词法分析器与语法分析器是编译器的两个重要组成部分,它们在编译过程中扮演着至关重要的角色。

词法分析器负责将源代码转化为一个个标记(token)序列,而语法分析器则根据词法分析器生成的标记序列构建语法树,验证源代码的语法正确性。

本实验旨在实现一个简单的词法分析器和语法分析器。

实验一:词法分析器实现在实现词法分析器之前,需要定义所需词法项的规则。

以C语言为例,常见的词法项包括关键字(如int、if、for等)、标识符、运算符(如+、-、*、/等)、常量(如整数、浮点数等)和分隔符(如括号、逗号等)。

接下来,我们来实现一个简单的C语言词法分析器。

1. 定义词法项的规则在C语言中,关键字和标识符由字母、数字和下划线组成,且首字符不能为数字。

运算符包括各种数学运算符和逻辑运算符。

常量包括整数和浮点数。

分隔符包括括号、逗号等。

2. 实现词法分析器的代码下面是一个简单的C语言词法分析器的实现代码:```pythondef lexer(source_code):keywords = ['int', 'if', 'for'] # 关键字列表operators = ['+', '-', '*', '/'] # 运算符列表separators = ['(', ')', '{', '}', ',', ';'] # 分隔符列表tokens = [] # 标记序列列表current_token = '' # 当前标记for char in source_code:if char.isspace(): # 如果是空格,则忽略continueelif char.isalpha(): # 如果是字母,则可能是关键字或标识符的一部分current_token += charelif char.isdigit(): # 如果是数字,则可能是常量的一部分current_token += charelif char in operators or char in separators: # 如果是运算符或分隔符,则当前标记结束if current_token:tokens.append(current_token)current_token = ''tokens.append(char)else: # 如果是其他字符,则当前标记结束if current_token:tokens.append(current_token)current_token = ''return tokens```以上代码通过遍历源代码的字符,根据定义的规则生成一个个标记,存储在`tokens`列表中。

编译原理实验报告(词法分析器语法分析器)

编译原理实验报告(词法分析器语法分析器)

编译原理实验报告实验一一、实验名称:词法分析器的设计二、实验目的:1,词法分析器能够识别简单语言的单词符号2,识别出并输出简单语言的基本字.标示符.无符号整数.运算符.和界符。

三、实验要求:给出一个简单语言单词符号的种别编码词法分析器四、实验原理:1、词法分析程序的算法思想算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。

2、程序流程图(1)主程序(2)扫描子程序3、各种单词符号对应的种别码五、实验容:1、实验分析编写程序时,先定义几个全局变量a[]、token[](均为字符串数组),c,s( char型),i,j,k (int型),a[]用来存放输入的字符串,token[]另一个则用来帮助识别单词符号,s用来表示正在分析的字符。

字符串输入之后,逐个分析输入字符,判断其是否‘#’,若是表示字符串输入分析完毕,结束分析程序,若否则通过int digit(char c)、int letter(char c)判断其是数字,字符还是算术符,分别为用以判断数字或字符的情况,算术符的判断可以在switch语句中进行,还要通过函数int lookup(char token[])来判断标识符和保留字。

2 实验词法分析器源程序:#include <stdio.h>#include <math.h>#include <string.h>int i,j,k;char c,s,a[20],token[20]={'0'};int letter(char s){if((s>=97)&&(s<=122)) return(1);else return(0);}int digit(char s){if((s>=48)&&(s<=57)) return(1);else return(0);}void get(){s=a[i];i=i+1;}void retract(){i=i-1;}int lookup(char token[20]){if(strcmp(token,"while")==0) return(1);else if(strcmp(token,"if")==0) return(2);else if(strcmp(token,"else")==0) return(3);else if(strcmp(token,"switch")==0) return(4);else if(strcmp(token,"case")==0) return(5);else return(0);}void main(){printf("please input string :\n");i=0;do{i=i+1;scanf("%c",&a[i]);}while(a[i]!='#');i=1;j=0;get();while(s!='#'){ memset(token,0,20);switch(s){case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':case 'g':case 'h':case 'i':case 'j':case 'k':case 'l':case 'm':case 'n':case 'o':case 'p':case 'q':case 'r':case 's':case 't':case 'u':case 'v':case 'w':case 'x':case 'y':case 'z':while(letter(s)||digit(s)){token[j]=s;j=j+1;get();}retract();k=lookup(token);if(k==0)printf("(%d,%s)",6,token);else printf("(%d,-)",k);break;case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':while(digit(s)){token[j]=s;j=j+1;get();}retract();printf("%d,%s",7,token);break;case '+':printf("('+',NULL)");break;case '-':printf("('-',null)");break; case '*':printf("('*',null)");break;case '<':get();if(s=='=') printf("(relop,LE)");else{retract();printf("(relop,LT)");}break;case '=':get();if(s=='=')printf("(relop,EQ)");else{retract();printf("('=',null)");}break;case ';':printf("(;,null)");break;case ' ':break;default:printf("!\n");}j=0;get();} }六:实验结果:实验二一、实验名称:语法分析器的设计二、实验目的:用C语言编写对一个算术表达式实现语法分析的语法分析程序,并以四元式的形式输出,以加深对语法语义分析原理的理解,掌握语法分析程序的实现方法和技术。

编译原理语法分析器

编译原理语法分析器

编译原理语法分析器编译原理语法分析器是编译器中的重要组成部分,它负责将源代码解析成抽象语法树,为后续的语义分析和代码生成做准备。

本文将介绍语法分析器的原理、分类和常用算法。

一、语法分析器的原理语法分析器的主要任务是根据给定的文法定义,将源代码解析成一个个语法单元,并构建出一棵抽象语法树。

它通过递归下降、预测分析和LR分析等算法来实现。

1. 递归下降法递归下降法是一种基于产生式的自顶向下分析方法。

它从文法的开始符号出发,通过不断地推导和回溯,逐步地构建抽象语法树。

递归下降法易于理解和实现,但对左递归和回溯有一定的局限性。

2. 预测分析法预测分析法也是自顶向下的分析方法,它通过预测下一个输入符号来选择适当的产生式进行推导。

为了提高效率,预测分析法使用预测分析表来存储各个非终结符和终结符的关系。

3. LR分析法LR分析法是一种自底向上的分析方法,它使用LR自动机和LR分析表来进行分析。

LR自动机是一个有限状态控制器,通过状态转移和规约动作来解析源代码。

LR分析表存储了状态转移和规约的规则。

二、语法分析器的分类根据语法分析器的特性和实现方式,可以将其分为LL分析器和LR 分析器。

1. LL分析器LL分析器是基于递归下降法和预测分析法的一类分析器。

它从左到右、从左到右地扫描源代码,并根据预测分析表进行推导。

常见的LL分析器有LL(1)分析器和LL(k)分析器。

2. LR分析器LR分析器是基于LR分析法的一类分析器。

它先通过移进-归约的方式建立一棵语法树,然后再进行规约操作。

LR分析器具有强大的语法处理能力,常见的LR分析器有LR(0)、SLR(1)、LR(1)和LALR(1)分析器。

三、常用的语法分析算法除了递归下降法、预测分析法和LR分析法,还有一些其他的语法分析算法。

1. LL算法LL算法是一种递归下降法的改进算法,它通过构造LL表和预测分析表实现分析过程。

LL算法具有很好的可读性和易于理解的特点。

2. LR算法LR算法是一种自底向上的分析方法,它通过建立LR自动机和构造LR分析表来进行分析。

编译原理词法语法语义分析器设计_毕业设计

编译原理词法语法语义分析器设计_毕业设计

编译技术课程设计二零一一年七月编译技术课程设计一、目的<<编译技术>>是理论与实践并重的课程,而其实验课要综合运用一、二年级所学的多门课程的内容,用来完成一个小型编译程序。

从而巩固和加强对词法分析、语法分析、语义分析、代码生成和报错处理等理论的认识和理解;培养学生对完整系统的独立分析和设计的能力,进一步培养学生的独立编程能力。

二、任务及要求基本要求:1.词法分析器产生下述小语言的单词序列这个小语言的所有的单词符号,以及它们的种别编码和内部值如下表:对于这个小语言,有几点重要的限制:首先,所有的关键字(如IF﹑WHILE等)都是“保留字”。

所谓的保留字的意思是,用户不得使用它们作为自己定义的标示符。

例如,下面的写法是绝对禁止的: IF(5)=x其次,由于把关键字作为保留字,故可以把关键字作为一类特殊标示符来处理。

也就是说,对于关键字不专设对应的转换图。

但把它们(及其种别编码)预先安排在一张表格中(此表叫作保留字表)。

当转换图识别出一个标识符时,就去查对这张表,确定它是否为一个关键字。

再次,如果关键字、标识符和常数之间没有确定的运算符或界符作间隔,则必须至少用一个空白符作间隔(此时,空白符不再是完全没有意义的了)。

例如,一个条件语句应写为IF i>0 i= 1;而绝对不要写成IFi>0 i=1;因为对于后者,我们的分析器将无条件地将IFI看成一个标识符。

这个小语言的单词符号的状态转换图,如下图:2.语法分析器能识别由加+ 减- 乘* 除/ 乘方^ 括号()操作数所组成的算术表达式,其文法如下:E→E+T|E-T|TT→T*F|T/F|FF→P^F|Pp→(E)|i使用的算法可以是:预测分析法;递归下降分析法;算符优先分析法;LR分析法等。

3.中间代码生成器产生上述算术表达式的中间代码(四元式序列)较高要求:1.扩充上述小语言的单词;2.增加语法分析器的功能,能识别条件语句和循环语句等;3.增加中间代码生成器的功能,能产生条件语句和循环语句等的中间代码(四元式序列)4.增加报错功能;5.将中间代码翻译成汇编语言。

语法分析器的设计与实现

语法分析器的设计与实现

辅导教师成绩实验日期实验时间1 实验名称语法分析器的设计与实现2、实验目的掌握自上而下语法分析方法、自下而上语法分析方法3、实验要求(1)实验内容:四选一①设计及实现能够识别表达式的预测分析程序。

文法如下:G[E] :E->E+T|TT->T*F|FF->(E)|i②设计及实现能够识别表达式的LR分析程序。

文法如下:G[E] :E->E+T|TT->T*F|FF->(E)|i③设计及实现能够识别表达式的算符优先分析程序。

文法如下:G[E] :E->E+T|TT->T*F|FF- >P↑F|PP->(E)|i④设计及实现计算表达式的计算器。

表达式中可包含 +、- 、* 、/ 、(、)运算符。

(2)实验要求:对已给的一个二元式形式表达式,能够检查有无语法错误。

并指定出错位置。

将表达式的语法树输出(或将语法分析过程输出)。

4、实验原理根据自上而下和自下而上的语法分析思想实现语法分析程序。

5、实验步骤(1)根据文法构造语法分析表。

(2)编写总控程序实现语法分析。

6、状态转换图及词法分析程序#include<iostream>#include<stdio.h>#include <string>#include <stack>using namespacestd;char Vn[]={'E','e','T','t','F'};//定义文法的非终结符,小写字母 e 表示E’char Vt[]={'i','+','*','(',')','#'};//定义文法的终结符int LENVt=sizeof(Vt);void showstack(stack<char> st)//从栈底开始显示栈中的内容{int i,j;char ch[100];j=st.size();for(i=0;i<j;i++){ch[i]=st.top();st.pop();}for(i=j-1;i>=0;i--){cout<<ch[i];st.push(ch[i]);}}int find(char c,chararray[],int n)//查找函数,返回布尔值{int i;int flag=0;for(i=0;i<n;i++){if(c==array[i])flag=1;}return flag;}int location(charc,char array[])//定位函数 ,指出字符所在位置,即将字母转换为数组下标值{int i;for(i=0;c!=array[i];i++);return i;}void error(){cout<<"出错 !"<<endl;}void analyse(charVn[],char Vt[],string M[5][6],string str) {int i,j,p,q,h,flag=1;char a,X;stack<char> st;//定义堆栈st.push('#');st.push(Vn[0]); j=0;//#与识别符号入栈//j 指向输入串的指针h=1;a=str[j];cout<<"步骤"<<" 分析栈"<<" 剩余输入串"<<"所用产生式"<<endl;while(flag==1){cout<<h<<"";h++;showstack(st);cout<<"for(i=j;i<str.size();i++) cout<<str[i]; X=st.top();if(find(X,Vt,LENVt)==1)if(X==a)";//显示步骤//显示分析栈中内容//显示剩余字符串//取栈顶符号放入 X//X 是终结符//分析栈的栈顶元素和剩余输入串的第一个元素相比较if (X!='#'){cout<<""<<X<<"匹配 "<<endl;st.pop();a=str[++j];//读入输入串的下一字符}else{cout<<""<<" 接受 !"<<endl<<endl; flag=0;}else{error();break;}else{p=location(X,Vn);//实现下标的转换(非终结符转换为行下标)q=location(a,Vt);//实现下标的转换(终结符转换为列下标)string S1("NULL"),S2("null");if(M[p][q]==S1 || M[p][q]==S2)//查找二维数组中的产生式{error();break;}//对应项为空,则出错else{string str0=M[p][q];cout<<""<<X<<"-->"<<str0<<endl; //显示对应的产生式st.pop();if(str0!="$")//$代表“空”字符 for(i=str0.size()-1;i>=0;i--)st.push(str0[i]);//产生式右端逆序进栈}}}}main(){string M[5][6]={"Te","NULL","NULL","Te","NULL","NULL","NULL","+Te" ,"NULL","NULL","$","$","Ft", "NULL","NULL","Ft","NULL","NULL","NULL","$","*Ft", "NULL","$","$","i","NULL","NULL","(E)", "NULL","NULL"};//预测分析表jstring str;int errflag,i;cout<<"文法: E->E+T|T T->T*F|F F->(E)|i"<<endl;cout<<"请输入分析串(以 #结束):"<<endl;do{ errflag=0; cin>>str;for(i=0;i<str.size();i++)if(!find(str[i],Vt,LENVt)){cout<<"输入串中包含有非终结符 "<<str[i]<<"( 输入错误 )!"<<endl;errflag=1;}} while(errflag==1); //判断输入串的合法性analyse(Vn,Vt, M,str);return 0;}7、测试及结果8、心得如果有需要的请下载,并不是本人写的,我只是图方便转发一下。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

《编译原理》实验报告题目: 语法分析器的制作
学生姓名:江荣吉
班级:
学号:
指导教师:
成绩:
西安邮电大学计算机学院
2015 年 6 月 7 日
一:实验目的
熟悉语法分析的过程;
理解相关文法的步骤;
熟悉First集和Follow集生成
二:实验要求
对于给定的文法,试编写调试一个语法分析程序:
要求和提示:
(1)可选择一种你感兴趣的语法分析方法(LL(1)、算符优先、递归下降、SLR(1)等)作为编制语法分析程序的依据。

(2)对于所选定的分析方法,如有需要,应选择一种合适的数据结构,以构造所给文法的机内表示。

(3)能进行分析过程模拟。

如输入一个句子,能输出与句子对应的语法树,能对语法树生成过程进行模拟;能够输出分析过程每一步符号栈的变化情
况。

设计一个由给定文法生成First集和Follow集并进行简化的算法动态模拟。

三:实验过程
1:文法:
E->TE’
E’->+TE’|ε
T->FT’
T’->*FT’|ε
F->(E)|i:
2程序描述(LL(1)文法)
本程序是基于已构建好的某一个语法的预测分析表来对用户的输入字符串进行分析,判断输入的字符串是否属于该文法的句子。

基本实现思想:接收用户输入的字符串(字符串以“#”表示结束)后,对用做分析栈的一维数组和存放分析表的二维数组进行初始化。

然后取出分析栈的栈顶字符,判断是否为终结符,若为终结符则判断是否为“#”且与当前输入符号一样,若是则语法分析结束,输入的字符串为文法的一个句子,否则出错若不为“#”且与当前输入符号一样则将栈顶符号出栈,当前输入符号从输入字符串中除去,进入下一个字符的分析。

若不为“#”且不与当前输入符号一样,则出错。

3:流程图
4:该文法的预测分析表为:
四:实验结果
1、显示预测分析表,提示用户输入字符串
2、输入的字符串为正确的句子:
3、输入的字符串中包含了不属于终结符集的字符
4、输入的字符串不是该文法能推导出来的句子
五:实验心得
通过本次实验基本掌握了语法分析的原理和LL(1)语法分析方法,以及预测分析表的构造;进一步熟悉了语法分析的详细过程。

通过编写程序进一步复习巩固了java语言和数据结构的相关知识,尤其是加深了对栈相关知识的印象;
在编程过程中遇到了很多基础性问题,通过不断的查阅课本,最终解决了问题,但程序仍然存在很多值得改进和完善的地方,这就提醒我们在以后的学习过程当中应该及时复习巩固以前学过的相关知识。

相关文档
最新文档