在构建编译器(使用ANTLR)时使用AST的目的是什么.有必要吗?什么是所谓的TreeParser,如何使用它?是否可以构建没有任何树的编译器?如果没有,是否有详细描述该主题的好教程?
我正在玩ANTLR,并希望创建一个这样的函数:
MOVE x y z pitch roll
Run Code Online (Sandbox Code Playgroud)
这会产生以下AST:
MOVE
|---x
|---y
|---z
|---pitch
|---roll
Run Code Online (Sandbox Code Playgroud)
到目前为止,我已经尝试过没有运气,并且我不断让AST将参数作为兄弟姐妹,而不是孩子.
代码到目前为止:
C#:
class Program
{
const string CRLF = "\r\n";
static void Main(string[] args)
{
string filename = "Script.txt";
var reader = new StreamReader(filename);
var input = new ANTLRReaderStream(reader);
var lexer = new ScorBotScriptLexer(input);
var tokens = new CommonTokenStream(lexer);
var parser = new ScorBotScriptParser(tokens);
var result = parser.program();
var tree = result.Tree as CommonTree;
Print(tree, "");
Console.Read();
}
static void Print(CommonTree tree, string indent)
{ …Run Code Online (Sandbox Code Playgroud) 我最近开始学习Antlr并下载AntlrWorks 1.4,据说包括Antlr 3.2.现在,3.2应该支持像' - >'这样的重写规则语法,但是我甚至无法得到基于Lexer或Parser规则构建的最简单的情况:
grammar TestRewrite;
ab : a b -> a;
a : A;
b : B;
A : 'a';
B : 'b';
Run Code Online (Sandbox Code Playgroud)
当我尝试编译它时,我收到错误:
[11:26:29] error(100): TestRewrite.g:3:13: syntax error: antlr: TestRewrite.g:3:13: unexpected token: a
Run Code Online (Sandbox Code Playgroud)
为什么是这样.结构看起来很简单:ab应该生成一棵树,其中只捕获一个节点.不是你怎么做的?我无法使用rooting('^')或忽略('!').我很困惑.
我正试图在ANTLR 3中充实wiki文本到HTML的翻译,但我一直陷入困境.
你知道一个我可以检查的工作实例吗?我尝试了MediaWiki ANTLR语法和Wiki Creole语法,但是我无法让它们在ANTLR 3中生成词法分析器和解析器.
以下是我尝试使用的两个语法的链接:
我无法获得这两个中的任何一个来生成我的Java Lexer和Parser.(我使用ANTLR3作为Eclipse插件).MediaWiki需要花费很长时间来构建,然后在某些时候抛出OutOfMemory异常.另一个有错误,我不知道如何调试.
编辑:好的,我有一个非常基本的语法:
grammar wikitext;
options {
//output = AST;
//ASTLabelType = CommonTree;
output = template;
language = Java;
}
document: line (NL line?)*;
line: horizontal_line | list | heading | paragraph;
/* horizontal line */
horizontal_line: HRLINE;
/* lists */
list: unordered_list | ordered_list;
unordered_list: '*'+ content;
ordered_list: '#'+ content;
/* Headings */
heading: heading1 | heading2 | heading3 | heading4 | heading5 | heading6;
heading1: H1 …Run Code Online (Sandbox Code Playgroud) 我想要可以包含空格的标识符.
grammar WhitespaceInSymbols;
premise : ( options {greedy=false;} : 'IF' ) id=ID{
System.out.println($id.text);
};
ID : ('a'..'z'|'A'..'Z')+ (' '('a'..'z'|'A'..'Z')+)*
;
WS : ' '+ {skip();}
;
Run Code Online (Sandbox Code Playgroud)
当我用"IF语句分析"测试时,我得到一个MissingTokenException和输出"IF语句分析".
我想,通过使用greedy = false,我可以告诉ANTLR退出'IF'并将其作为令牌.但相反,IF是ID的一部分.有没有办法实现我的目标?我已经尝试过greed = false-option的一些变体,但没有成功.
这是一个简单的规则:
NAME : 'name1' | 'name2' | 'name3';
Run Code Online (Sandbox Code Playgroud)
是否可以使用包含字符串的数组动态地为此类规则提供替代方案?
我为字符串变量声明编写了以下语法.字符串定义为单引号之间的任何内容,但必须有一种方法通过使用$ letter 转义将单引号添加到字符串值.
grammar test;
options
{
language = Java;
}
tokens
{
VAR = 'VAR';
END_VAR = 'END_VAR';
}
var_declaration: VAR string_type_declaration END_VAR EOF;
string_type_declaration: identifier ':=' string;
identifier: ID;
string: STRING_VALUE;
STRING_VALUE: '\'' ('$\''|.)* '\'';
ID: LETTER+;
WSFULL:(' ') {$channel=HIDDEN;};
fragment LETTER: (('a'..'z') | ('A'..'Z'));
Run Code Online (Sandbox Code Playgroud)
如果您尝试为var_declaration规则运行此代码,则此语法不起作用:
VAR A :='$12.2' END_VAR
Run Code Online (Sandbox Code Playgroud)
我得到MismatchedTokenException.
但是这个代码适用于string_type_declaration规则:
A :='$12.2'
Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个软件,该软件应仅使用以下功能执行基本编程语言的指令:
它应该一次一步地显示"减少"或"简化"的代码,并让我展示一个示例输出的示例:
迭代1:
a=3;
b=2;
c=true;
if(c && (a < 3 * (5 -2) ) || b >= 3 * (5 -2))){
System.out.println("going through if");
}else{
System.out.println("going through else");
}
Run Code Online (Sandbox Code Playgroud)
迭代2:
if(true && (a < 3 * (5 -2) ) || b >= 3 * (5 -2))){
System.out.println("going through if");
}else{
System.out.println("going through else");
}
Run Code Online (Sandbox Code Playgroud)
迭代3:
if(true && (3 < 3 * (5 -2) ) || 2 >= 3 * (5 -2))){
System.out.println("going through if");
}else{
System.out.println("going …Run Code Online (Sandbox Code Playgroud) 当我尝试生成监听器/访问者...对于我的语法我收到以下错误:ANTLR无法生成从4.5版开始的Javascript代码
有谁知道如何解决它?我仍然可以生成C#和Java代码.
(几天前我和ANTLR开始了我的语言冒险.我对语言理论和编译器构造的了解非常有限.如果这不是一个有效的问题,请原谅.)
ANTLR是一个解析器生成器,特别是一个ALL(*)解析器.根据这里,解析器是:
编译器的一部分,试图使语法理解源代码.
AFAIK编译器应由5个阶段组成:
所以ANTLR似乎只覆盖了1和2.
因此,如果我想为教育目的语言编写一个编译器,该语言目标是JVM上的Java字节代码.我可以在第3-5阶段使用哪些其他工具?
为什么ANTLR只覆盖1和2?我猜4和5被跳过,因为它们对目标平台来说太具体了.但为什么3被ANTLR跳过?
antlr ×10
antlr3 ×4
antlr4 ×2
antlrworks ×2
javascript ×2
creole ×1
grammar ×1
identifier ×1
java ×1
ll-grammar ×1
mediawiki ×1
parsing ×1
whitespace ×1
wikitext ×1