我正在使用带有c#目标的Antlr 4.这是我的语法的一个子集:
/*
* Parser Rules
*/
text : term+ EOF;
term : a1 a2 a3;
a1: ....
...
...
Run Code Online (Sandbox Code Playgroud)
我想接受有效数据块作为(term)s,当出现错误时我想搜索下一个有效术语并打印出导致错误的整个文本,供用户手动分析.
如何将输入同步到下一个有效期限?以及如何获取被忽略的文本?
是否可以使用ANTLR4从规则中提取第一组和后续组?我在ANTLR3中玩了一点这个并没有找到一个令人满意的解决方案,但如果有人知道任何一个版本的信息,我们将不胜感激.
我想解析用户输入用户的光标位置,然后提供自动完成的可能选择列表.目前,我对自动完成部分输入的令牌不感兴趣.我希望在解析的某个时刻显示所有可能的后续标记.
例如:
sentence:
subjects verb (adverb)? '.' ;
subjects:
firstSubject (otherSubjects)* ;
firstSubject:
'The' (adjective)? noun ;
otherSubjects:
'and the' (adjective)? noun;
adjective:
'small' | 'orange' ;
noun:
CAT | DOG ;
verb:
'slept' | 'ate' | 'walked' ;
adverb:
'quietly' | 'noisily' ;
CAT : 'cat';
DOG : 'dog';
Run Code Online (Sandbox Code Playgroud)
考虑到上面的语法......
如果用户还没有键入任何内容,则自动完成列表将是['The'](请注意,我必须检索FIRST而不是规则句子的FOLLOW,因为基本规则的跟随始终是EOF).
如果输入为"The",则自动完成列表将为['small','orange','cat','dog'].
如果输入是"猫睡了,自动完成列表将['安静','吵闹','.'].
所以ANTLR3提供了一种方法来获得以下这样的集合:
BitSet followSet = state.following[state._fsp];
Run Code Online (Sandbox Code Playgroud)
这很好用.我可以在我的解析器中嵌入一些逻辑,这样当解析器调用用户所在的规则时,它会检索该规则的以下内容,然后将它们提供给用户.但是,这对于嵌套规则也不起作用(例如,基本规则,因为跟随集忽略并且子规则如下所示).
我想如果用户已完成规则(这可能很难确定)以及覆盖所有有效选项的FOLLOW设置,我需要提供FIRST集.我还认为我需要构建我的语法,这样两个令牌永远不会在规则级别后续.
我会将上面的"firstSubject"规则划分为一些子规则......
从
firstSubject:
'The'(adjective)? CAT | DOG;
Run Code Online (Sandbox Code Playgroud)
至
firstSubject:
the (adjective)? CAT | DOG;
the:
'the';
Run Code Online (Sandbox Code Playgroud)
我还没有找到有关从规则中检索FIRST集的任何信息.
ANTLR4似乎已经在生成的解析器级别上大大改变了它的工作方式,所以此时我不确定是否应继续使用ANTLR3或跳转到ANTLR4. …
我正在阅读"最终的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) 使用ANTLR 4.2,我正在尝试对此测试数据进行非常简单的解析:
RRV0#ABC
Run Code Online (Sandbox Code Playgroud)
使用最小语法:
grammar Tiny;
thing : RRV N HASH ID ;
RRV : 'RRV' ;
N : [0-9]+ ;
HASH : '#' ;
ID : [a-zA-Z0-9]+ ;
WS : [\t\r\n]+ -> skip ; // match 1-or-more whitespace but discard
Run Code Online (Sandbox Code Playgroud)
根据Terence Parr的最终ANTLR 4参考文献中的摘录,我希望词法分析器RRV在ID之前匹配:
BEGIN : 'begin' ; // match b-e-g-i-n sequence; ambiguity resolves to BEGIN
ID : [a-z]+ ; // match one or more of any lowercase letter
Run Code Online (Sandbox Code Playgroud)
使用上面的测试数据运行ANTLR4测试台,输出为
[@0,0:3='RRV0',<4>,1:0]
[@1,4:4='#',<3>,1:4]
[@2,5:7='ABC',<4>,1:5]
[@3,10:9='<EOF>',<-1>,2:0]
line 1:0 mismatched input 'RRV0' expecting …Run Code Online (Sandbox Code Playgroud) 我正在尝试编写用于解析单行注释的语法.以" - "开头的注释可以出现在文件的任何位置.
我的基本语法如下所示.
grammar aa;
statement
: commentStatement* ifStatement
| commentStatement* returnStatement
;
ifStatement
: 'if' '(' expression ')'
returnStatement+
;
returnStatement : 'return' expression ';' ;
commentStatement : '--' (.+?) '\\n'? ;
expression : IDENTIFIER ;
IDENTIFIER : [a-z]([A-Za-z0-9\-\_])* ;
NEWLINE : '\r'? '\n' -> skip ;
WS : [ \t\r\f\n]+ -> skip ;
Run Code Online (Sandbox Code Playgroud)
public class aaTest {
static class aaListener extends aaBaseListener {
public void enterCommentStatement(CommentStatementContext ctx) {
System.out.println(ctx.getText());
}
}
public static void main(String[] …Run Code Online (Sandbox Code Playgroud) 所以,这是我的问题.我已经成功编译了我的ANTLR4代码,没有错误,现在我想测试它.ANTLR4文档告诉我,为了测试我的应用程序,我将这样做:
java org.antlr.v4.runtime.misc.TestRig
Run Code Online (Sandbox Code Playgroud)
我试过这个并得到以下错误:
错误:无法找到或加载主类org.antlr.v4.runtime.misc.TestRig.
我已经检查过我的CLASSPATH是否未设置,但是所有内容都已正确设置.我也尝试将文件直接移动到我的测试文件夹并在那里打开CMD并再次尝试,我发生了同样的错误.在互联网上搜索没有帮助,因为之前似乎没有人用ANTLR4发生过这个错误.
眼镜:
Java 1.7.0.55
ANTLR 4.4
对于下面的语法,
grammar names;
fullname : TITLE? FIRST_NAME LAST_NAME;
TITLE : 'Mr.' | 'Ms.' | 'Mrs.' ;
FIRST_NAME : ('A'..'Z' | 'a'..'z')+ ;
LAST_NAME : ('A'..'Z' | 'a'..'z')+ ;
WHITESPACE : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+ -> skip ;
Run Code Online (Sandbox Code Playgroud)
在解析像"John Smith先生"这样的输入时,它会抛出异常
mismatched input 'Smith' expecting LAST_NAME
Run Code Online (Sandbox Code Playgroud)
是否可以配置ANTLR来处理这种情况?如果不可能,可以采用哪种替代方法来处理它?
请注意,它不仅限于这种简单的情况.
我认为测序(由子规则隐式给出)在ANTLR4解析器中具有比交替更高的优先级(由|字符明确给出),这意味着
a : x | y z ;
在语义上是相同的
a : x | ( y z) ;
看一下ANTLR4的书并进行搜索,我无法找到明确的陈述,但这似乎是合理的,但是给出了规则
expression :
pmqident
|
constant
|
[snip]
|
'(' scalar_subquery ')'
|
unary_operator expression // this is unbracketed
|
expression binary_operator expression
[snip]
;
Run Code Online (Sandbox Code Playgroud)
我喂它这个select - 2 / 3我得到这个解析树
而如果我只是添加括号unary_operator expression并且完全没有改变,那就得到这个
expression :
[snip]
'(' scalar_subquery ')'
|
( unary_operator expression ) // brackets added here
|
expression binary_operator expression
[snip]
;
Run Code Online (Sandbox Code Playgroud)
并给它相同的SQL,我明白了
我有什么误会?
(顺便说一句,另外," - 2/3"到"( - …
我想将ANTLR4与Python 2.7结合使用,为此,我做了以下工作:
我antlr4-4.6-1使用sudo pacman -S antlr4。将软件包安装在Arch Linux上。
我写了一个MyGrammar.g4文件,并成功生成了Lexer和Parser Codeantlr4 -Dlanguage=Python2 MyGrammar.g4
现在执行例如生成的Lexer代码并python2 MyGrammarLexer.py导致错误ImportError: No module named antlr4。
可能是什么问题?仅供参考:我同时安装了Python2和Python3-我不知道这是否会造成任何麻烦。
我正在使用ANTLR4和Java定义语法。对于Integers,我想要一个以减号开头的数字。我知道可以这样做:
integer: '-' (DIGIT)* | DIGIT* ;
Run Code Online (Sandbox Code Playgroud)
但是我想知道是否有一个符号(类似于*)来确保减号出现零或一次:
integer: ('-')<some symbol here> (DIGIT)* ;
Run Code Online (Sandbox Code Playgroud)