0

I have this grammar:

grammar PrimeGrammar;

options
{
    backtrack=true;
    language = CSharp3;
    memoize=true;
}

@parser::header
{
    using System;
}

@parser::members 
{
    public int[] ObjInput = new int[]{1,2,3,4,5,6,7,8,9,10,11,12,13};

    private int CurrObj()               //current object
    {
        int id =  ((CommonTokenStream)InputStream).Lt(1).TokenIndex;
        return ObjInput[id];
    }

    private bool isPrime()
    {
        int number = CurrObj();

        int boundary = (int)Math.Floor(Math.Sqrt(number));

        if (number == 1) return false;
        if (number == 2) return true;

        for (int i = 2; i <= boundary; ++i)  {
            if (number % i == 0)  return false;
        }

        return true;
    }

    private bool isEven()
    {
        int number = CurrObj();

        return number % 2 == 0;
    }
}

parse                   : anyObj*;

////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////RULEs SECTIONs///////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////

anyObj                  : primeSequence
                        | evenSequence
                        | OBJ
                        ;

////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////Prime Section////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////

prime                   : {isPrime()}? OBJ;
primeSequence           : prime (OBJ prime)+;

////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////Even Section/////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////

even                    : {isEven()}? OBJ;
evenSequence            : even (OBJ even)+;

OBJ                     : .;

It is simply Object-Related grammar, what can parse int objects instead of characters or built-in tokens. (ObjInput is array of objects in this case) To run example you just send Parser same amount of tokens what laying inside of ObjInput field.

So, before parse I just set this array and run my top rule on same amount of any junk tokens. But there is a problem: if rule with predicate fails, backtrack won't happen and state machine just goes on until reaches end...

How to force ANTLR to go to previous successful state if predicate fails? And i think backtrack-option in C# is just broken, cause this grammar working perfectly in ANTLRWorks if I rewrite this on Java.

Any ideas? What I can do instead of writing a bunch of lookahed instructions?

eocron
  • 6,885
  • 1
  • 21
  • 50
  • ANTLR 4 no longer uses such features (backtrack nor predicates). You should study what's changed between ANTLR 3 and 4. Then such questions will be answered automatically. I happened to write a blog post a few months ago, https://blog.lextudio.com/2014/08/how-to-use-antlr-4-on-net/ – Lex Li Jan 19 '16 at 13:24
  • Well, this is very very sad. ANTLR 4 loses ability to parse complex objects. – eocron Jan 20 '16 at 07:24
  • I wrote that post after migrating a commercial product to v4. So I don't think your claim of "complex objects" is really a road blocker of using v4. – Lex Li Jan 20 '16 at 10:33
  • It is. Now you can't encode complex object's with predicates. I mean, for example, create token prime on virtual character to deceive antlr and parse it like character on need. Of course you can compute this before passing but this is just not optimal solution. – eocron Jan 20 '16 at 12:29

0 Answers0