我正在尝试将语法从 bison 翻译为 ANTLR。野牛的语法本身非常简单,但我找不到简单的方法来做到这一点。
野牛语法:
expr = expr or expr | expr and expr | (expr)
Run Code Online (Sandbox Code Playgroud)
欢迎任何提示/链接/指针。
谢谢,尤利安
实际上这个问题与我之前的问题Catching ANTLR's NoViableAltException in Java和ANTLRWorks Debugger有关,但由于症状不同,我决定将它们分开。
问题在于向 ANTLR 输入文本提供信息,其中包含未知标记。例如,考虑一下我们的语法对以符号开头的标记一无所知@。如果我们尝试将此类文本提供给ANTLRWorks解释器,我们将收到NoViableAltException结果图表。
但是,如果我们使用 Java 生成和编译的语法并尝试用它解析此类无效文本,我们可以收到以下结果之一(这取决于我们将放置这个未知标记的位置,即我们将其放置的“深度”)进入文本):
1)没有错误,并且顶级对象中null的字段值(提到的问题正是关于这种情况);chidlrenCommonTree
2)java.lang.OutOfMemoryError: Java heap space错误。
这个问题是关于第二种情况的。我们如何防止ANTLR解析器的这种行为?例如,在生产中,客户端可能会因为向 DSL 解析器提供不正确的字符序列而意外导致系统崩溃。
我对antlr 的理解停留在非常基础的层面。浏览 Parr 博士的“权威 ANTLR 4 参考”。在第 4.2 节“使用访问者构建计算器”中列出了以下语法:
\n\ngrammar LabeledExpr; // rename to distinguish from Expr.g4\n\nprog: stat+ ;\n\nstat: expr NEWLINE # printExpr\n | ID \'=\' expr NEWLINE # assign\n | NEWLINE # blank\n ;\n\nexpr: expr op=(\'*\'|\'/\') expr # MulDiv\n | expr op=(\'+\'|\'-\') expr # AddSub\n | INT # int\n | ID # id\n | \'(\' expr \')\' # parens\n ;\n\nMUL : \'*\' ; // assigns token name to \'*\' used above in grammar\nDIV : \'/\' ;\nADD : \'+\' …Run Code Online (Sandbox Code Playgroud) 我是 ANTLR(任何版本)的新手,我刚刚开始编写我的第一个语法文件。我正在使用带有 ANTLR 插件 (v1.6) 的 IntelliJ IDE。
我的语法是
grammar TestGrammar;
testfile : message+ EOF;
message : timestamp WS id (NL | EOF);
timestamp : NumericLiteral;
id : NumericLiteral;
NumericLiteral : INTEGER | DECIMAL;
INTEGER : [+-]? [0-9]+;
DECIMAL : [+-]? [0-9]* '.' [0-9]+;
EXPONENT : [eE] [+-]? [0-9]+;
WS: (' ' | '\t')+;
NL: '\r'? '\n';
Run Code Online (Sandbox Code Playgroud)
当我应用简单的测试输入时
123 1231
123 1312
Run Code Online (Sandbox Code Playgroud)
数据已正确解析,但我在 IntelliJ 预览窗口中收到错误消息。“额外的输入 '<EOF>' 期待 {<EOF>, NL}”
我做错了什么?EOF 似乎被正确检测到...如果我在最后一行添加一个 NL,那么该文件将被正确解析,但我需要确保最终的 NL 是可选的。
格式的其他详细信息:
我们正在对数据格式进行逆向工程,所以老实说,我们真的不知道约束是什么!我们目前的理解是:
我们已经看到文件遵循这些模式的证据,因此我们知道它们是有效的输入。
我对 ANTLR 和语法有一定的了解。说 ANTLR 可以进行源语言到目标语言的转换,如 ASP 到 JSP 或 COBOL 到 JSP 的转换是否正确?如果是的话,你能帮我提供一些信息/教程/链接到资源管理器的可能性吗?
想法是使用 ANTLR 务实地将大量代码从源代码转换为目标代码。
谢谢
我正在尝试编写一个语法来评估可能会或可能不会被括号包围的方程。前任 -
在我的规则中,我有
clause
: expression EOF
;
expression
:
LPAREN expression RPAREN #parenExpression
| isNumeric #isNumericExpression
| leftSide IS NOT? NULL #nullExpression
| compare #comparatorExpression
| NOT #notExpression
;
compare : NOT? LPAREN? NOT? leftSide op=comparator rightSide RPAREN? ;
Run Code Online (Sandbox Code Playgroud)
现在,这有几个问题。
任何有关如何为这些规则编写语法的帮助都会非常有帮助。
提前致谢!
如何List<double>使用ANTLR4将包含十进制数字的文件解析为C#中的a?一个完整的工作示例将说明所有部分如何组合在一起。
输入文件如下所示:
12.34
45.67
89.10
Run Code Online (Sandbox Code Playgroud) 我在玩 antlr4 语法文件,我想编写自己的jsonpath语法。
我想出了这个:
grammar ObjectPath;
objectPath : dnot;
dnot : ROOT expr ('.' expr)
| EOF
;
expr : select #selectExpr
| ID #idExpr
;
select : ID '[]' #selectAll
| ID '[' INT ']' #selectIndex
| ID '[' INT (',' INT)* ']' #selectIndexes
| ID '[' INT ':' INT ']' #selectRange
| ID '[' INT ':]' #selectFrom
| ID '[:' INT ']' #selectUntil
| ID '[-' INT ':]' #selectLast
| ID '[?(' query ')]' #selectQuery
; …Run Code Online (Sandbox Code Playgroud) 我正在努力理解 ANTLR4 算法以及它如何处理左递归。希望有人可以教育我一点。
采用左下递归语法:
grammar Dummy;
TOK1 : 'foo';
TOKE_OPT : 'bar';
TOK2 : 'baz';
TOKDERP : 'derp';
SPACES
: [ \u000B\t\r\n] -> channel(HIDDEN)
;
rr
: rr TOK1 rr TOKE_OPT?
| '(' TOK2 ')'
| TOKDERP
;
Run Code Online (Sandbox Code Playgroud)
以及以下输入字符串:
derp foo derp foo derp
Run Code Online (Sandbox Code Playgroud)
当运行TestRig -diagnosticsANTLR 时,得出的语法是模棱两可的,我不明白为什么:
line 1:5 reportAttemptingFullContext d=2 (rr), input='foo'
line 1:9 reportContextSensitivity d=2 (rr), input='foo derp'
line 1:14 reportAttemptingFullContext d=2 (rr), input='foo'
line 2:0 reportAmbiguity d=2 (rr): ambigAlts={1, 2}, input='foo derp
'
Run Code Online (Sandbox Code Playgroud)
如果有人能解释为什么这种语法有歧义以及如何消除歧义,将不胜感激。我也有可能不明白为什么歧义意味着:)。
如果我删除该 …
ANTLR 是否可以根据我们在解析过程中的条件来更改 AST?
例如,在解析像 foo().dropLastBar(true).bar() 这样的字符串时,如果我们知道存在 dropLastBar(true),我们希望删除最后一次出现的栏。
现在我已经使用ANTLR中的“成员”来记录是否存在具有真值的dropLastBar。但是我不知道如何修改ANTLR的规则,使生成的AST根据我们拥有的字符串而有所不同。字符串可以是foo().dropLastBar(true).bar().bar().bar(),那么我们有没有可能得到foo().dropLastBar(true).bar()生成的AST。 bar() 没有解析两次?