Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在Antlr 4中创建和解析if语句_Java_Antlr_Antlr4_Language Design - Fatal编程技术网

Java 如何在Antlr 4中创建和解析if语句

Java 如何在Antlr 4中创建和解析if语句,java,antlr,antlr4,language-design,Java,Antlr,Antlr4,Language Design,所以,我刚开始学习antlr4,我只是做了一个非常简单的编程语言。该语言可以创建变量(int、boolean和string)、更改它们的值并输出它们的值。然而,我正在尝试做一个if语句,但是经过多次尝试,它没有起作用。谷歌搜索也无济于事,因为其他大多数代码都太不相同,我自己无法理解和应用。我的大部分代码遵循本教程: 这是我的语法文件 grammar valhallap; program : 'begin' statement+ 'end'; ifState : ifDec 'STARTIF

所以,我刚开始学习antlr4,我只是做了一个非常简单的编程语言。该语言可以创建变量(int、boolean和string)、更改它们的值并输出它们的值。然而,我正在尝试做一个if语句,但是经过多次尝试,它没有起作用。谷歌搜索也无济于事,因为其他大多数代码都太不相同,我自己无法理解和应用。我的大部分代码遵循本教程:

这是我的语法文件

grammar valhallap;

program : 'begin' statement+ 'end';

ifState : ifDec 'STARTIF' statement+ 'ENDIF';



statement :  createINT|assign|addINT|printVar|createString|print|createBool|;




ifDec: 'if' (NUMBER|ID) EXPRESION (NUMBER|ID) 'then';
createINT : 'new' 'int' ID;
createBool: 'new' 'bool' ID;
createString : 'new' 'string' ID;
addINT : 'addINT' ID NUMBER;
assign : 'set' ID (STRING|BOOL|NUMBER);
print : 'output' 'say' STRING;
printVar : 'output' 'var' ID;





ID : [A-z]+;
NUMBER : [0-9]+ ;
STRING : ["] ( ~["\r\n\\] | '\\' ~[\r\n] )* ["] | ['] ( ~['\r\n\\] | '\\' ~[\r\n] )* ['];
BOOL : 'true' | 'false';
WS : [ \n\t]+ -> skip;
Comment: '**' ~( '\r' | '\n' )* -> skip;
STATEMENT : .;
EXPRESION:
     'MORETHAN'
     |'LESSTHAN'
     |'EQUALS'
     |'LESSEQUALS'
     |'MOREEQUALS';
最后是listener类

import com.power.valhallap.grammar.*;
import java.io.FileInputStream;
import java.io.IOException;

import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;

/**
 *
 * @author admin
 */

public class ValhallaListener extends valhallapBaseListener{

/**
 * @param args the command line arguments
 */
private Map<String, Object> variables;
public static boolean ifState = false;

public ValhallaListener()
{
    //init all the variables
    variables = new HashMap<>();
}


//if statements



@Override
public void exitAssign(valhallapParser.AssignContext ctx)
{
    String variable = ctx.ID().getText();


    if(variables.get(variable) instanceof String)
    {
        if(ctx.NUMBER() != null || ctx.BOOL() != null)
        {`enter code here`
            System.out.println("error expecting string");
        }
    }
    if(variables.get(variable) instanceof Boolean)
    {
        if(ctx.NUMBER() != null || ctx.STRING() != null)
        {
            System.out.println("error expecting boolean");
        }
    }
    if(variables.get(variable) instanceof Integer)
    {
        if(ctx.STRING() != null || ctx.BOOL() != null)
        {
            System.out.println("error expecting integer");
        }
    }

    if(ctx.STRING() != null)
    {
        if(variables.get(variable) instanceof String)
        {
           String finalString = ctx.STRING().getText();
           finalString = finalString.replace("\"", "");
           variables.put(variable, finalString);
        }

    }

    if(ctx.NUMBER() != null)
    {
        if(variables.get(variable) instanceof Integer)
        {
           variables.put(variable, Integer.parseInt(ctx.NUMBER().getText()));
        }

    }

    if(ctx.BOOL() != null)
    {
        if(variables.get(variable) instanceof Boolean)
        {
           boolean answer = Boolean.parseBoolean(ctx.BOOL().getText());

           variables.put(variable, answer);
        }

    }


}

@Override
public void exitCreateINT(valhallapParser.CreateINTContext ctx)
{
    //get's the variable name of int
    String variableName = ctx.ID().getText();

     if(!variables.containsKey(variableName))
    {
        //add the name to the hashmap with the init value of 0
        variables.put(variableName, 0);
    }
}



@Override
public void exitAddINT(valhallapParser.AddINTContext ctx)
{
    //get the var name
    String varName = ctx.ID().getText();

    //get the value
    int first = Integer.parseInt(variables.get(varName).toString());

    int addValue = Integer.parseInt(ctx.NUMBER().getText());

    int finalValue = first + addValue;

    //assign the new value

    variables.put(varName, finalValue);
}


 @Override
public void exitPrintVar(valhallapParser.PrintVarContext ctx)
{
    String varName = ctx.ID().getText();



    System.out.println(variables.get(varName));
}

@Override
public void exitPrint(valhallapParser.PrintContext ctx)
{
    String output = ctx.STRING().getText();
    output = output.replace("\"", "");
    System.out.println(output);
}

@Override
public void exitCreateString(valhallapParser.CreateStringContext ctx)
{
    String variableName = ctx.ID().getText();


    if(!variables.containsKey(variableName))
    {
        //add the name to the hashmap with the init value of null
        variables.put(variableName, "");
    }
}



@Override
public void exitCreateBool(valhallapParser.CreateBoolContext ctx)
{
    //get's the variable name of int
    String variableName = ctx.ID().getText();

     if(!variables.containsKey(variableName))
    {
        //add the name to the hashmap with the init value of false
        variables.put(variableName, false);
    }
}





public static void main(String[] args) {
   try {
    ANTLRInputStream input = new ANTLRInputStream(
        new FileInputStream(args[0]));    

    valhallapLexer lexer = new  valhallapLexer(input);
    valhallapParser parser = new valhallapParser(new CommonTokenStream(lexer));
    parser.addParseListener(new ValhallaListener());

    // Start parsing
    parser.program();


    if(ifState)
    {
        parser.ifState();
    }



    } catch (IOException e) {
        e.printStackTrace();
    }
}

我是antlr4的新手,有些概念对我来说是新的,如果有人能帮我的话,那就太好了,谢谢

ifState
在您的
语句中没有提到

另外,请记住,您定义了在
之后应该有“STARTIF”
——这不在示例输入中

另一个观察结果是,您的
语句
规则以
|结尾-这意味着它允许空语句。这在没有语句分隔符的语言中没有意义

编辑 正如@CoronA所指出的,问题在于首先在main中调用
程序
规则,然后调用
ifState
。这样做意味着您希望首先解析程序(以
begin
开始,以
end
结束),然后才指示解析器解析if语句。因此,当前代码将解析的输入必须类似于:

begin
    ...
end
if 5 MORETHAN 4 then
STARTIF
   ...
ENDIF

您可能想做的是使
ifState
成为另一种可能的语句类型,即将其添加到
语句
规则中,并从main仅调用
程序

“它不起作用”没有告诉我们任何信息。请阅读以下内容:因此,我的程序开始解析位于“begin”和“end”关键字之间的“statement”。因此,我尝试在then关键字之后调用语法文件中的“语句”,如果if语句返回true,则将执行该语句。但是,我无法通过if语句阻止解析器访问解析器。换句话说,解析器只是忽略if语句并解析所有内容。既然我在网上看到了许多不同的例子,我想肯定还有其他的方法,但我只需要对所有这些进行一些解释。最好一步一步地解决你的问题。你的问题不是听众。你的问题是理解解析。如果要在
begin…end
之间使用If语句,则应允许它作为语句(不要根据静态变量
ifState
对其进行明确解析。请将您的示例简化为您的主要问题。当您的第一个问题解决后,如果您再问另一个问题,没有人会介意。
ifState
在main中显式调用。调用
程序
ifState
i实际上没有意义。)n序列。@JiriTousek@CoronA,谢谢!让我更容易理解。但是,在尝试执行与您所说相同的操作之后,我在尝试跳过ifState中的语句时遇到了问题。例如,如果条件返回false,并且我希望跳过并继续执行程序,我将如何做?是否有特定的函数在这一点上,我可以跳过“语句”继续?你的意思是如果条件为false,内部可能是无效代码吗?这将很难做到。如果你是指普通语义(即,如果条件为false,代码必须有效,但不会执行),这是在侦听器中处理的,而不是在解析器中。@Jiri Tusek,是的,这就是我要说的,但我不确定如何在侦听器类中处理它,我尝试使用context.statement().remove(0),但它仍然不起作用。它要么给我一个错误,要么就是根本不起作用。
begin
    ...
end
if 5 MORETHAN 4 then
STARTIF
   ...
ENDIF