标签: antlr3

在ANTLR中生成简单AST

我正在玩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)

antlr abstract-syntax-tree antlrworks antlr3

2
推荐指数
1
解决办法
3165
查看次数

所有ANTLR语法都会产生错误"在输入'<EOF>'时没有可行的替代方法"

我需要解析一个小的表达式语言(并且,或者,不是,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)

parsing antlr antlr3

2
推荐指数
1
解决办法
4381
查看次数

用于解析规则的C#产品私有方法的ANTLR

我正在尝试使用ANTLR为使用C#代码生成的简单语言创建解析器.

我已成功地使用名为"rule"的非常简单的规则来生产MyLangLexer.cs和MyLangParser.cs.

问题是生成的方法rule()是私有的.

我想要的是使用ANTLR将字符串解析为AST.

谢谢,Ido.

c# antlr antlr3

2
推荐指数
1
解决办法
225
查看次数

动态创建词法分析器规则

这是一个简单的规则:

NAME : 'name1' | 'name2' | 'name3';
Run Code Online (Sandbox Code Playgroud)

是否可以使用包含字符串的数组动态地为此类规则提供替代方案?

grammar antlr antlr3 antlr4

2
推荐指数
1
解决办法
2059
查看次数

ANTLR词法分析器中的特殊字符处理

我为字符串变量声明编写了以下语法.字符串定义为单引号之间的任何内容,但必须有一种方法通过使用$ 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)

antlr antlr3

2
推荐指数
1
解决办法
4687
查看次数

使一些解析器规则在antlr中不区分大小写

我正在编写一个小的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).我无法在我的应用程序中将每个标记转换为小写,因为它也会更改标识符的大小写.我怎样才能做到这一点?

antlr antlr3

2
推荐指数
1
解决办法
2503
查看次数

从ANTLR4解析器获取第一个并遵循元数据

是否可以使用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. …

antlr3 antlr4

2
推荐指数
1
解决办法
1347
查看次数

ANTLR:带参数的规则?

我是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)

java antlr antlr3

2
推荐指数
1
解决办法
2924
查看次数

Python + ANTLR4:没有名为antlr4的模块

我想将ANTLR4与Python 2.7结合使用,为此,我做了以下工作:

  1. antlr4-4.6-1使用sudo pacman -S antlr4。将软件包安装在Arch Linux上。

  2. 我写了一个MyGrammar.g4文件,并成功生成了Lexer和Parser Codeantlr4 -Dlanguage=Python2 MyGrammar.g4

  3. 现在执行例如生成的Lexer代码并python2 MyGrammarLexer.py导致错误ImportError: No module named antlr4

可能是什么问题?仅供参考:我同时安装了Python2和Python3-我不知道这是否会造成任何麻烦。

python antlr python-import antlr3 antlr4

2
推荐指数
1
解决办法
4857
查看次数

ANTLR4:零或一倍

我正在使用ANTLR4和Java定义语法。对于Integers,我想要一个以减号开头的数字。我知道可以这样做:

integer: '-' (DIGIT)* | DIGIT* ;
Run Code Online (Sandbox Code Playgroud)

但是我想知道是否有一个符号(类似于*)来确保减号出现零或一次:

integer: ('-')<some symbol here> (DIGIT)* ;
Run Code Online (Sandbox Code Playgroud)

grammar antlr antlr3 antlr4

2
推荐指数
1
解决办法
1552
查看次数