Well, I just did a little test with a "plain" ANTLR version, and everything went just fine.
Here's what I did:
1 new Android project
Create a new project called AndAbac
(Android-Abacus) with a package named bk.andabac
and an activity called AndAbac
.
2 create a grammar
Create a grammar file called Exp.g
(explanation here) anywhere on your system and paste the following in it:
grammar Exp;
@parser::header {
package bk.andabac;
}
@lexer::header {
package bk.andabac;
}
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
: (' ' | '' | '
'| '
') {$channel=HIDDEN;}
;
3 download ANTLR & generate lexer/parser
Download ANTLR here: http://www.antlr3.org/download/antlr-3.3-complete.jar and put it in the same directory as your Exp.g
file. Generate a lexer and parser (explanation here) and copy the generated .java
files to the following folder in your Android project: src/bk/andabac
. Also put this ANTLR jar to the classpath of your Android project.
4 change some project files
Paste the following in res/layout/main.xml
:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<EditText
android:id="@+id/input_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="5 * (8 + 2)"
/>
<Button
android:id="@+id/parse_button"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:text="eval" />
<TextView
android:id="@+id/output_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text=""
/>
</LinearLayout>
and the following in src/bk/andabac/AndAbac.java
:
package bk.andabac;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.RecognitionException;
public class AndAbac extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.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 ANTLRStringStream(source));
ExpParser parser = new ExpParser(new CommonTokenStream(lexer));
try {
out.setText(source + " = " + parser.eval());
}
catch (RecognitionException e) {
out.setText("Oops: " + e.getMessage());
}
}
});
}
}
5 test the app
Either run the project in an emulator, or create an APK file and install this on an Android device (I tested both, and both worked). You will see the following after pressing the eval button:
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…