我必须定义一个文件的语法,如下所示.
//示例文件
NameCount = 4
Name = a
Name = b
Name = c
Name = d
//文件结尾
现在我可以为NameCount和Name定义标记.但我必须定义文件结构,包括令牌名称的有效实例数,这是NameCount之后的值.我将值解析并转换为整数并存储在语法的全局范围内的变量中(例如在变量nc中).
如何在语法中定义Name应该重复nc次?
grammar AdifyMapReducePredicate;
PREDICATE
: PREDICATE_BRANCH
| EXPRESSION
;
PREDICATE_BRANCH
: '(' PREDICATE (('&&' PREDICATE)+ | ('||' PREDICATE)+) ')'
;
EXPRESSION
: ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
;
Run Code Online (Sandbox Code Playgroud)
试图在ANTLRWorks 1.4中解释这一点,并收到以下错误:
[12:18:21] error(211): <notsaved>:1:8: [fatal] rule Tokens has non-LL(*) decision due to recursive rule invocations reachable from alts 1,2. Resolve by left-factoring or using syntactic predicates or using backtrack=true option.
[12:18:21] Interpreting...
Run Code Online (Sandbox Code Playgroud)
当我解释时,我试图解释一个预测,我的测试用例是(A || B)
我错过了什么?
我最近开始使用 ANTLR。我目前正试图编码与表达语法+,-,*并array[index]和几个结构。
这是所需的语法:
Exp -> Exp (+ | - | * | < | &&) Exp
| Exp [ Exp ]
| -Exp
| ( Exp )
| Exp.length
| true
| false
| Id
| this
| ! Exp
Run Code Online (Sandbox Code Playgroud)
我首先将其重构为AndExp, SumExp,ProdExp等以解决优先级问题。大致是这样的:
Exp -> AndExp
AndExp -> CmpExp (&& CmpExp)*
CmpExp -> SumExp (< SumExp)*
SumExp -> ProdExp ((+|-) ProdExp)*
ProdExp -> UnaryExp (Times UnaryExp)*
UnaryExp -> …Run Code Online (Sandbox Code Playgroud) 我正在尝试分析 Java 代码结构。
所以,我通过使用 ANTLRv3 和 java 语法代码生成了一个 Java 解析器和词法分析器......
但我不知道如何使用生成的解析器和词法分析器生成上下文流图。
我试图通过教程页面学习如何做到这一点,但教程页面已经消失了。
你能给我一个如何做到这一点的方法吗?或教程页面?
谢谢你。
我在java中使用带有antlr的Lua.g语法生成了一个Lua Parser.
我希望解析的我的lua代码基本上是这样的
function uniqueid_some_event (e)
if (e:HasString("string1")) then
-- do something
end
if (e:HasString("string2")) then
-- do something
end
end
Run Code Online (Sandbox Code Playgroud)
我在不同的文件中有数百个这些事件用于特定的actor绑定.
现在我想解析这些文件并收集每个检查条件 - 在上面的例子中 - 我想提取"string1"和"string2"作为事件触发器.(更确切地说,我想创建一个只显示每个文件的触发器的报告)
我收集我需要以某种方式修改Lua.g以在那里添加我自己的逻辑,但我失去了因为我没有找到任何关于此的文档 - 我看了LuaEclise基本上做了一些事情,但它也不适用于我.
那么 - 是否可以向生成的LuaParser添加某种w3c DOM返回值?或者像getFunctions()这样的东西返回找到的所有函数,并在每个函数getHasStringStatements()中返回条件?
TL; DR:
我的计算器语法依赖于递归下降到彼此内部嵌套括号组,但是太多嵌套的parens(大约20个)会导致堆栈溢出.我怎样才能解决这个问题?有没有办法让问题更平坦?
长表:
不久之前 - 我的脑袋深深陷入了小规模的嵌入式系统 - 没有半脑的人会遇到堆栈溢出.现在因为更抽象的任务而感到谦卑,我来这里寻求建议.
激励项目是Android的计算器.目前的计算器在很多方面都显得不够,但我今天没带上我的肥皂盒,所以我只是直接遇到我遇到的问题:堆栈溢出!
具体来说,当用户创建太多嵌套括号组时,包括函数等.这是因为我的计算器依赖于ANTLR语法,这意味着它使用递归下降.方便地,这允许它通过PEMDAS连续运行,允许容易地计算嵌套函数和括号.但!我发现 - 根据电话 - 按下parens按钮20次左右会导致崩溃,这是由于调用堆栈产生的堆栈溢出导致大约100个函数调用深度,这是递归下降方法的自然结果.
我知道,flat比嵌套更好,但它下降的4个级别(函数)是完全必要的,而其他几个级别使我的生活在对数上变得更容易.即使删除这些级别也无法解决问题:用户仍然可以在几分钟内导致系统崩溃.有一个"太多的parens!" 错误信息是坏的(这是其他计算器之一会做的事情).另外,我使用AST输出来格式化输入字符串以使其非常类似,因此预先计算parens组会使整个系统有点过于复杂.
所以,问题:
即使问这个问题似乎很愚蠢,但是:有没有办法在ANTLR中实现一个语法,它可以解析和解释复杂和深度嵌套的表达式而不会爆炸调用堆栈?
语法:
grammar doubleCalc;
options {
language = Java;
output = AST;
// k=2;
}
// Calculation function.
prog returns [double value]
: e=addsub EOF {$value = $e.value;}
;
addsub returns [double value]
: e=muldiv {$value = $e.value;}
( PLUS^ e=muldiv {$value += $e.value;}
| MINUS^ e=muldiv {$value -= $e.value;}
)*
;
muldiv returns [double value]
: e=power {$value = …Run Code Online (Sandbox Code Playgroud) 我正在阅读"最终的ANTLR4参考"一书,并决定在他们的计算器语法中添加几个关键字以帮助清除记忆.构建语法并编译生成的java代码可以正常工作,但是当我执行访问者代码时,我得到了错误:"line 6:0 extraneous input '$rem' expecting {<EOF>, '(', ID, INT, NEWLINE}"对于'$clearmem'第8行:0也是如此.
这是我的语法文件:
grammar LabeledExpr;
//Parser rules=================================
prog: kword+
| stat+
;
stat: expr endl # printExpr
| ID '=' expr endl # assign
| NEWLINE # blank
;
expr: expr op=('*'|'/') expr # MulDiv
| expr op=('+'|'-') expr # AddSub
| INT # int
| ID # id
| '(' expr ')' # parens
;
kword: '$clearmem' endl #clearMem
| '$rem' ID endl #remVar
;
endl: …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 ANTLR4 将数学公式解析为 LaTeX 的子集。例如它应该解析(a+4)/(b*10)为\frac{a+4}{b\cdot 10}.
我的简单语法创建了一个这样的树:

现在我正在尝试实现解析树侦听器,以在遍历树时以某种方式构造 LaTeX 字符串。在这里,我失败了,因为构造一个像\frac{}{}它必须递归构建的字符串。然而,解析树遍历器一个接一个地访问树节点(据我所知,以广度优先的方式)。
我已经阅读了可能是我需要的解析树访问者。但是我无法找到一些如何应用这些访问者的示例。
您能否举例说明在这种特殊情况下如何使用解析树侦听器/访问器?您认为我首先将 ANTLR 用于解析器的方法有意义吗?
我试图解析以下内容:
SELECT name-of-key[random text]
Run Code Online (Sandbox Code Playgroud)
这是我想要构建的更大语法的一部分.为了清楚起见,我把它留下了.
我想出了以下规则:
select : 'select' NAME '[' anything ']'
;
anything : (ANYTHING | NAME)+
;
NAME : ('a'..'z' | 'A'..'Z' | '0'..'9' | '-' | '_')+
;
ANYTHING : (~(']' | '['))+
;
WHITESPACE : ('\t' | ' ' | '\r' | '\n')+ -> skip
;
Run Code Online (Sandbox Code Playgroud)
这似乎不起作用.例如,输入SELECT a[hello world!]提供以下错误:
line 1:0 mismatched input 'SELECT a' expecting 'SELECT'
Run Code Online (Sandbox Code Playgroud)
这是错误的,因为输入SELECT a被识别ANYTHING,而不是select.我该如何解决这个问题?我觉得我在这里遗漏了一些概念,但很难开始.
我收到错误label assigned to a block which is not a set。我的标签,会出现此错误:child,left,right,first,和last。我正在做的是为一组备选方案分配一个标签;这不应该被支持吗?
我的语法片段:
expr:
unaryExpr '(' child=(stat | expr | NUMBER) ')' #labelUnaryExpr
| binaryExpr '(' left=(stat | expr | constant) ',' right=(stat | expr | constant) ')' #labelBinaryExpr
| multipleExpr '(' first=(stat | expr | constant) (',' rest=(stat | expr | constant))+ ')' #labelMultipleExpr
;
Run Code Online (Sandbox Code Playgroud)