一个简单的java递归下降语法分析器例子

import parser.Parser;
import parser.RecursiveDescentParser;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        // 关键词
        List<String> keyList = new ArrayList<>(Arrays.asList("int","String"));
        // 关键词数
        List<Integer> keyNum = new ArrayList<>(Arrays.asList(1,2));
        // 运算符和界符
        List<String> symbolList = new ArrayList<>(Arrays.asList("+","-"));
        // 运算符和界符的数
        List<Integer> symbolNum = new ArrayList<>(Arrays.asList(10,11));

        // 从文件取出的字符
        String letter;
        // 将字符转为单词
        String words;

        String test ="int main() { int i,j; String a,b;} 123 ccd";

//        Parser parser = new Parser();
//        parser.analysis(test,keyList);

        // 测试语法分析,递归下降分析
        String input = "5+10*2";
        RecursiveDescentParser recursiveDescentParser = new RecursiveDescentParser(input);
        int rs = recursiveDescentParser.parseExpression();
        System.out.println("Result: " + rs);
    }
}

package parser;

/**
 * 递归下降解析
 * 文法规则:
 * expression = term + expression|term
 * term = = factor * term|factor
 * factor = (expression)|number
 * number = [0-9]+
 *
 */
public class RecursiveDescentParser {
    private String input;
    private int position;
    public RecursiveDescentParser(String input){
        this.input = input;
        this.position = 0;
    }

    public int parseExpression(){
        int term = parseTerm();
        if (position < input.length() && Character.toString(input.charAt(position)).equals("+")) {
            position++;
            int expression =parseExpression();
            return term+expression;
        }
        return term;
    }

    public int parseTerm(){
        int factor = parsefactor();
        if (position < input.length() && Character.toString(input.charAt(position)).equals("*")) {
            position++;
            int term =parseTerm();
            return factor*term;
        }
        return factor;
    }

    public int parsefactor(){
        if (position < input.length() && Character.toString(input.charAt(position)).equals("(")){
            position++;
            int expression =parseExpression();
            if (position < input.length() && Character.toString(input.charAt(position)).equals(")")){
                position++;
                return expression;
            }
        }else{
            StringBuilder number = new StringBuilder();
            while (position < input.length() && Character.isDigit(input.charAt(position))){
                number.append(input.charAt(position));
                position++;

                System.out.println("number: " + number);
            }
            return Integer.parseInt(number.toString());
        }

        throw new RuntimeException("错误输入");
    }
}

测试结果

如果看不懂,可以先学习一下上下文无关文法、产生式、终结符、非终结符的概念。

上下文无关文法、产生式、终结符、非终结符-CSDN博客

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

npm i 依赖下载失败

git config --global url."https://".insteadOf git://解决npm install 报错 npm ERR code 128 Permission denied_please make sure you have the correct access right-CSDN博客

Apache Answer 开源问答社区安装体验

Answer 是由 SegmentFault 思否团队打造的一款问答平台软件,后端使用 Go 语言编写,于2022年10月24日(程序员节)正式开源。你可以免费使用 Answer 高效地搭建一个问答社区,并用于产品技术问答、客户支持、用户交流等场景。 2023年10月9日,Answer 顺利通过投票,以全票通过…

【Python】函数基础(纯干货版)

目录 什么是函数 函数定义 函数的文档说明 局部变量和全局变量 综合案例&#xff1a;模拟实现ATM界面 什么是函数 函数是组织好的&#xff0c;可重复使用的&#xff0c;用于实现特定功能的代码段&#xff0c;将功能封装在函数内&#xff0c;可供随时随地重复利用&#xff…

BTP连接cloud connector中配置的SAP

登录地址 登录之后可以看到我们已经配置成功的后端系统SAP。 从cloud connector中获取location ID ,然后在BTP中配置Destination 选择目标标签页&#xff0c;点击‘新建目标’&#xff0c;如下图&#xff1a; 新建连接 暂时不知道错误原因 创建目标-HTTP  新建目标&…

(五)STM32F407 cubemx定时器PWM驱动舵机

这篇文章主要是个人的学习经验&#xff0c;想分享出来供大家提供思路&#xff0c;如果其中有不足之处请批评指正哈。 废话不多说直接开始主题&#xff0c;本人是基于STM32F407VET6芯片&#xff0c;但是意在你看懂这篇文章后&#xff0c;不管是F1,F4,H7等一系列系统定时器PWM配置…

动态IP与静态IP的区别,你选对了吗?

在互联网世界中&#xff0c;IP地址是每台设备在网络上的唯一标识。这些地址可以是动态的&#xff0c;也可以是静态的。对于非专业人士来说&#xff0c;理解这两者之间的区别可能会有些困难。本文旨在深入探讨动态IP和静态IP的主要差异&#xff0c;帮助读者根据自己的需求做出明…

华为sr-mpls policy配置案例

SR&#xff0d;MPLS POLICY在ensp上面做不了&#xff0c;这是官方上的配置

CSS基础之伪元素选择器(如果想知道CSS的伪元素选择器知识点,那么只看这一篇就足够了!)

前言&#xff1a;我们已经知道了在CSS中&#xff0c;选择器有基本选择器、复合选择器、伪类选择器、那么选择器学习完了吗&#xff1f;显然是没有的&#xff0c;这篇文章讲解最后一种选择器——伪元素选择器。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解更多内容可以访问我…

爱上JDK源码阅读-Integer

知识点 自动装箱和拆箱IntegerCache机制toString()实现算法优化 从一道面试题开始 Integer a 100; int b 100; if (a b) {System.out.println("a b"); } else {System.out.println("a ! b"); }聪明的你应该马上可以知道答案了&#xff0c;输出就是 …

【SQL】DISTINCT GROUP BY

找到所有办公室里的所有角色&#xff08;包含没有雇员的&#xff09;,并做唯一输出(DISTINCT) 用DISTINCT : SELECT DISTINCT B.Building_name,E.Role FROM Buildings B LEFT JOIN Employees EON B.Building_name E.Building需要找到的结果&#xff1a;所有办公室名字&#…

C# 图像旋转一定角度后,对应坐标怎么计算?

原理分析 要计算图像内坐标在旋转一定角度后的新坐标&#xff0c;可以使用二维空间中的点旋转公式。假设图像的中心点&#xff08;即旋转中心&#xff09;为 (Cx, Cy)&#xff0c;通常对于正方形图像而言&#xff0c;中心点坐标为 (Width / 2, Height / 2)。给定原坐标点 (X, …

10:HAL---高级定时器

前言&#xff1a; 高级定时器具有通用定时器的所有功能&#xff0c;我们在这里面只说它不一样的地方。&#xff08;通用定时器不具备的功能&#xff09; 一&#xff1a;高级定时器 1&#xff1a;介绍 2&#xff1a;重复计数器 在我们普通的定时器中当CNTCCR时直接发生溢出。然…

阿里二面凉了,难蹦。。。

分享一位同学阿里巴巴的后端面经&#xff0c;共有 2 面&#xff0c;第一面很顺利过了&#xff0c;可惜挂在第二面。 这两面的知识点范围&#xff0c;我帮大家罗列一下&#xff1a; 网络&#xff1a;TCP、HTTP mysql&#xff1a;索引应用、索引结构、隔离级别、最左匹配 redis…

图小灵的多线程

进程 简而言之,一个运行的程序就叫作进程 管理进程,要先将进程使用类/结构体,表示各个属性 为了后续增删改查,需要将进程通过数据结构串联起来 系统中有一个结构体专门用来表示进程的属性,叫作PCB(进程控制块) 一个进程使用一个或者多个PCB来表示 系统会使用类似于双向链…

pycharm-git 配置(1)

1.安装git2.pycharm 中配置git 插件 弹出Git版本号&#xff0c;即配置成功。3.创建本地仓库 VCS->VCS operations->create repository->设置本地目录 左下角可以看到git本地仓库git可以看到push,commit。 4.配置远方仓库&#xff0c;此时确保git上是有这个项目…

在开发板上运行spidev_test报错:“./spidev_test: line 2: h: not found”

问题 今天交叉编译spidev_test后&#xff0c;放到开发板上运行报错&#xff1a;“./spidev_test: line 2: h: not found” 原因 编译方式不同&#xff0c;生成的是64为程序&#xff0c;应该生成32位的程序。 解决办法&#xff1a; 修改为直接用命令编译&#xff0c;生成…

酷开科技抓住“客厅经济”发展的机遇,不断对酷开系统升级赋能

酷开科技抓住“客厅经济”发展的机遇&#xff0c;不断对酷开系统升级赋能&#xff0c;打造新的生活场景&#xff0c;满足消费者的不同生活需求&#xff0c;酷开科技的产品和服务让消费者能够在家庭空间中享受到更加智能、便捷和温馨的时光。同样凭借更加包容、开放的生态体验&a…

贪吃蛇项目实战——学习详解

前言:贪吃蛇是一个经典的游戏&#xff0c; 本节将使用c语言实现一个简易的的贪吃蛇小游戏。 本节内容适合已经学完c语言还有数据结构链表的友友们。 我们要实现的贪吃蛇是在控制台进行游戏的。 它运行起来是这样的&#xff1a; 贪吃蛇 那么&#xff0c; 为了实现这个小游戏。 我…

添加Redis缓存

1.缓存查询 在service层Impl文件中&#xff0c;进行查询时优先向Redis中查数据&#xff0c;查到就查到了&#xff0c;没有查到向mysql数据库中查&#xff0c;查到之后不先返回&#xff0c;而是先将数据存到数据库&#xff08;缓存&#xff09;,在再返回数据。 1.1 代码实现(缓…

鸿蒙端云一体化开发--调用云函数--适合小白体制

如何实现在端侧调用云函数&#xff1f; 观看前&#xff0c;友情提示&#xff1a; 不知道《如何一键创建端云一体化模板》的小白同学&#xff0c;请看&#xff1a; 鸿蒙端云一体化开发--开发云函数--适合小白体制-CSDN博客 实现方法&#xff1a; 第一步&#xff1a;添加依赖 …