编译原理—语法分析器(Java)

递归下降语法分析

1. 语法成分说明
<语句块> ::= begin<语句串> end
<语句串> ::= <语句>{;<语句>}
<语句> ::= <赋值语句> | <循环语句> | <条件语句>
<关系运算符> ::= < | <= | >= | > | == | !=
<赋值语句> ::= ID:=<表达式>
<表达式> ::= <项>{+<项> | -<项> }
<项> ::= <因子>{*<因子> | /<因子> }
<因子> ::= ID | NUM | <表达式>

2. 相应的上下文无关文法
*P — > begin S end
S — >A S1 | B S1 | C S1
S1— >S | ε
R — > < | <= | >= | > | == | !=
A — >I:=E;
E— >T E1
E1— >+TE1 | -TE1 | ε
T— >F T1
T1— >FT1 | /FT1 | ε
F — > (E) | I

测试样例

i:=5+i*(i/3-i);
i:=i+i;
end
#

在这里插入图片描述

语法分析

public class GrammarAnalysis {static char[] s = new char[100];static int sing;static int i; //用来记录数组s中的下标;static int error=0;static void P() {if(Objects.equals(analyzer.llist.get(i), "begin")) {++i;S();
//处理if(Objects.equals(analyzer.llist.get(i), "end")) {++i;}else{System.out.println("error!--------不是结尾符号end,"+"程序第"+analyzer.map.get(i)+"行出现语法错误");error++;++i;}}else {System.out.println("error!--------缺少开头符号begin,"+"程序第"+analyzer.map.get(i)+"行出现语法错误");error++;S();
//处理if(Objects.equals(analyzer.llist.get(i), "end")) {++i;}else{System.out.println("error!--------不是结尾符号end,"+"程序第"+analyzer.map.get(i)+"行出现语法错误");error++;++i;}}}static void S() {A();if(Objects.equals(analyzer.llist.get(i), ";")) {++i;// if(s[i]!='e') {S1();// }}else {System.out.println("error!-----------缺少结尾符号;"+",程序第"+analyzer.map.get(i)+"行出现语法错误");error++;++i;S1();}}static void S1() {if(!Objects.equals(analyzer.llist.get(i), "end")) {// ++i;S();}}static void A() {if(i+1<analyzer.llist.size()&&Objects.equals(analyzer.llist.get(i+1), ":=")) {++i;++i;E();if(Objects.equals(analyzer.llist.get(i), ")") || Objects.equals(analyzer.llist.get(i), ";")) {if(Objects.equals(analyzer.llist.get(i), ")")) {++i;}}else {System.out.println("error!--------不是结尾符号;或者)"+",程序第"+analyzer.map.get(i)+"行出现语法错误");error++;++i;}}else {System.out.println("error!---------不是赋值语句"+",程序第"+analyzer.map.get(i)+"行出现语法错误");error++;++i;++i;E();if(Objects.equals(analyzer.llist.get(i), ")") || Objects.equals(analyzer.llist.get(i), ";")) {if(Objects.equals(analyzer.llist.get(i), ")")) {++i;}}else {System.out.println("error!--------不是结尾符号;或者)"+",程序第"+analyzer.map.get(i)+"行出现语法错误");error++;++i;}}}static void E() {T();if(Objects.equals(analyzer.llist.get(i), "+") || Objects.equals(analyzer.llist.get(i), "-") || Objects.equals(analyzer.llist.get(i), ";") || Objects.equals(analyzer.llist.get(i), ")")) {E1();}else {System.out.println("error!-----------不是结尾符号+或者-或者;或者)"+",程序第"+analyzer.map.get(i)+"行出现语法错误"); error++;E1();}}static void T() {F();if(Objects.equals(analyzer.llist.get(i), "+") || Objects.equals(analyzer.llist.get(i), "-") || Objects.equals(analyzer.llist.get(i), ";") || Objects.equals(analyzer.llist.get(i), ")") || Objects.equals(analyzer.llist.get(i), "*") || Objects.equals(analyzer.llist.get(i), "/")) {T1();}}static void F() {if(Objects.equals(analyzer.llist.get(i), "(")) {++i;E();}else {++i;}}static void T1() {if(Objects.equals(analyzer.llist.get(i), "*")) {++i;F();T1();}else if(Objects.equals(analyzer.llist.get(i), "/")){++i;F();T1();}}static void E1() {if(Objects.equals(analyzer.llist.get(i), "+")) {++i;T();E1();}else if(Objects.equals(analyzer.llist.get(i), "-")){++i;T();E1();}}public static void main(String[] args) {Scanner sc=new Scanner(System.in);System.out.println("==词法分析程序==");System.out.println("从文件中读取程序");System.out.println("==============");analyzer.initToken();analyzer.ReadFile1();System.out.println("语法分析中....,请稍候");i=0;sing=0;if(Objects.equals(analyzer.llist.get(0), "#")) System.exit(-1);P();if(Objects.equals(analyzer.llist.get(i), "#")) {}else {System.out.println("error!-------不是结尾符号#"+analyzer.llist.get(i)+i);error++;}System.out.println("===词法分析完成===");System.out.println("共检查出"+error+"个语法错误");}}

词法分析

public class analyzer {public static List<String> llist=new ArrayList<>();static  Map<Integer,Integer> map=new HashMap<>();final static String ID = "\\p{Alpha}(\\p{Alpha}|\\d)*";static  int countLine=1;/** 整形常数 NUM >> 正则表达式*/final static String NUM = "\\d\\d*";/** token 词法单元* <词符号, 种别码> *//** 关键字 token*/static Map<String, Integer> TOKEN_KEYWORDS;/** 运算符/界符 token */static Map<String, Integer> TOKEN_OPERATOR_BOUNDARY;/** 其他单词 token*/static Map<String, Integer> TOKEN_ID_SUM;/** 文件根目录*/static final String ROOT_DIRECTORY = "program.txt";/*** 初始化 token 单元*/public static void initToken(){//种别码创建TOKEN_KEYWORDS = new HashMap<String, Integer>(){//关键字{put("begin", 1);put("if", 2);put("then", 3);put("while", 4);put("do", 5);put("end", 6);}};TOKEN_OPERATOR_BOUNDARY= new HashMap<String, Integer>(){//运算符和界符{put("+", 13);put("-", 14);put("*", 15);put("/", 16);put(":", 17);put(":=", 18);put("<", 20);put("<>", 21);put("<=", 22);put(">", 23);put(">=", 24);put("=", 25);put(";", 26);put("(", 27);put(")", 28);put("#", 0);}};TOKEN_ID_SUM= new HashMap<String, Integer>(){//标识符和整型常数{put(ID, 10);put(NUM, 11);}};}/*** 读 源程序 文件*/public static void ReadFile1() {FileInputStream fis = null;InputStreamReader isr = null;BufferedReader br = null;try {fis = new FileInputStream(ROOT_DIRECTORY);isr = new InputStreamReader(fis, "UTF-8"); // 转化类br = new BufferedReader(isr); // 装饰类String line;/** 记录 程序 行数 */while ((line = br.readLine()) != null) {  // 每次读取一行,分析一行boolean answer = lexicalAnalysis(line);if(answer == false){System.out.printf("ERROR 编译错误=== 第 %d 行出现 词法错误 \n", countLine);break;}countLine++;}System.out.printf("===词法分析完成===\n");} catch (Exception ex) {ex.printStackTrace();} finally {try {br.close(); // 关闭最后一个类,会将所有的底层流都关闭} catch (Exception ex) {ex.printStackTrace();}}}/** 判断key是否是其他单词*/private static boolean isIDOrSUM(String key){if (key.matches(ID) ) {llist.add(key);map.put(llist.size()-1,countLine);System.out.printf("(%d, %s)\n", TOKEN_ID_SUM.get(ID), key);}else if (key.matches(NUM)) {llist.add(key);map.put(llist.size()-1,countLine);System.out.printf("(%d, %s)\n", TOKEN_ID_SUM.get(NUM), key);}else {return false;}return true;}/*** 进行 词法分析* @param word 要分析的字符串* @return 结果*/public static boolean  lexicalAnalysis(String word){word = word.trim(); // 去首尾空格String[] strings = word.split("\\p{Space}+"); // 分割字符串,保证处理的字符串没有空格for (String string : strings) {/** 3种情况:*      1. 关键字 == end (关键字的后面一定是空格 )*      2. 运算符/ 分界符 == continue*      3. 其他单词 == continue*/String key = "";for (int i = 0; i < string.length(); i++){String indexChar = String.valueOf(string.charAt(i)) ;if(i+1<string.length()){if((indexChar+string.charAt(i+1)).equals("//"))return true;}/** 是 运算符 或者 关键字*/if (TOKEN_OPERATOR_BOUNDARY.containsKey(indexChar) ||TOKEN_KEYWORDS.containsKey(string.substring(i, string.length()))){if (key.length() > 0) {if (isIDOrSUM(key) == false) {/** 词法错误 */return false;}key = "";}if(TOKEN_OPERATOR_BOUNDARY.containsKey(indexChar)) {/**  1. 是 运算符/分界符 */key += indexChar;if(i + 1 < string.length() && TOKEN_OPERATOR_BOUNDARY.containsKey(indexChar + string.charAt(i+1))){ // 运算分界符key += string.charAt(++i);}llist.add(key);map.put(llist.size()-1,countLine);System.out.printf("(%d, %s)\n",TOKEN_OPERATOR_BOUNDARY.get(key),key);key = "";}else if(TOKEN_KEYWORDS.containsKey(key = string.substring(i, string.length()))) {/** 2. 是关键字*/llist.add(key);map.put(llist.size()-1,countLine);System.out.printf("(%d, %s)\n",TOKEN_KEYWORDS.get(key),key);key = "";break;}}else {/** 是其他单词*/key += indexChar;/** 其他单词后面是 1. 换行,2. 运算符/界符 3. 其他单词*/if(i+1 >= string.length()){if (isIDOrSUM(key) == false) {/** 词法错误 */return false;}}}}}return true;}public analyzer() {}public static void main(String[] args) {initToken();System.out.println("==词法分析程序==");System.out.println("从文件中读取程序");System.out.println("==============");ReadFile1(); for(String s:llist) System.out.println(s);System.out.println();}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/392138.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

编译原理—语义分析(Java)

递归下降语法制导翻译 实现含多条简单赋值语句的简化语言的语义分析和中间代码生成。 测试样例 begin a:2; b:4; c:c-1; area:3.14*a*a; s:2*3.1416*r*(hr); end #词法分析 public class analyzer {public static List<String> llistnew ArrayList<>();static …

linux boot菜单列表,Bootstrap 下拉菜单(Dropdowns)简介

Bootstrap 下拉菜单是可切换的&#xff0c;是以列表格式显示链接的上下文菜单。这可以通过与 下拉菜单(Dropdown) JavaScript 插件 的互动来实现。如需使用下拉菜单&#xff0c;只需要在 class .dropdown 内加上下拉菜单即可。下面的实例演示了基本的下拉菜单&#xff1a;实例主…

数据挖掘—Apriori算法(Java实现)

算法描述 &#xff08;1&#xff09;扫描全部数据&#xff0c;产生候选1-项集的集合C1&#xff1b; &#xff08;2&#xff09;根据最小支持度&#xff0c;由候选1-项集的集合C1产生频繁1-项集的集合L1&#xff1b; &#xff08;3&#xff09;对k>1&#xff0c;重复执行步骤…

泰晤士报下载_《泰晤士报》和《星期日泰晤士报》新闻编辑室中具有指标的冒险活动-第1部分:问题

泰晤士报下载TLDR: Designing metrics that help you make better decisions is hard. In The Times and The Sunday Times newsrooms, we have spent a lot of time trying to tackle three particular problems.TLDR &#xff1a;设计度量标准以帮助您做出更好的决策非常困难…

背景消除的魔力

图片的功能非常强大&#xff0c;有一图胜千言的效果&#xff0c;所以在文档或演示文稿中使用图片来增加趣味性是一种很棒的想法。但问题是&#xff0c;图片通常会变为文字中间的独立矩形&#xff0c;而不是真正与内容融合在一起。您可以在图片中放置边框或效果&#xff0c;使其…

数据挖掘—BP神经网络(Java实现)

public class Test {public static void main(String args[]) throws Exception {ArrayList<ArrayList<Double>> alllist new ArrayList<ArrayList<Double>>(); // 存放所有数据ArrayList<String> outlist new ArrayList<String>(); // …

特征工程tf-idf_特征工程-保留和删除的内容

特征工程tf-idfThe next step after exploring the patterns in data is feature engineering. Any operation performed on the features/columns which could help us in making a prediction from the data could be termed as Feature Engineering. This would include the…

monkey测试===通过monkey测试检查app内存泄漏和cpu占用

最近一直在研究monkey测试。网上资料很多&#xff0c;但都是一个抄一个的。原创的很少 我把检查app内存泄漏的情况梳理一下&#xff1a; 参考资料&#xff1a; Monkey测试策略&#xff1a;https://testerhome.com/topics/597 Android Monkey测试详细介绍&#xff1a;http://www…

三维空间两直线/线段最短距离、线段计算算法 【转】

https://segmentfault.com/a/1190000006111226d(ls,lt)|sj−tj||s0−t0(be−cd)u⃗ −(ae−bd)v⃗ ac−bd(ls,lt)|sj−tj||s0−t0(be−cd)u⃗ −(ae−bd)v⃗ ac−b2|具体实现代码如下&#xff08;C#实现&#xff09;&#xff1a; public bool IsEqual(double d1, double d2) { …

iOS绘圆形图-CGContextAddArc各参数说明

2019独角兽企业重金招聘Python工程师标准>>> 1.使用 UIGraphicsGetCurrentContext() 画圆 CGContextAddArc(<#CGContextRef _Nullable c#>, <#CGFloat x#>, <#CGFloat y#>, <#CGFloat radius#>, <#CGFloat startAngle#>, <#CGFlo…

[收藏转载]C# GDI+ 简单绘图(一)

最近对GDI这个东西接触的比较多&#xff0c;也做了些简单的实例&#xff0c;比如绘图板&#xff0c;仿QQ截图等&#xff0e; 废话不多说了&#xff0c;我们先来认识一下这个GDI&#xff0c;看看它到底长什么样. GDI&#xff1a;Graphics Device Interface Plus也就是图形设备接…

mybaties总结+hibernate总结

一、对原生态jdbc程序中问题总结 1.1 jdbc程序 需求&#xff1a;使用jdbc查询mysql数据库中用户表的记录 statement:向数据库中发送一个sql语句 预编译statement&#xff1a;好处&#xff1a;提高数据库性能。 预编译statement向数据库中发送一个sql语句&#xff0c;数据库编译…

Python14 函数

函数 面向对象编程&#xff1a; 类----class 面向过程编程&#xff1a;过程---def 函数式编程&#xff1a;函数---def def test(x):描述x 1return x#def是定义函数的关键字#test是函数名称#&#xff08;x&#xff09;是参数#x1是 函数体&#xff0c;是一段逻辑代码#return 定义…

pandas之数值计算与统计

数值计算与统计 对于DataFrame来说&#xff0c;求和、最大、最小、平均等统计方法&#xff0c;默认是按列进行统计&#xff0c;即axis 0&#xff0c;如果添加参数axis 1则会按照行进行统计。 如果存在空值&#xff0c;在统计时默认会忽略空值&#xff0c;如果添加参数skipna …

python自动化数据报告_如何:使用Python将实时数据自动化到您的网站

python自动化数据报告This tutorial will be helpful for people who have a website that hosts live data on a cloud service but are unsure how to completely automate the updating of the live data so the website becomes hassle free. For example: I host a websit…

android intent参数是上次的结果,【Android】7.0 Intent向下一个活动传递数据、返回数据给上一个活动...

1.0 可以利用Intent吧数据传递给上一个活动&#xff0c;新建一个叫“hellotest01”的项目。新建活动FirstActivity&#xff0c;勾选“Generate Layout File”和“Launcher Activity”。image修改AndroidMainifest.xml中的内容&#xff1a;android:name".FirstActivity&quo…

学习深度学习需要哪些知识_您想了解的有关深度学习的所有知识

学习深度学习需要哪些知识有关深层学习的FAU讲义 (FAU LECTURE NOTES ON DEEP LEARNING) Corona was a huge challenge for many of us and affected our lives in a variety of ways. I have been teaching a class on Deep Learning at Friedrich-Alexander-University Erlan…

html5--3.16 button元素

html5--3.16 button元素 学习要点 掌握button元素的使用button元素 用来建立一个按钮从功能上来说&#xff0c;与input元素建立的按钮相同button元素是双标签&#xff0c;其内部可以配置图片与文字&#xff0c;进行更复杂的样式设计不仅可以在表单中使用&#xff0c;还可以在其…

如何注册鸿蒙id,鸿蒙系统真机调试证书 和 设备ID获取

鸿蒙系统真机调试创建项目创建项目创建应用创建鸿蒙应用(注意&#xff0c;测试阶段需要发邮件申请即可)关联应用项目进入关联 添加引用准备调试使用的 p12 和证书请求 csr使用以下命令// 别名"test"可以修改&#xff0c;但必须前后一致&#xff0c;密码请自行修改key…

读zepto核心源码学习JS笔记(3)--zepto.init()

上篇已经讲解了zepto.init()的几种情况,这篇就继续记录这几种情况下的具体分析. 1. 首先是第一种情况,selector为空 既然是反向分析,那我们先看看这句话的代码; if (!selector) return zepto.Z() 这里的返回值为zepto.Z();那我们继续往上找zepto.Z()函数 zepto.Z function(dom…