如何实现一个字符串数据容器并使用它添加两个带有Kotlin和Antlr的字符串

如何实现一个字符串数据容器并使用它添加两个带有Kotlin和Antlr的字符串,kotlin,parsing,compiler-construction,antlr,Kotlin,Parsing,Compiler Construction,Antlr,我正在尝试使用Kotlin和Antlr来创建自己的语言解析器。我试图为字符串数据实现一个数据容器,并让代码执行 要执行的代码: val program = """ x = "Hello"; y = "World"; // Expect "Hello World" print(x ++ y); """ 到目前为止,我的Kotlin后端是: package backend im

我正在尝试使用Kotlin和Antlr来创建自己的语言解析器。我试图为字符串数据实现一个数据容器,并让代码执行

要执行的代码:

val program = """
x = "Hello";
y = "World";

// Expect "Hello World"
print(x ++ y);
"""
到目前为止,我的Kotlin后端是:

package backend
import org.antlr.v4.runtime.*
import mygrammar.*

abstract class Data

data class StringData(val value: String) : Data()
data class IntData(val value: Int): Data()

class Context: HashMap<String, Data>()

abstract class Expr {
    abstract fun eval(scope: Context): Data
}


class Compiler: PLBaseVisitor<Expr>() {
}

我一直在尝试搜索接下来的步骤,但无论我搜索什么,似乎总是会给出如何编译Kotlin代码的结果,而不是如何使用Kotlin编译您自己的代码。

在拥有ANTLR语法和执行代码之间有相当多的步骤

下一步就是使用ANTLR为解析器生成源代码,以识别与语法匹配的源代码。由于Kotlin在Java互操作方面非常出色,因此您可以为语法生成并编译Java目标。(如果你想坚持使用Kotlin,我看到这里有人支持它。(我自己没有使用过它,但我知道Strumenta社区,所以我希望它会很好。(看起来他们的介绍很好)

编译生成的解析器后,应该能够找到在源代码上调用解析器的示例代码(
program
)。这将为您提供一个ParseTree。ANTLR以侦听器和/或访问者的形式提供方便的类,使您能够轻松处理生成的解析树。此时,ANTLR为您提供了它的值。ANTLR是一个工具,用于为解析器生成源代码以识别您的输入。ParseTree是该解析的结果。从这里开始,由您决定如何解释解析树并执行逻辑

如果您的语言没有变得太复杂,并且对性能不是特别敏感,那么您可以通过逻辑访问执行其中表示的逻辑的树(保留一个值字典,解释和执行ParseTree中的操作,等等)

您的问题表明,您可能希望ANTLR能够编译和执行您的逻辑。事实并非如此。我所概述的是未来的步骤,您可以选择多种方式来执行逻辑

如果您需要ANTLR的介绍,这本很不错:


这个页面链接到更多的

,您需要做的一件事是将
++
操作符添加到语法中(假设您希望以这种方式拼写字符串连接操作符)。除此之外,请尝试将运行时和编译分开。在最基本的编译器体系结构中,程序文本被转换为AST(其中大部分由Antlr完成),然后AST被转换成一个数据结构,它表示程序文本中包含的执行序列。这可能是一个实际机器指令的向量,或一个虚拟机指令的向量,甚至是简单的AST本身……这个东西——对象文件——必须在某种运行时环境中执行。这就是这是字符串容器的所在地。我认为您离这还有几项任务要做。
grammar PL;

@header {
package mygrammar;
}

program     : statement* EOF
        ;

statement   : assignment ';'    # assignmentStatement
        | expr ';'      # exprStatement
        ;

assignment  : 'let' ID '=' expr
        ;

expr        : x=expr '+' y=expr # addExpr
        | x=expr '-' y=expr # subExpr
        | x=expr '*' y=expr # mulExpr
        | x=expr '/' y=expr # divExpr
        | '(' expr ')'      # parenExpr
        | value         # valueExpr
        ;

value       : NUMERIC       # numericValue
        | STRING        # stringValue
        | ID            # idValue
        ;


NUMERIC     : ('0' .. '9')+ ('.' ('0' .. '9')*)?
        ;

STRING      : '"' ( '\\"' | ~'"' )* '"'
        ;

ID      : ('a' .. 'z' | 'A' .. 'Z' | '_') ('a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_')*
        ;

COMMENT     : '/*' .*? '*/' -> skip
        ;

WHITESPACE  : (' ' | '\t' | '\r' | '\n')+ -> skip
        ;