我想使用Antlr4来解析我的C#应用程序中的一些文件.鉴于我的语法,到目前为止,我已经能够生成解析器和词法分析器文件.现在我想在文件中使用read并将解析器和词法分析器应用于它们.我一直在寻找有关如何做到这一点的文档,但我很简短.我找到了一些使用以前版本的Antlr的旧例子,但它们似乎不适用于Antlr4.任何帮助,将不胜感激.谢谢.
我正在尝试在Eclipse Luna(4.4)上安装ANTLR 4 IDE.我已经从Marketplace安装了它,但我不知道如何创建一个包含ANTLR 4 Lexer/Parser的项目.
当我去创建一个新项目时,我没有看到ANTLR 4的任何选项.我尝试创建一个.g4文件,它在编辑器中打开,但是当我保存它没有做任何事情.
我尝试使用gradle antlr插件,但遇到了几个问题.
我有一个语法文件叫wls.g4
:
grammar WlsScript;
@header {
package hu.pmi.wls.antlr.ws;
}
program
: 'statementList'? EOF
;
// Several more grammar and lexer rules
Run Code Online (Sandbox Code Playgroud)
(注意:我将statementList设为一个关键字,只是为了制作一个正确的语法而不包括整个语法.;-))
该文件位于/ src/main/antlr(作为antlr生成语法文件的默认源文件夹).
以下是来自的代码段build.gradle
:
project('common') {
apply plugin: 'antlr'
dependencies {
// Some dependencies
antlr "org.antlr:antlr4:4.5"
}
}
Run Code Online (Sandbox Code Playgroud)
当我使用generateGrammarSource
gradle任务(从antlr
插件中提交)生成源文件时,它会生成build/generated-src/antlr/main
默认文件夹中的文件.
出了什么问题,它没有创建java包的文件夹(hu/pmi/wls/antlr/ws
在我们的例子中),因此源将错误地定位在Eclipse中.
我的主要问题是如何强制任务以包结构的方式生成源文件?换句话说,如何配置gradle任务以使用语法中的包声明?
谢谢!
我正在尝试为juniper/srx路由器访问控制列表编写解析器.以下是我使用的语法:
grammar SRXBackend;
acl:
'security' '{' 'policies' '{' COMMENT* replaceStmt '{' policy* '}' '}' '}'
applications
addressBook
;
replaceStmt:
'replace:' IDENT
| 'replace:' 'from-zone' IDENT 'to-zone' IDENT
;
policy:
'policy' IDENT '{' 'match' '{' fromStmt* '}' 'then' (action | '{' action+ '}') '}'
;
fromStmt:
'source-address' addrBlock # sourceAddrStmt
| 'destination-address' addrBlock # destinationAddrStmt
| 'application' (srxName ';' | '[' srxName+ ']') # applicationBlock
;
action:
'permit' ';'
| 'deny' ';'
| 'log { session-close; }'
;
addrBlock:
'[' srxName+ …
Run Code Online (Sandbox Code Playgroud) 我正在尝试将我的语法从v3转换为v4,并且在找到所有正确的部分时遇到了一些麻烦.
在v3中处理一个String,我用过:
public static DataExtractor create(String dataspec) {
CharStream stream = new ANTLRStringStream(dataspec);
DataSpecificationLexer lexer = new DataSpecificationLexer(stream);
CommonTokenStream tokens = new CommonTokenStream(lexer);
DataSpecificationParser parser = new DataSpecificationParser(tokens);
return parser.dataspec();
}
Run Code Online (Sandbox Code Playgroud)
如何将其更改为在v4中工作?
在ANTLR 3中,您可以执行以下操作:
andExpression
: (andnotExpression -> andnotExpression)
(AND? a=andnotExpression -> ^(AndNode $andExpression $a))*
;
Run Code Online (Sandbox Code Playgroud)
知道如何在新版本中做到这一点吗?
我是ANTLR4的新手,似乎没有针对v4的Eclipse-Plug-In.因此,从.g4语法自动构建Java源代码会很好.我有一个简单的空Maven项目,带有src/main/java,src/test/java.在哪里放置.g4文件?如何使用Maven自动构建语法?
我自己的POM测试失败了:
<repository>
<id>mvn-public</id>
<name>MVNRepository</name>
<url>http://mvnrepository.com</url>
</repository>
...
<build>
<plugins>
<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId>
<version>4.0.0</version>
<executions>
<execution>
<goals>
<goal>antlr</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Run Code Online (Sandbox Code Playgroud)
Eclipse说:
Failure to find org.antlr:antlr4-maven-plugin:pom:4.0.0 in http://repo.maven.apache.org/maven2 was cached in the local repository, resolution will not be reattempted until the update interval of
central has elapsed or updates are forced
Run Code Online (Sandbox Code Playgroud) 如何在ANTLR中以任何顺序制定规则以匹配其所有备选方案一次?
即
rule: ('example\r\n' | 'example2\r\n') nextRule
Run Code Online (Sandbox Code Playgroud)
我希望'example'和'example2'在进入下一个规则之前只匹配一次.
应匹配以下输入:
example
example2
Run Code Online (Sandbox Code Playgroud)
要么
example2
example
Run Code Online (Sandbox Code Playgroud)
但没有输入:
example
example
example2
Run Code Online (Sandbox Code Playgroud) 如何在通用遍历解析树的同时访问ANTLR4中的备用标签?或者,是否有任何方法可以复制^
ANTLR3 的运算符的功能,因为这样可以解决问题.
我正在尝试为任何符合简单方法的ANTLR4语法编写AST漂亮的打印机(比如用替代标签命名产品).我希望能够打印出更漂亮的一个术语类似3 + 5
的(int_expression (plus (int_literal 3) (int_literal 5)))
,或类似的东西,给出类似下面的语法:
int_expression
: int_expression '+' int_expression # plus
| int_expression '-' int_expression # minus
| raw_int # int_literal
;
raw_int
: Int
;
Int : [0-9]+ ;
Run Code Online (Sandbox Code Playgroud)
我无法有效地为制作plus
和minus
制作命名,因为将它们拉到自己的制作中会导致工具抱怨规则是相互左递归的.如果我不能把它们拉出来,我怎么能给这些作品命名呢?
注1:+
通过将"好"终端(例如,Int
上面的)放在特殊制作中(以特殊前缀开头的制作等raw_
),我能够在方法论上摆脱论证.然后,我只能打印那些父作品被命名为" raw_
......"而终止所有其他作品的终端.这非常适合摆脱+
,同时保持3
和5
输出.这可以通过!
ANTLR3完成.
注意2:我知道我可以编写一个专门的漂亮的打印机或为给定语言的每个产生使用动作,但我想使用ANTLR4来解析和生成各种语言的AST,看起来我应该是能够编写如此简单漂亮的打印机.换句话说,我只关心获得AST,而我宁愿不用每个语法来使用量身定制的漂亮打印机来获取AST.也许我应该回到ANTLR3?
使用ANTLR,我解析语法.ANTLR错误在语法的自定义编辑器中指示.但是,我想禁用将错误消息打印到Java控制台.
我已经实现了自己的BaseErrorListener并删除了ANTLR书中描述的默认值:
MyErrorListener errList=new MyErrorListener ();
lexer.removeErrorListeners();
lexer.addErrorListener(errList);
parser.removeErrorListeners();
parser.addErrorListener(errList);
Run Code Online (Sandbox Code Playgroud)
我仍然得到打印输出到我的Java控制台(连接到Java输出和错误流).
如何在ANTLR中禁用打印到控制台?