我正在尝试用ANTLR学习EBNF语法。所以我想我会把维基百科的EBNF语法转换成ANTLR 4,然后玩它。然而,我在这方面经历了一段糟糕的时光。我能够将语法简化为产生问题的一个步骤
似乎如果我只有一个令牌引用另一个令牌,那么ANTLR 4就无法解析输入
这是我的语法:
grammar Hello;
program : statement+ ;
statement : IDENTIFIER STATEMENTEND /*| LETTERS STATEMENTEND */ ;
LETTERS
我正在为一种古老的语言编写语法
这门语言相当复杂,但我想把重点放在一个特定的问题上,所以我做了一个简单的版本。
轻型版本允许指定赋值语句和简单表达式,如数学运算或字符串串联
像这样:
@assign[@var1 (1+3)*2]
@assign[@var2 "foo" $ "bar"]
@var1 @var2
注意:在赋值语句中,变量不能以@char开头。语句也可以写在多行上,因此以下赋值是等效的:
@assign[@var2 "foo" $ "bar"]
@assign[var2
使用ANTLR v4,第一个文件的解析需要几秒钟,接下来的文件的解析几乎是瞬间完成的
是否可以保存ANTLR的状态以避免预热时间
decisionToDFA是唯一应该序列化的数据结构吗?我只能为ANTL3说话,但是如果Antl4没有类似的机制,我会非常惊讶。在ANTLR3中,您可以重置解析器和lexer,并使用新字符串重新开始。但您不会创建新的解析器实例,而是从以前的运行中重用它。但是,我无法在多个执行(不同的进程/JVM)之间共享状态。通常,我希望在我的语言的标准库上训练解析器,然后将经过训练
在我的用例中,我必须在生成的解析树上使用访问者将数千个小的独立表达式解析成一个树表示。
目前,为每个解析操作创建了新的流、lexer和解析器实例
我认为这可能不是最优的。在这样的设置中,哪些对象实例可以重复使用以利用ANTLR4的预热属性?线程安全性如何?这些实例中哪些应该是线程本地的?重复使用lexer或parser实例是否需要某种重置?在ANTLR 4的早期(最初发布之前的几个月),自适应DFA缓存是基于每个实例创建的,因此使用lexer.setInputStream或parser.setI
假设以下语法:
grammar Demo;
start: START_BLOCK SEPERATOR;
START_BLOCK: '-.-.-';
ID: ( LETTER SEPERATOR ) (LETTER SEPERATOR)+;
fragment LETTER: L_A|L_K;
fragment L_A: '.-';
fragment L_K: '-.-';
SEPERATOR: '!';
我将以下输入传递给语法:-。-
我希望ANTLR能够识别START_块和分隔符。但
输入
(001)
规则消息不产生可行的替代方案:
[@0,0:0='(',<2>,1:0]
[@1,1:1='0',<3>,1:1]
[@2,2:2='0',<3>,1:2]
[@3,3:3='1',<3>,1:3]
[@4,4:4=')',<1>,1:4]
[@5,5:4='<EOF>',<-1>,1:5]
line 1:1 no viable alternative at input '0'
它解决了这个问
我正在为一种语言编写一个ANTLR 4语法,这种语言将有switch语句,这些语句不允许出错(类似于C)。所有的case语句必须由break语句终止。多个case语句可以相互跟随,中间没有任何代码(同样,与C#中的情况相同)。下面是一段语法片段,它抓住了这一点:
grammar MyGrammar;
switchStmt : 'switch' '(' expression ')' '{' caseStmt+ '}' ;
caseStmt : (caseOpener)+ statementLi
我尝试在TestRig中运行以下语法:
grammar COBOLfragment;
// hidden tokens
WS : [ ]+ -> channel(HIDDEN);
NL : '\n' -> channel(HIDDEN);
// keywords
PERIOD : '.';
DIVISION : 'DIVISION';
SECTION : 'SECTION';
DATA : 'DATA';
WORKING_STORAGE : 'WORKING-STORAGE'
我正在测试ANTLR的词汇规则,但我发现与所使用的表达式规则有些不同
给埃克斯梅普
CN : (CHN|STRING)+;
此规则只能匹配以中文开头的字符和不能匹配字母的字符
model
: CN (.*?) #modelName
| ID (.*?) #modelName
;
此通配符(.*)语法规则只能与当前定义的词汇规则(例如点、NUM、ID、CN)匹配。它不能匹配任何其他字符
Formula.g4
grammar Formula;
prog
:
有人知道是否有办法获取当前的ATNState吗?我正在直接实现ParseTreeListener,并希望按照以下思路做一些事情:
public class MyParseTreeListener implements ParseTreeListener {
private ATN atn;
public MyParseTreeListener(ATN atn) {
this.atn = atn;
}
@Override
public
我正试图为一个受fortran启发的DSL编写一个ANTLR4语法。我在“ole classic”方面遇到困难。op.“运算符:
if (1.and.1) then
其中,两个“1”都应解释为整数。我查看了OpenFortranParser以获得洞察力,但我无法理解它
最初,我在lexer中对INTEGER和REAL有合适的定义。因此,不管我怎么做,上面的第一个“1”总是解析为实数。我尝试将东西移动到解析器中,并使它能够可靠地识别“.”和“.”以及它周围的数字作为适当的整数或实数
if (1.
我想知道Antlr4生成的解析树是否是线程安全的。文档中没有任何东西表明它是或不是。我想缓存生成的解析树,这样就不必为相同的输入重新分析它们,但我想在这样做之前确保它们是安全的。让它们成为线程安全的取决于您。这是一个您必须像其他任何数据结构一样加以保护的数据结构。假设我的访问者没有更改树数据,我可以假设它是线程安全的吗?访问解析树的行为是否会导致修改antlr目标运行时内部的解析树?我很确定它不会在内部改变数据,但我希望从一个开发人员那里得到一个明确的答案。从多个线程进行只读访问从来都不是问题。
我一直在努力破解我的ANTLR4语法,试图一次消除它的所有歧义和lexer规则错误。我似乎做什么都不能解决问题。这些lexer规则给出的错误如下:
Identifier: Letter (Letter | Digit | Und)+;
Keyword : Letter+;
Param: Number | Identifier;
Statement: Keyword Lpr Param+ Rpr;
Block: Lbc Statement+ Rbc;
正如你们可能已经注意到的,他们的一个共同
ANTLR4.7.1在parse.cs文件中生成一行,表示
throw new RuntimeException("UNEXPECTED_CHAR=" + (_localctx._UNEXPECTED_CHAR!=null?_localctx._UNEXPECTED_CHAR.Text:null));
例外情况不存在。手工编辑生成的代码很容易修复,但每次都要进行语法编辑,这有点烦人
像这样使用内置的c#支持
java -jar c:\tools\antlr-4.7.1-complete.jar
我在尝试使用版本ANTLR 4.7.2构建解析器时收到此警告
warning(125): CobolParser.g4:1075:20: implicit definition of token END_ACCEPT in parser
如果我将accept_语句规则更改为使用END_ADD而不是END_accept,
解析器生成时没有警告
你能解释一下为什么我会收到这个警告吗,
既然END_ACCEPT是在lexer中定义的
从CobolLexer.g4:
END:
是否可以保存由ANTLR4生成的解析树?例如,使ParseTree或其子类可序列化
我想使用ANTLR4解析项目中的源文件。我的项目相当大,包含数百个源文件。通常,我需要遍历几个源文件的解析树来获得我想要的信息。完整的语法非常庞大,即使只解析一个源文件也需要一段时间。因此,每次启动工具以获取一条信息(例如函数的调用者)时,再次解析所有源文件是不切实际的。如果我可以只解析一次并将解析器输出保存到硬盘中,那就太好了。如果您在性能方面有问题,您应该确保使用两阶段解析策略。例如,查看以下测试中TWO\u
我的语法(如下所示(从原始语法中删减))需要一些重叠的规则
grammar NOVIANum;
statement : (priorityStatement | integerStatement)* ;
priorityStatement : T_PRIO TwoDigits ;
integerStatement : T_INTEGER Integer ;
WS : [ \t\r\n]+ -> skip ;
T_PRIO : 'PRIO' ;
T_INTEGER : 'INTE
我使用Antlr4来标记和解析遗留语言,我的最终目标是生成C#代码,并在模拟执行遗留语言的物理硬件的运行时环境中执行该代码
模拟器和代码生成工作得很好
我想从侦听器生成特定的错误消息或警告消息,这可能吗
例如,语言允许一行以分号结尾或不以分号结尾,如果一行缺少分号,我想发出警告
我有很多类似的场景,语言和物理硬件有很多奇怪的特性
谢谢,
Gregg更好的方法可能是从解析器发出警告。在解析器的构造中,有两种方法:
parser.addErrorListener(new YourErrorListe
由于我是antlr的新手,我在语法谓词方面有很多问题。
我一直在尝试转换这个语法,这是natty语法的一部分,为了用antlr4解析它,我真的很困惑如何以有意义的方式更改它
date_time
: (
(date)=>date (date_time_separator explicit_time)?
| explicit_time (time_date_separator date)?
) -> ^(DATE_TIME date? explicit_
我想知道是否有一个库包含使用Xtext定义的不同语法语言,类似于antlrv4的库。这将实现重用并帮助重新发明轮子。不,没有这样的东西,至少没有一个单一的集成存储库。
在官方文件中,有
但是,根据您试图实现的目标,像基本语法或像文本建模语言这样的语言可能会达到您的目的。除此之外,你可以
到目前为止,我认为标记值(由lexer规则生成)与该规则的规则索引相同。显然,情况并非如此,当您查看生成的代码中的ruleNames和literal/display names字段时可以看到这一点。与显示名称(仅是标记值的字符串表示形式)相比,规则名称的顺序部分不同,并且还包含片段规则等内容。另一方面,没有虚拟令牌的条目(定义见令牌部分)
现在,当您希望从令牌值获取规则索引时,您将如何做到这一点?我能想象的唯一方法是从词汇表中获取符号名(即规则名),然后在规则名数组中查找。但这似乎有点奇怪。应该
我正在为计算器应用程序使用Antlr4编写一个简单的表达式解析器。我不知道如何编写区分数字9和算术表达式9-9的语法。非常感谢您的任何帮助
这是我的语法表达式。g4:
grammar expression;
expression = expression ADDOPER expression
| expression SUBOPER expression
| NUMBER;
/* lexical rules */
ADDOPER :
我有一个表达式规则,如下所示:
expression : '(' expression ')' # ParenthesizedExpression
| literal # LiteralExpression
| identifier # IdentifierExpression
| functionCall # FunctionCallExpression
我正在寻找antlr4的C#Runtime,网站上有v4运行时的直接下载
阅读文档后,它说要使用NuGet获取Antlr4运行时
但是,在搜索NuGet查找Antlr,Antlr4,Antlr4时,没有Antlr4运行时。搜索Antlr4时,有一个用于StringTemplate4的包,但没有直接的antl4运行时 通过我自己的尝试,我发现Visual Studio的ANTLR扩展仅在VS2010及以下版本中可用 有关安装ANTLR 4的C#目标的说明,可在下一页底部的readme.md文件中找
在我调查了中引用的语法之后,很明显问题的关键在于这些产生式规则:
TIMESPAN : startTime (WS THRU WS endTime)? ;
startTime : TOD ;
endTime : TOD ;
中间生成规则startTime和endTime的原因是为这些规则生成侦听器回调,因此我不必在TIMESPAN侦听器中显式解析它们。但显然,这混淆了antlr4解析器。为了解决这个问题,我将规则简化如下:
TIMESPAN : TOD (WS THRU WS TOD)
标签: Antlr4
context-free-grammar
我使用antlr 4定义自己的语法,我想根据操作的优先级(+*-/)构建tree true
我发现关于操作优先级(*+)的示例工作正常
我尝试对其进行编辑以添加操作优先级(-/),但失败:(
操作优先级(+*)的语法为:
如何向它们添加操作优先级(-/)?您通常通过定义表达式、术语和因子产生式规则来解决这个问题。下面是一个语法(在EBNF中指定),它实现了一元+和一元-,以及4个二元算术运算符和括号:
start ::= expression
expression ::= term (('+'
标签: Antlr4
context-free-grammarleft-recursion
我试着寻找我的解决方案的答案,但我似乎无法将我的头脑集中在广义的解决方案上。我无法找出哪些元素对应于大写字母,哪些元素应该用小写字母表示,这对我没有帮助
这是我的Antlr语法的一部分:
expression
: literal
| unaryExpression
| binaryExpression
| priorityExpression
| invocation
;
binaryExpression: expression binaryOp
我试图重用lexer/parser来顺序解析短文本块。为了确保前一次跑步不会留下任何痕迹,我总是这样做
mLexer.reset();
mLexer.setInputStream(new ANTLRInputStream(data));
mParser.reset();
mParser.setTokenStream(new CommonTokenStream(mLexer));
认为这将完全重置lexer和parser,不管之前发生了什么。不幸的是,在解析无效
在ANTLR4中,在流包含某个多字符字符串之前,匹配任意字符串的正确lexer规则是什么
例如,在CharStream中,我有:
#integer12314#end
#freetextFoo bar#end
我想从Foo-bar创建一个令牌类型为TEXT的令牌
每个条目都用#end标记关闭
文本由[\u001-\u007f]*组成,但现在我们先忘掉空格交互
文本可以包含、#e、#en
从上面的CharStream中,我期望令牌流为:
tokenOf(#integer) Integer to
我有以下antlr4语法:
grammar nota;
word: WORD;
WORD: ~'a'; //match anything that isn't an 'a'
如上所述,这将否定单个给定字符或字符范围的字符集
然后我尝试解析一些测试用例文本(每个测试用例输入一个字符):
a预期失败
b预期成功
$预期成功
+意外失败
=意外失败
§预期成功
\预期成功
/意外失败
~预期成功
如果有关系,我将使用nodejs的antlr4ts 0.5.0-alpha.4。
例如,默认错误侦听器打
我正在编写一个编译器,将JavaCC转换为ANTLR4,其中一个规则涉及传递参数并从中获取返回值
对于规则“术语”,我必须执行以下操作:
Term term(ReadOptions options, int priority):
{
int p = options.operatorSet.getNextLevel(priority);
Term t;
}
{
(
LOOKAHEAD({p==0})
t = simpleTerm(options)
|
LOO
假设我有一个语法,它有一个解析器规则来匹配几个特定字符串中的一个。
语法中正确的做法是为每个特定字符串创建备用语法分析器规则,还是保持语法分析器规则的通用性并在访问者子类中解码该字符串?如果特定字符串有意义(例如DSL中的关键字),听起来您需要令牌。语法中的任何规则都可以引用您创建的标记
一般来说,最好让语法尽可能多地完成语法分析器的工作,而不是过度概括和编写大量额外的代码
请参见以下内容:太好了!这是我的本能,我用代币代替,而不是不必要地把事情复杂化。谢谢你的帮助!
我在分析antlr4中的格式行列表时遇到问题
* this is a string
* "first" this is "quoted"
* this is "quoted with \" "
我想构建一个解析树,就像
(list
(line * (value (string this is a string)))
(line * (value (parameter first) (string this is) (parameter quoted)))
(line * (val
标签: Antlr4
lexerdisambiguation
我对ANTLR4语法有问题。我需要解析一个包含6个字符的文本。
根据文本的上下文,它可以表示:
-一个6-a标识符(航班预订号-PNR-看起来像7B22MS或JPN92Y或类似物),
-航空公司代号(两个字母)+航班号(四个数字),例如LH1856
问题是,如果我创建lexer规则来解析航空公司、号码和PNR标识符,如下所示:
航空公司:A''Z''A''Z'
FlNum:('0'..'9')('0'..'9')('0'..'9')('0'..'9')
PNR:(‘A’、‘Z’、‘0’、‘9’)
我正在试验w/ANTL4语法,最好将其标记为短语而不是单词(即,大多数标记可能包含空格)。但是,在某些情况下,我希望捕获特定的子字符串短语作为单个标记。考虑下面的例子:
Occurrence A of Encounter Performed
短语“的出现”很特别——每当我看到它,我都想把它拔出来。语句的其余部分(“Conference Performed”)相当随意,在本例中,可以是任何内容
在本例中,我快速编写了以下语法:
grammar test;
stat: OCCURRENCE PH
我有一组要解析的文件,它们的内容很奇怪。每行包含以下数据(删除此处不相关的所有其他内容):
数据
然后我们可以得到如下文本:
file: lines+ EOF
;
lines: data_line
| text_line
;
text_line: TEXT TEXTUALDATA
;
data_line: DATA sensordata
;
sensordata: DATA FLOATVALUE PERIOD
;
TEXT:'TEXT';
DATA: 'DATA' ->
在一种情况下,我的语法允许。。。ID=expr或。。。ID=expr(expr[,expr]*),即带有终止分号的表达式和函数调用。当参数列表中出现错误时,ANTLR决定最简单的解决方案是用分号替换开括号。这确实符合规则,但是其余的输入看起来像垃圾。随后出现的分析错误具有误导性
在这种情况下,我认为这是错误的恢复方式。很有可能错误出现在参数列表中,而不是键入(用于;)。我想告诉ANTLR,如果它在那里找到一个开括号,它必须使用它,而不是替换它。然后(在我的梦中),ANTLR将正确诊断内部表达式的
我有一条规则如下:
INTEGER : [0-9]+;
myFields : uno=INTEGER COMMA dos=INTEGER
现在要访问uno,我需要编码:
Integer i = Integer.parseInt(myFields.uno.getText())
Integer i = myFields.uno
如果我能告诉鹿角帮我做那个转换,那会干净得多;然后我只需要编写代码:
Integer i = Integer.parseInt(myFields.uno.getText
我在如下目录中有两个语法文件:
+- antlr4
+- common
| +- Numbers.g4
+- lang
+- Lang.g4
在Lang.g4中,我尝试:
grammar Lang;
options {
tokenVocab = common.Numbers;
}
但我有一个错误:
cannot find tokens file <PROJECT_LOCATION>/target/g
我试图使用ANTLR4解析java文件,并遍历解析树搜索特定的函数调用
虽然我可以通过访客和听众两种方式实现这一点,但压力测试表明,与访客相比,听众的速度要快得多,这与普遍的看法相反
理论上,访问者应该更快,因为他们只会检查特定节点,而侦听器会检查所有节点。有人知道为什么会出现这种情况吗?在ANTLR中,听众应该比访客更快,尽管性能差异不容易测量(如果有的话)
侦听器在中使用walker算法。访问者在中使用该算法。两者都“考虑”所有节点
除了轻微的实现差异之外,一个数量上的差异是访问者调用涉及一
坚持使用of中的示例代码,我无法使任何一个都正常工作。例如,当初始化GenericParser时,它会说:
error(50): :1426:3: syntax error: 'lL' came as a complete surprise to me while matching a lexer rule
error(50): :1448:3: syntax error: '1-9' came as a complete surprise to me while matching a lexe
我不熟悉ANTLR并使用ANTLR4(4.7.2 Jar文件)。我目前正在研究Oracle解析器。
我对十进制数有意见。我只保留了相关部分。
我的语法文件如下
现在,当我解析下面的语句时,就可以了。“.1”在我的情况下是一个有效数字。
开始一个数字:=.1;结束
我还没有展示语法,但以下是我在Oracle中的有效案例
a NUMBER:= .1; // with Space after operator
a NUMBER:=1.1; // without Space after operator
这是我精简的ANTLR4语法(注意,我使用常量false替换返回false的方法):
我的测试文件只包含一个单词“hello”,测试结果如下:
D:\work\antlr4\work>java org.antlr.v4.runtime.misc.TestRig AnnotProcessor cppCompilationUnit -tree in.cpp
line 1:5 no viable alternative at input '<EOF>'
(cppCompilation
因此,我正在尝试使用Antlr v4,并用一些不寻常的语法对其进行测试,以了解其工作原理。下面是我当前的测试用例:
我想要一个按顺序由字母a、B、C、d组成的语法。这些字母可以重复。我还将a和B分组在一起,C和d也分组在一起,以使语法更有趣。这样的字符串是可以接受的语法:
AAA
ABCD
ACCCDD
但这并不顺利。我认为现在发生的是,Antlr需要一个更好的语法退出规则。它似乎没有意识到,在收集了a和B之后,C的存在意味着进入下一个规则。实际上,这是可行的,但我得到了错误消息,并且生成的解析
我正在sql语法中使用限制标记。它工作得很好,但是当我使用与令牌名相同的列名时,我就遇到了问题。我有一个与limit相同的列名。我如何解决这个问题
输出:
line 1:10 mismatched input 'limit' expecting VAL
line 1:10 mismatched input 'limit' expecting VAL
输入:
select a, limit from abc limit 55 ;
语法:
grammar SQLCmd;
parse : sql
我猜我正在修复这里提到的517:
但我不是很确定。我只知道如果我移动,我的xdot解析器就会崩溃
从4.2.2到4.3
xdot有一个成语:N-。广泛使用。
比如说
3-ABC
4-@8&
我在这里只使用了一个片段来实现它,并将字符限制为数字:
integer returns [int v]
:
lhs=integer DIGIT {$v = (10 * $lhs.v) + $DIGIT.int;}
| DASH DIGIT {$v = - $DIGIT.int
我正在尝试编写一个lexer规则,它将匹配以下字符串
A.
aa
aaa
bbbb
这里的要求是所有字符必须相同
我尝试使用这个规则:
重复字符:([a-z])(\1)*
但是\1在antlr4中无效。有可能想出一个模式来解决这个问题吗?在ANTLR lexer中你不能这样做。至少,语法中没有特定于目标的代码。在语法中放置代码是不应该做的事情(这会使阅读变得困难,而且语法与该语言有关)。最好在用户或访问者内部进行此类检查/验证
诸如回溯引用和环视是krept在编程语言的正则表达式引擎中使用的特性
我正在将系统Verilog修改为Antlr4。然而,对于我真正需要的东西来说,这是一个巨大的过度消耗。基本上,我需要类似于gcc中的-M开关的依赖性分析。这个问题出人意料地难以解决,而我目前基于regex的解决方案是不完整的,有缺陷的,并且在暴露于新代码时会不断中断,即使它已经被修补了很多次。我曾尝试使用各种免费提供的解析器,但它们似乎都无法处理符合最新Systemverilog(2012)标准的代码
我认为我需要一种基于解析器的方法,我认为我一直在构建自己的解析器。但我很有兴趣听到关于这方面的
我有一个语法分析器,如:
c:a | b+
a是这样的:
名称EQ INT
b就像:
名称EQ ALPHA
当我使用一个看起来像b a的序列进行测试时,我得到一个错误,表明解析a失败,因为解析器预期的是ALPHA,就好像它预期的是b一样
我认为a | b+可以找到任意顺序的a和b的链-类似于角色类的a[ab]+。但这似乎是在期待最初发现的任何一种选择都会在没有其他选择的情况下被重复
我是否理解a | b+的含义是错误的?你的理解是正确的——这就是它的工作原理
这里的问题可能是a和b规则的行为与A
代码tool.process(语法,false)生成空指针异常
请参见下面的我的代码:
package antlr;
import java.nio.file.Files;
import java.nio.file.Paths;
import org.antlr.v4.Tool;
import org.antlr.v4.tool.Grammar;
import org.antlr.v4.tool.ast.GrammarRootAST;
import org.junit.Test;
// Li
上一页 1 2 3 4 5 6 ...
下一页 最后一页 共 15 页