我正在玩ANTLR,并希望创建一个这样的函数:
MOVE x y z pitch roll
Run Code Online (Sandbox Code Playgroud)
这会产生以下AST:
MOVE
|---x
|---y
|---z
|---pitch
|---roll
Run Code Online (Sandbox Code Playgroud)
到目前为止,我已经尝试过没有运气,并且我不断让AST将参数作为兄弟姐妹,而不是孩子.
代码到目前为止:
C#:
class Program
{
const string CRLF = "\r\n";
static void Main(string[] args)
{
string filename = "Script.txt";
var reader = new StreamReader(filename);
var input = new ANTLRReaderStream(reader);
var lexer = new ScorBotScriptLexer(input);
var tokens = new CommonTokenStream(lexer);
var parser = new ScorBotScriptParser(tokens);
var result = parser.program();
var tree = result.Tree as CommonTree;
Print(tree, "");
Console.Read();
}
static void Print(CommonTree tree, string indent)
{ …Run Code Online (Sandbox Code Playgroud) 我需要解析一个小的表达式语言(并且,或者,不是,parens改变优先级)所以选择了ANTLR来完成任务,我取得了很好的进展(ANTLRWorks非常适合新手).我在antlr网站上使用了一些Getting Starting引用,然后找到两篇完全适合我想要完成的内容的博客文章:
http://www.codeproject.com/KB/recipes/sota_expression_evaluator.aspx http://www.alittlemadness.com/2006/06/05/antlr-by-example-part-1-the-language
我遇到的问题是无论我输入什么输入我总是得到错误:
第1:29行输入'EOF'没有可行的选择
因此,作为我的故障排除的一部分,我决定尝试一种我知道很好的语法,并从第一个链接中找到的ECalc.g语法生成一个词法分析器/解析器.令我惊讶的是,在使用该语法时我遇到了同样的错误!我很生气.我对语法的唯一改变是让它生成Java代码并在@members部分中取出一些CSharp代码.
这是我的测试类:
public class ECalcTester {
private final static Logger logger = Logger.getLogger(ECalcTester.class);
public static void main(String[] args) {
BasicConfigurator.configure();
ECalcLexer lex = new ECalcLexer(new ANTLRStringStream("false || not (false and true)"));
Token token;
while (true) {
token = lex.nextToken();
if (token.getType() == Token.EOF) {
break;
}
System.out.println("Token: ‘" + token.getText() + "’");
}
CommonTokenStream tokens = new CommonTokenStream(lex);
lex.nextToken();
ECalcParser parser = new ECalcParser(tokens);
try {
logger.debug(parser.expression().getTree());
} catch (org.antlr.runtime.RecognitionException e) {
logger.error("Exception ", …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用ANTLR为使用C#代码生成的简单语言创建解析器.
我已成功地使用名为"rule"的非常简单的规则来生产MyLangLexer.cs和MyLangParser.cs.
问题是生成的方法rule()是私有的.
我想要的是使用ANTLR将字符串解析为AST.
谢谢,Ido.
这是一个简单的规则:
NAME : 'name1' | 'name2' | 'name3';
Run Code Online (Sandbox Code Playgroud)
是否可以使用包含字符串的数组动态地为此类规则提供替代方案?
我为字符串变量声明编写了以下语法.字符串定义为单引号之间的任何内容,但必须有一种方法通过使用$ letter 转义将单引号添加到字符串值.
grammar test;
options
{
language = Java;
}
tokens
{
VAR = 'VAR';
END_VAR = 'END_VAR';
}
var_declaration: VAR string_type_declaration END_VAR EOF;
string_type_declaration: identifier ':=' string;
identifier: ID;
string: STRING_VALUE;
STRING_VALUE: '\'' ('$\''|.)* '\'';
ID: LETTER+;
WSFULL:(' ') {$channel=HIDDEN;};
fragment LETTER: (('a'..'z') | ('A'..'Z'));
Run Code Online (Sandbox Code Playgroud)
如果您尝试为var_declaration规则运行此代码,则此语法不起作用:
VAR A :='$12.2' END_VAR
Run Code Online (Sandbox Code Playgroud)
我得到MismatchedTokenException.
但是这个代码适用于string_type_declaration规则:
A :='$12.2'
Run Code Online (Sandbox Code Playgroud) 我正在编写一个小的csharp控制台应用程序,它从控制台读取文本,做一些操作并返回一个字符串.为此,我使用的是Antlr.语法文件如下所示.
grammar test;
options {
language = CSharp2;
output = AST;
}
start returns [String res]: expression EOF
{
$res=$expression.res;
} ;
expression returns [String res]
: Identifier {$res=$Identifier.text}
|Num {$res=$num.text;
|function {$res=function.res}
;
function: 'left' '( Identifier ')'{some code here}
| 'right' '( Identifier ')'{some code here}
|..........
;
Num : (Minus)?('0'..'9')+ ;
Identifier : ('a'..'z'|'A'..'Z'|'\\'|'/'|'_'|':'|';'|'?'|'.'|'0'..'9')('a'..'z'|'A'..'Z'|'\\'|'/'|'_'|':'|';'|'.'|'?'|'0'..'9')*;
Run Code Online (Sandbox Code Playgroud)
我有几个这样的函数,它们进行一些字符串操作.现在,我希望Antlr无论如何都能识别这些函数名称.目前,它只接受小写字母作为函数名称,例如.. upper(asdf).我无法在我的应用程序中将每个标记转换为小写,因为它也会更改标识符的大小写.我怎样才能做到这一点?
是否可以使用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. …
我是ANTLR的新手.我开始探索ANTLR教程.我已经看到了为特定规则定义了返回类型的示例(参见下面的示例).
我也可以将争论传递给统治吗?我只是想到了,我想根据提供给它的论点改变一个微观状态的规则行为.
如果它在ANTLR中可以通过,请帮帮我,还是这样做是个好主意?
atom returns [int value]
:
INT
{
$value = Integer.parseInt($INT.text);
}
| ID // variable reference
{
Integer v = (Integer) memory.get($ID.text);
if (v != null)
$value = v.intValue();
}
;
Run Code Online (Sandbox Code Playgroud) 我想将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)