编译原理—语法分析器(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,一经查实,立即删除!

相关文章

老笔记整理四:字符串的完美度

今天在宠果网上发现一道题目&#xff0c;求一个字符串的完美度http://hero.pongo.cn/home/index觉得这道题很有趣就挑战了一下&#xff0c;结果没有在规定的1小时里面写完&#xff08;笑&#xff09;&#xff0c;多花了10分钟终于做出来了。题目是这样的&#xff1a;我们要给每…

nlp构建_使用NLP构建自杀性推文分类器

nlp构建Over the years, suicide has been one of the major causes of death worldwide, According to Wikipedia, Suicide resulted in 828,000 global deaths in 2015, an increase from 712,000 deaths in 1990. This makes suicide the 10th leading cause of death world…

域名跳转

案例&#xff1a;当访问lsx.com网站&#xff0c;是我最早论坛的域名。回车之后会自动跳转到lshx.com。 为什么药lsx跳转到lshx.com呢&#xff1f; 为了统一品牌。建议换成了lshx.com。所有之前的lsx.com就不要用了&#xff0c;就让它跳转到lshx.com。是因为之前lsx.com上有很多…

Elastic Stack 安装

Elastic Stack 是一套支持数据采集、存储、分析、并可视化全面的分析工具&#xff0c;简称 ELK&#xff08;Elasticsearch&#xff0c;Logstash&#xff0c;Kibana&#xff09;的缩写。 安装Elastic Stack 时&#xff0c;必须相关组件使用相同的版本&#xff0c;例如&#xff1…

区块链去中心化分布式_为什么渐进式去中心化是区块链的最大希望

区块链去中心化分布式by Arthur Camara通过亚瑟卡马拉(Arthur Camara) 为什么渐进式去中心化是区块链的最大希望 (Why Progressive Decentralization is blockchain’s best hope) 不变性是区块链的最大优势和最大障碍。 逐步分权可能是答案。 (Immutability is blockchain’s…

编译原理—语义分析(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问题总结

linux问题总结 编写后台进程的管理脚本&#xff0c;使用service deamon-name stop的时候&#xff0c;出现如下提示&#xff1a;/sbin/service: line 66: 23299 Terminated env -i LANG"$LANG" PATH"$PATH" TERM"$TERM" "${SERVICEDIR}/${SE…

linux vi行尾总是显示颜色,【转载】Linux 下使用 vi 没有颜色的解决办法

vi 是没有颜色的&#xff0c;vim 是有颜色的。我们可以通过 rpm -qa |grep vim 看看系统中是否安装了下面 3 个 rpm 包&#xff0c;如果有就是安装了 vim 。[rootBetty ~]# rpm -qa |grep vimvim-minimal-7.0.109-7.el5vim-enhanced-7.0.109-7.el5vim-common-7.0.109-7.el5如果…

时间序列分析 lstm_LSTM —时间序列分析

时间序列分析 lstmNeural networks can be a hard concept to wrap your head around. I think this is mostly due to the fact that they can be used for so many different things such as classification, identification or just simply regression.神经网络可能是一个难…

关于计算圆周率PI的经典程序

短短几行代码&#xff0c;却也可圈可点。如把变量s放在PI表达式中&#xff0c;还有正负值的处理&#xff0c;都堪称经典。尤其是处处考虑执行效率的思想令人敬佩。 /* pi/41-1/31/5-1/71/9-…… */ #include <stdio.h> int main(){ int s1; float pi0.,n1.,…

华为产品技术学习笔记之路由原理(一)

路由器&#xff1a;路由器是一种典型的网络连接设备&#xff0c;用来进行路由选择和报文转发。路由器与它直接相连的网络的跳数为0&#xff0c;通过一台路由器可达的网络的跳数为1.路由协议&#xff1a;路由器之间维护路由表的规则&#xff0c;用以发现路由&#xff0c;生成路由…

Linux网络配置:设置IP地址、网关DNS、主机名

查看网络信息 1、ifconfig eth0 2、ifconfig -a 3、ip add 设置主机名需改配置文件&#xff1a; /etc/hosts /etc/sysconfig/network vim /etc/sysconfig/network NETWORKINGyes NETWORKING_IPV6no HOSTNAMEwendyhost Linux配置网络 方法一&#xff1a; 1、使用setup命令进入如…

编译原理—小型(简化)高级语言分析器前端(Java)

实现一个一遍扫描的编译前端&#xff0c;将简化高级语言的部分语法成分&#xff08;含赋值语句、分支语句、循环语句等&#xff09;翻译成四元式&#xff08;或三地址代码&#xff09;&#xff0c;还要求有合理的语法出错报错和错误恢复功能。 测试样例 beginwhile a<b do…

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

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

dynamodb管理ttl_如何使用DynamoDB TTL和Lambda安排临时任务

dynamodb管理ttlby Yan Cui崔燕 如何使用DynamoDB TTL和Lambda安排临时任务 (How to schedule ad-hoc tasks with DynamoDB TTL and Lambda) CloudWatch Events let you easily create cron jobs with Lambda. However, it’s not designed for running lots of ad-hoc tasks,…

5g创业的构想_数据科学项目的五个具体构想

5g创业的构想Do you want to enter the data science world? Congratulations! That’s (still) the right choice.您想进入数据科学世界吗&#xff1f; 恭喜你&#xff01; 那(仍然)是正确的选择。 The market currently gets tougher. So, you must be mentally prepared f…

Microsoft Windows Phone 7 Toolkit Silverlight SDK XNA Game Studio 4.0 开发工具套件正式版下载...

Windows Phone 7开发工具套件包括Visual Studio 2010 Express for Windows Phone、Windows Phone模拟器、Expression Blend 4 for Windows Phone、XNA Game Studio 4.0和新增加的必应地图SDK。 英文版的光盘镜像&#xff1a;点击下载 文档中心&#xff1a;Windows Phone develo…

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

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

怎么汇报一周开发工作情况_如何在没有经验的情况下获得第一份开发人员工作

怎么汇报一周开发工作情况Whether you’ve done a coding bootcamp or taught yourself, getting your first developer job with only a few months of coding under your belt is hard.无论您是完成了编码训练营还是自学了&#xff0c;仅靠几个月的编码就很难拿到第一份开发人…

vue.js的认知

Vue.js&#xff08;读音 /vjuː/, 类似于 view&#xff09; 是一套构建用户界面的渐进式框架。 Vue 只关注视图层&#xff0c; 采用自底向上增量开发的设计。 Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。 Vue 学习起来非常简单&#xff0c;。转载于…