2

I've been trying to make the answer given to this question work for ANTLR4 on Android. I've made certain to add the right Java files and added the jar to the project, but it's not showing me the result to the input. Once I click on the 'eval' button on my device the output is this

5 * (8 + 2) equals []

The only changes I've done were to the grammar and import methods to make them work on ANTLR4.

Here's the grammar (Exp.g4) code:

grammar Exp;

@parser::header {
  package bk.andabac2;
}

@lexer::header {
  package bk.andabac2;
}

eval returns [double value]
 : exp=additionExp {$value = $exp.value;}
 ;

additionExp returns [double value]
 : m1=multiplyExp       {$value =  $m1.value;} 
   ( '+' m2=multiplyExp {$value += $m2.value;} 
   | '-' m2=multiplyExp {$value -= $m2.value;}
   )* 
 ;

multiplyExp returns [double value]
 : a1=atomExp       {$value =  $a1.value;}
   ( '*' a2=atomExp {$value *= $a2.value;} 
   | '/' a2=atomExp {$value /= $a2.value;}
   )* 
 ;

atomExp returns [double value]
 : n=Number                {$value = Double.parseDouble($n.text);}
 | '(' exp=additionExp ')' {$value = $exp.value;}
 ;

Number
 : ('0'..'9')+ ('.' ('0'..'9')+)?
 ;

WS  
 : (' ' | '\t' | '\r'| '\n') {skip();}
 ;

And my MainActivity.java code in Eclipse:

package bk.andabac2;

import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.RecognitionException;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        final Button button = (Button)findViewById(R.id.parse_button);

        button.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {

                EditText in = (EditText)findViewById(R.id.input_text);
                TextView out = (TextView)findViewById(R.id.output_text);

                String source = in.getText().toString();
                ExpLexer lexer = new ExpLexer(new ANTLRInputStream(source));
                ExpParser parser = new ExpParser(new CommonTokenStream(lexer));

                try {
                    out.setText(source + " evalúa a " + parser.eval());
                }
                catch (RecognitionException e) {
                    out.setText("Oops: " + e.getMessage());
                }
            }
        });
    }

}

What I get in the logs is the following messages about the TreeViewer class:

Unable to resolve superclass of Lorg/antlr/v4/runtime/tree/gui/TreeViewer; (763)
Link of class 'Lorg/antlr/v4/runtime/tree/gui/TreeViewer;' failed
Could not find class 'org.antlr.v4.runtime.tree.gui.TreeViewer', referenced from method org.antlr.v4.runtime.RuleContext.inspect
VFY: unable to resolve new-instance 1351 (Lorg/antlr/v4/runtime/tree/gui/TreeViewer;) in Lorg/antlr/v4/runtime/RuleContext;
VFY: replacing opcode 0x22 at 0x0000
Unable to resolve superclass of Lorg/antlr/v4/runtime/tree/gui/TreeViewer; (763)
Link of class 'Lorg/antlr/v4/runtime/tree/gui/TreeViewer;' failed
DexOpt: unable to opt direct call 0x21be at 0x02 in Lorg/antlr/v4/runtime/RuleContext;.inspect
Community
  • 1
  • 1
Ralvr
  • 21
  • 1
  • 3

2 Answers2

0

I'm running into the same types of problems. It appears that antlr runtime is normally built for use as a java application with access to javax.swing libraries. These don't exist on android.
So my strategy would be to rebuild the antlr 4 runtime, and takeout any javax.swing related library references.

I recently created a branch for antlr4 on github here to support android: https://github.com/jkalkhof/antlr4/tree/4.0-android

  • I recently created a branch for antlr4 on github here to support android: https://github.com/jkalkhof/antlr4/tree/4.0-android – user3011237 Oct 09 '14 at 18:04
0

Here is how you can create an Android compatible ANTLR4 runtime library:

1. First clone ANTLR4:

git clone https://github.com/antlr/antlr4.git
cd antlr4

2. Checkout tag 4.3 (or another version):

git checkout 4.3

3. Remove the entire gui package:

rm -rf runtime/Java/src/org/antlr/v4/runtime/tree/gui

4. Fix compiler error in the classes that contain gui classes:

  • runtime/Java/src/org/antlr/v4/runtime/RuleContext.java
  • runtime/Java/src/org/antlr/v4/runtime/tree/Trees.java

5. Build the project by doing:

mvn clean install -DskipTests=true

6. Copy the runtime library into the Android project:

cp runtime/Java/target/antlr4-runtime-4.3.jar /your/android/project/app/libs

I've also created a small Android App that uses this library. Find it in this GitHub repo: https://github.com/bkiers/antlr4android

Bart Kiers
  • 166,582
  • 36
  • 299
  • 288