我无法弄清楚 antlr3 API,因此我可以在一些 javascript 代码中生成和使用解析树。当我使用antlrWorks(他们的IDE)打开语法文件时,解释器能够向我显示解析树,而且它甚至是正确的。
我在追踪如何使用 antlr3 运行时在我的代码中获取此解析树的资源时遇到了很多困难。我一直在弄乱运行时和解析器文件中的各种函数,但无济于事:
var input = "(PR=5000)",
cstream = new org.antlr.runtime.ANTLRStringStream(input),
lexer = new TLexer(cstream),
tstream = new org.antlr.runtime.CommonTokenStream(lexer),
parser = new TParser(tstream);
var tree = parser.query().tree;
var nodeStream = new org.antlr.runtime.tree.CommonTreeNodeStream(tree);
nodeStream.setTokenStream(tstream);
parseTree = new org.antlr.runtime.tree.TreeParser(nodeStream);
因为antlrWorks可以在没有我自己的任何树语法的情况下显示解析树,并且因为我已经读到antlr自动从语法生成解析树文件中,我假设我可以使用一些我可能不知道的运行时函数来访问这个基本的解析树。我的这个想法正确吗?
I'm having trouble figuring out the antlr3 API so I can generate and use a parse tree in some javascript code. When I open the grammar file using antlrWorks (their IDE), the interpreter is able to show me the parse tree, and it's even correct.
I'm having a lot of difficulties tracking down resources on how to get this parse tree in my code using the antlr3 runtime. I've been messing around with the various functions in the runtime and Parser files but to no avail:
var input = "(PR=5000)",
cstream = new org.antlr.runtime.ANTLRStringStream(input),
lexer = new TLexer(cstream),
tstream = new org.antlr.runtime.CommonTokenStream(lexer),
parser = new TParser(tstream);
var tree = parser.query().tree;
var nodeStream = new org.antlr.runtime.tree.CommonTreeNodeStream(tree);
nodeStream.setTokenStream(tstream);
parseTree = new org.antlr.runtime.tree.TreeParser(nodeStream);
Since antlrWorks can display the parse tree without any tree grammar from myself, and since I have read that antlr automatically generates a parse tree from the grammar file, I'm assuming that I can access this basic parse tree with some runtime functions that I am probably not aware of. Am I correct in this thinking?
发布评论
评论(1)
不,那是不正确的。 ANTLR 创建扁平的一维标记流。
ANTLRWorks 在解释某些源代码时会动态创建自己的解析树。您无权访问该树(无法使用 Javascript,甚至无法使用 Java)。您必须定义您认为应该是(子)树的根的标记和/或定义需要从 AST 中删除的标记。查看以下问答,了解如何创建正确的 AST:如何输出使用 ANTLR 构建的 AST?
编辑
由于目前还没有合适的 JavaScript 演示,这里有一个快速演示。
以下语法使用以下运算符解析布尔表达式:
,其中
not
具有最高优先级。当然有
true
和false
,并且可以使用括号对表达式进行分组。文件:Exp.g
上面的语法生成一个 AST,可以将其提供给下面的树遍历器:
文件:ExpWalker.g
(对
{ ... }
中混乱的 JavaScript 代码表示歉意:我对 JavaScript 的经验很少!)现在下载 ANTLR 3.3(没有早期版本!)和 JavaScript 运行时文件:
重命名
antlr-3.3-complete.jar
到antlr-3.3.jar
并解压antlr-javascript-runtime-3.1.zip
并将所有文件存储在与您的Exp.g
和ExpWalker.g
文件位于同一文件夹。现在生成词法分析器、解析器和树遍历器:
并使用以下 html 文件对其进行测试:
看看结果:
No, that is incorrect. ANTLR creates a flat, 1 dimensional stream of tokens.
ANTLRWorks creates its own parse tree on the fly when interpreting some source. You have no access to this tree (not with Javascript or even with Java). You will have to define the tokens that you think should be the roots of your (sub) trees and/or define the tokens that need to be removed from your AST. Checkout the following Q&A that explains how to create a proper AST: How to output the AST built using ANTLR?
EDIT
Since there's no proper JavaScript demo on SO yet, here's a quick demo.
The following grammar parses boolean expression with the following operators:
where
not
has the highest precedence.Of course there are
true
andfalse
, and the expressions can be grouped using parenthesis.file: Exp.g
The grammar above produces an AST which can be fed to the tree-walker below:
file: ExpWalker.g
(apologies for the messy JavaScript code inside
{ ... }
: I have very little experience with JavaScript!)Now download ANTLR 3.3 (no earlier version!) and the JavaScript runtime files:
Rename
antlr-3.3-complete.jar
toantlr-3.3.jar
and unzipantlr-javascript-runtime-3.1.zip
and store all files in the same folder as yourExp.g
andExpWalker.g
files.Now generate the lexer, parser and tree-walker:
And test it all with the following html file:
And behold the result: