gpt4 book ai didi

python - 两个基本的 ANTLR 问题

转载 作者:太空狗 更新时间:2023-10-30 00:41:45 25 4
gpt4 key购买 nike

我正在尝试使用 ANTLR 来采用简单的语法并生成汇编输出。我在 ANTLR 中选择的语言是 Python。

许多教程看起来非常复杂,或者对与我无关的事情进行了详细说明;我真的只需要一些非常简单的功能。所以我有两个问题:

将一个规则的值“返回”到另一个规则。

假设我有这样的规则:

赋值:name=IDENTIFIER ASSIGNMENT表达式;

当这条规则被识别时,我可以在 {} 中运行 Python 代码,并且我可以通过执行以下操作将 args 传递给 Python 代码以供表达:

赋值:name=IDENTIFIER ASSIGNMENT 表达式[variablesList];

然后

表达式[变量列表]: blah blah

但是如何将值“返回”到我的原始规则?例如。我如何计算表达式的值,然后将其发送回我的赋值规则以在 Python 中使用?

如何写出我的目标语言代码?

所以我有一些 Python 在规则被识别时运行,然后我计算我希望该语句生成的程序集。但是我怎么说“将这串汇编指令写到我的目标文件中”呢?

任何与此类内容(属性语法、编译为 AST 以外的内容等)相关的优秀教程也会有所帮助。如果我的问题没有太大意义,请让我澄清;我很难全神贯注于 ANTLR。

最佳答案



将值从一个规则返回到另一个规则

假设您要解析简单的表达式并在运行时提供可在这些表达式中使用的变量映射。一个简单的语法,包括自定义 Python 代码、规则中的 returns 语句以及语法入口点的参数 vars 可能如下所示:

grammar T;

options {
language=Python;
}

@members {
variables = {}
}

parse_with [vars] returns [value]
@init{self.variables = vars}
: expression EOF {value = $expression.value}
;

expression returns [value]
: addition {value = $addition.value}
;

addition returns [value]
: e1=multiplication {value = $e1.value}
( '+' e2=multiplication {value = value + $e2.value}
| '-' e2=multiplication {value = value - $e2.value}
)*
;

multiplication returns [value]
: e1=unary {value = $e1.value}
( '*' e2=unary {value = value * $e2.value}
| '/' e2=unary {value = value / $e2.value}
)*
;

unary returns [value]
: '-' atom {value = -1 * $atom.value}
| atom {value = $atom.value}
;

atom returns [value]
: Number {value = float($Number.text)}
| ID {value = self.variables[$ID.text]}
| '(' expression ')' {value = $expression.value}
;

Number : '0'..'9'+ ('.' '0'..'9'+)?;
ID : ('a'..'z' | 'A'..'Z')+;
Space : ' ' {$channel=HIDDEN};

如果您现在使用 ANTLR v3.1.3(没有更高版本!)生成解析器:

java -cp antlr-3.1.3.jar org.antlr.Tool T.g

and run the script:

#!/usr/bin/env python
import antlr3
from antlr3 import *
from TLexer import *
from TParser import *

input = 'a + (1.0 + 2) * 3'
lexer = TLexer(antlr3.ANTLRStringStream(input))
parser = TParser(antlr3.CommonTokenStream(lexer))
print '{0} = {1}'.format(input, parser.parse_with({'a':42}))

您将看到正在打印以下输出:

a + (1.0 + 2) * 3 = 51.0

Note that you can define more than a single "return" type:

parse
: foo {print 'a={0} b={1} c={2}'.format($foo.a, $foo.b, $foo.c)}
;

foo returns [a, b, c]
: A B C {a=$A.text; b=$B.text; b=$C.text}
;



如何写出目标语言代码

最简单的方法是简单地将 print 语句放入自定义代码块并将输出通过管道传输到文件:

parse_with [vars]
@init{self.variables = vars}
: expression EOF {print 'OUT:', $expression.value}
;

然后像这样运行脚本:

./run.py > out.txt

这将创建一个“out.txt”文件,其中包含:OUT: 51.0。如果你的语法不是那么大,你可能会逃脱这个。但是,这可能会变得有点困惑,在这种情况下,您可以将解析器的输出设置为 template:

options {
output=template;
language=Python;
}

并通过您自己定义的模板发出自定义代码。

参见:

关于python - 两个基本的 ANTLR 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7565974/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com