java递归下降分析_JAVA中的递归下降

java递归下降分析_JAVA中的递归下降publicclassParser{//ThesearethetokentypefinalintNONE=0;finalintDELIMITER=1;finalintVARIABLE=2;finalintNUMBER=3;//ThesearethetypeofsyntaxerrorsfinalintSYNTAX=0;final…

大家好,又见面了,我是你们的朋友全栈君。

public class Parser {

// These are the token type

final int NONE = 0;

final int DELIMITER = 1;

final int VARIABLE = 2;

final int NUMBER = 3;

// These are the type of syntax errors

final int SYNTAX = 0;

final int UNBALPARENS = 1;

final int NOEXP = 2;

final int DIVBYZERO = 3;

// These token indicates end-of-expression

final String EOF = “\0”;

private String exp;

private int expIdx;

private String token;

private int tokType;

public double evaluate(String expstr) throws ParserException {

double result;

exp = expstr;

expIdx = 0;

getToken();

// no expression present

if (token.equals(EOF))

handleErr(NOEXP);

result = evalExp2();

if (!token.equals(EOF)) {

handleErr(SYNTAX);

}

return result;

}

private double evalExp2() throws ParserException {

char op;

double result;

double partialResult;

result = evalExp3();

while ((op = token.charAt(0)) == ‘+’ || op == ‘-‘) {

getToken();

partialResult = evalExp3();

switch (op) {

case ‘-‘:

result = result – partialResult;

break;

case ‘+’:

result = result + partialResult;

break;

}

}

return result;

}

private double evalExp3() throws ParserException {

char op;

double result;

double partialResult;

result = evalExp4();

while ((op = token.charAt(0)) == ‘/’ || op == ‘*’ || op == ‘%’) {

getToken();

partialResult = evalExp4();

switch (op) {

case ‘*’:

result = result * partialResult;

break;

case ‘/’:

if (partialResult == 0.0)

handleErr(DIVBYZERO);

result = result / partialResult;

break;

case ‘%’:

if (partialResult == 0.0)

handleErr(DIVBYZERO);

result = result / partialResult;

break;

}

}

return result;

}

private double evalExp4() throws ParserException {

double result;

double partialResult;

double ex;

int t;

result = evalExp5();

if (token.equals(“^”)) {

getToken();

partialResult = evalExp4();

ex = result;

if (partialResult == 0.0) {

result = 1.0;

} else

for (t = (int) partialResult – 1; t > 0; t–)

result = result * ex;

}

return result;

}

private double evalExp5() throws ParserException {

double result;

String op;

op = “”;

if ((tokType == DELIMITER) && token.equals(“+”) || token.equals(“-“)) {

op = token;

getToken();

}

result = evalExp6();

if (op.equals(“-“))

result = -result;

return result;

}

private double evalExp6()throws ParserException{

double result;

if(token.equals(“(“)){

getToken();

result = evalExp2();

if(!token.equals(“)”))

handleErr(UNBALPARENS);

getToken();

}

else result = atom();

return result;

}

private double atom() throws ParserException {

double result = 0.0;

switch (tokType) {

case NUMBER:

try {

result = Double.parseDouble(token);

} catch (NumberFormatException exc) {

handleErr(SYNTAX);

}

getToken();

break;

default:

handleErr(SYNTAX);

break;

}

return result;

}

private void handleErr(int error) throws ParserException {

String[] err = { “Syntax error”, “Unbalanced parentheses”,

“No expression Present”, “Division by zero” };

throw new ParserException(err[error]);

}

//下面的函数就是获得独立元素的值,并且用tokType来保存类型

private void getToken() {

// obtain the next token

tokType = NONE;

token = “”;

if (expIdx == exp.length()) {

token = EOF;

return;

}

while (expIdx < exp.length()

&& Character.isWhitespace(exp.charAt(expIdx)))

++expIdx;

if (expIdx == exp.length()) {

token = EOF;

return;

}

if (isDelim(exp.charAt(expIdx))) {// is operator

token += exp.charAt(expIdx);

expIdx++;

tokType = DELIMITER;

} else if (Character.isLetter(exp.charAt(expIdx))) {

while (!isDelim(exp.charAt(expIdx))) {

token += exp.charAt(expIdx);

expIdx++;

if (expIdx >= exp.length())

break;

}

tokType = VARIABLE;

} else if (Character.isDigit(exp.charAt(expIdx))) {

while (!isDelim(exp.charAt(expIdx))) {

token += exp.charAt(expIdx);

expIdx++;

if (expIdx >= exp.length())

break;

}

tokType = NUMBER;

} else {

token = EOF;

return;

}

}

private boolean isDelim(char c) {

if ((“+-*/%^=()”.indexOf(c)) != -1)

return true;

return false;

}

}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/149323.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • navicat注册码怎么获得_navicat永久激活码最新

    navicat注册码怎么获得_navicat永久激活码最新产品适用:Navcat产品+中文版+64位注册机百度网盘链接:https://pan.baidu.com/s/1H49nNga9h0WHWKGWAGy18g提取码:ri5d1、cmd进入注册机目录执行命令navicat-patcher.exe”D:\ProgramFiles\PremiumSoft\NavicatPremium12″(navicate的目录)2、执行…

    2022年10月13日
    20
  • SQL注入-报错注入[通俗易懂]

    SQL注入-报错注入[通俗易懂]sql注入之报错注入的演示与介绍

    2022年9月29日
    1
  • 单例模式(Singleton)应用场景和优缺点

    单例模式(Singleton)应用场景和优缺点单例(Singleton)模式 也叫单态模式概述:单例(Singleton)模式要求一个类有且仅有一个实例,并且提供了一个全局的访问点。这就提出了一个问题:如何绕过常规的构造器,提供一种机制来保证一个类只有一个实例?客户程序在调用某一个类时,它是不会考虑这个类是否只能有一个实例等问题的,所以,这应该是类设计者的责任,而不是类使用者的责任。 从另一个角度来说,Singleton模式其实也是一…

    2022年6月13日
    35
  • idea如何创建yml文件

    idea如何创建yml文件1 File gt Settings2 Editor gt FileAndCodeT gt 中间选中 Files gt 点击 号 添加模板 gt 输入模板名字 Name YmlFile xml name 可以自定义 gt 后缀名 extension yml3 选中文件夹 gt New amp

    2025年6月13日
    2
  • DICOM影像中的窗宽窗位

    DICOM影像中的窗宽窗位1.为什么有窗宽窗位?医学图像领域的关键技术窗技术,是CT检查中用以观察不同密度的正常组织或病变的一种显示技术,包括窗宽(windowwidth)和窗位(windowlevel)。由于各种组织结构或病变具有不同的CT值,因此想要显示某一组织结构细节时,应该选择适合观察该组织或病变的窗宽和窗位,以获得最佳显示。2.窗宽窗宽是CT图像上显示的CT值范围,在此CT值范围内的组织和病变均

    2022年6月29日
    55
  • android之Activity.startManagingCursor方法详解

    在使用数据库操作查询数据后,如果是在Activity里面处理,那么很可能就会用到startManagingCursor()方法,在这里讲一下它的作用和使用注意事项.调用这个方法,就是将获得的Cursor对象交与Activity 来管理,这样Cursor对象的生命周期便能与当前的Activity自动同步,省去了自己管理Cursor。看下文档里的注释This method allows

    2022年3月10日
    41

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号