I'd like to know how:
return a runtime value from a rule action
access that value from the parent rule's action.
With ANTLR I want to build a custom tree using actions (not listeners/visitors which are too complex). And I'd like to have a parser implementation where each action knows about its children but not about its parent.
It is possible to access parent action's $variables but instead I'd like to access runtime values returned from children (and I don't know how).
For example with Ruby's treetop I can build a custom tree like below. Is this approach available for ANTLR too?
// sample input: "hello joe"
grammar Test
rule greeting
'hello' name {
// here `name.value` returns an instance of Name (below)
return new Greeting(name.value)
}
end
rule name
ID {
return new Name(ID.text)
}
end
It is possible to (pseudo) return a custom value from action via assigning a special field which can be accessed from outside then:
greeting returns [MyGreeting value] : 'hello' name
{
$value = new MyGreeting();
System.out.println("statement with name " + $name.value); // accessing
};
name returns [MyName value] : ID
{
$value = new MyName(); // assigning
System.out.println("name...");
};
I tried to set value in TextView using my array logic.
Problem:
Instead of my actual value it might set address of string in
textview. I'm guessing this issue is simple, possibly not specifying .toString()?
Value that is being outputted:
com.android.carModel.Car#eacea24f
My code:
StringBuilder builder = new StringBuilder();
val = carDAO.carOutput(carId);
textbx.setText("");
for (Car details : val){
builder.append(details + "\n");
}
textbx.setText(builder.toString());
Your code is actually append someObjectClassname#hashcodenumber i.e com.android.carModel.Car#eacea24f in your case to stringBuilder. To get the desired output you need to do something like this.
`builder.append(details.getName() /*or anything*/ + "\n")`
Do you have access to the Car class? If so, add this method:
public String toString() {
return carName;
}
Replace carName with whatever you want to display. This toString() method is part of the Object class that all classes extend, and when overridden, it will change what something like a List will display.
I have an implementation where when user click on checkbox , a json gets associated as value of checkbox and that value is passed to my bean class.
And In the method invoked, the String is then parsed into JSON object.
When I select two checkbox, it works perfectly fine. But if I select one checkbox, then it gives me error.
Here is my Checkbox Bean class -
private ArrayList<String> Ancillary=new ArrayList<String>() ;
public ArrayList<String> getAncillary() {
for(int i=0;i<Ancillary.size();i++){
System.out.println(i+"Object:" +Ancillary.get(i)+"\n\n\n");
}
return Ancillary;
}
public void setAncillary(ArrayList<String> ancillary) {
Ancillary = ancillary;
}
Here is my method where I print value of a Particular key in JSON.
public Event updatePax(RequestContext context) throws Exception {
ExtrasMenu extrasMenu = (ExtrasMenu) context.getConversationScope().get(ScopeKeys.EXTRASMENU);
System.out.println("As a string:"+extrasMenu.getAncillary().toString());
JSONObject json=new JSONObject(extrasMenu.getAncillary().get(0));
System.out.println(json.get("firstName"));
}
And here is the Output-
If only one checkbox is selected -
0Object:{"firstName":"TIMOTHY"
1Object:"lastName":"WALKER"
2Object:"price":100}
If two or more checkboxes are selected -
0Object:{"firstName":"TIMOTHY","lastname":"WALKER","price":"50"}
1Object:{"firstName":"ANNE","lastname":"WALKER","price":"150"}
Since, I couldnt figure out why ArrayList is taking input like this,
I created a special case when User selects one check box. I will take the ArrayList and convert it to a String using toString.
So, the output of toString will be like -
{"firstName":"TIMOTHY","lastname":"WALKER","price":"50"}
Now I used a try catch block to create JSON object out of the string I get from toString.
JSONObject json=null;
try{
json=new JSONObject(extrasMenu.getAncillary().get(i));
}
catch(org.json.JSONException e){
int len=extrasMenu.getAncillary().toString().length();
json=new JSONObject(extrasMenu.getAncillary().toString());
}
So If it throws an error, the full list as a string will be used to create JSON object.
Although It is working fine, Still I am not very sure about Why ArrayList is working like this !
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I am fairly new to Java proramming, as I have already stated in the title I want to pass some parameters that could or could not exist as instances of a class. If it does not exist, I want to create it. My code so far:
public class TestClass {
public static void main(String[] args) {
Person Ted = new Person();
Person Jack = new Person();
Item it = new Item(Ted);
Item itSec = new Item (Pierce); //Person Pierce doesn't exist => should be created
}
}
public class Person {
public Person(){
//some code
}
}
public class Item {
public Item(Person name){
if(!(name instanceof Person)){
Person name = new Person(); //create that missing instance
}
else{
//some code
}
void getItem(Person name){
System.out.println(name);
}
}
You misunderstand some things.
You can't use an identifier before it's been declared. The following is not correct in your code:
Item itSec = new Item (Pierce);
That's because you didn't declare Pierce before this line. You don't have to create an instance of the class, but you need a valid identifier. You should have declared it before this way:
Person Pierce;
At this moment the identifier, or the reference, is empty, so to say, or it is equal null. All object references which are not local are initiated this way, or they are equal false or 0, whichever is correct for their type. The result is the same as if you declared explicitly:
Person Pierce = null;
But let's move on. Say the reference has been declared. (Btw, Java uses camelCaseNotation for variables, so pierce would be correct.) Let's say we're at a point when Pierce is null or refers to some object, we don't know. Now we call this:
Item itSec = new Item (Pierce);
new Item(Pierce) calls the constructor public Item(Person name){...} in the class Item, which you should know. But now, in that constructor there's the line:
if(!(name instanceof Person)){
which you misuse. What this line is checking is not if the variable name equals null or an existing object, but variable type of name is a subtype of Person. Which will always return true in this place, as the function heading public Item(Person name){...} says this: the function is public, is a constructor, and the argument is of type Person (so Person or a subtype).
What you want to say here is this:
public Item(Person name){
if(name==null)){ //if the reference is empty
this.name = new Person(); //I'll explain this below
}
else{
this.name = name; //otherwise the local "name" will stay null
}
}
I used this.name and it was a jump ahead. Why? In your code that is Person name = ..., which is not correct as that name wouldn't last once the constructor's finished. You need a field in the Item class object, which will hold this value. So the Item class might be defined this way:
public class Item {
Person name;
//...
}
And now the field name holds the value assigned in the line:
this.name = new Person();
You need to use this to disambiguate which name you means. One is the Item class field, the other one is Person name the constructor parameter.
Now, we go back to the main function. If you want the variable Pierce to reference the newly created Person, this still needs to be done. The assignment can take place here, but first you'd have to create a function in the class Item that returns the value of its field name. So:
getName() {
return name;
}
And now call it from the main function:
Pierce = itSec.getName();
That's it. Finally, this function doesn't make sense:
void getItem(Person name){
System.out.println(name);
}
}
It doesn't get any Item. It only prints what you pass to it. And this doesn't mean that if you call it with getItem(Pierce), you will see "Pierce" on the screen. It will call the toString function in the object Pierce denotes, and as it is, you will get a standard object identifier. But if you define a function:
void printItem() {
System.out.println(name);
}
Then you can call it this way. For an existing object itSec:
itSec.printItem();
As for a getter function, it should return what you ask for, but that's another story.
What do you expect without instancing?
Person Pierce = new Person();
Item itSec = new Item (Pierce);
You cannot use a variable that does not exist...
Item itSec = new Item (Pierce);
The snippet above will never work because Pierce is undefined.
The code:
if(!(name instanceof Person)){
Person name = new Person(); //create that missing instance
}
Does not really make any sense, because that is the same as calling
Person Ted = new Person();
Person Jack = new Person();
Wherein the Person instance does not actually contain any data (unless you have some magic going on when instantiating the Person!)
I assume what you really want to pass is not an object whose variable is the name of a person, but rather a Person object that contains the name of the person.
If so, your code should be like this:
Person p1 = new Person("Ted");
Person p2 = new Person("Jack");
If you really want to do some instantiation if something does not exist, you might be able to do something like this:
Item(String personName) {
if(isExisting(personName)) {
getPerson(personName);
} else {
Person p = new Person(personName);
}
boolean isExisting(String personName) {
// Check if person exists somewhere
}
Person getPerson(String personName) {
// Retrieve the Person instance with the same person name.
}
if(!(name instanceof Person)){
Person name = new Person();
}
is meaning less because 'name' is always object is instance of person in this situation..
Item itSec = new Item (Pierce);
Pierce is not an object.. We can pass only Person object to constructor of Item class.. There is no any method to create an object of any class by just passing unkown variable..
Item itSec = new Item (Pierce); //Person Pierce doesn't exist => should be created
If it does not exist, I want to create it.
There's no "if" about it. The code never declared that variable, so it will never exist. (And never compile in its current state. Surely your Java compiler is telling you this.) Given that it always needs to be created, just create it:
Person Pierce = new Person();
Item itSec = new Item(Pierce);
Edit: Based on ongoing comments, it sounds like you want to have something more like a Map. Consider an example:
Map<String,Person> people = new HashMap<String,Person>();
people.put("Pierce", new Person());
The Map would basically be a collection of key/value pairs where the name is the key and the Person is the value. You can dynamically add/edit/remove elements to the collection as you see fit.
Then to use it, you'd call another operation on the map:
Item itSec = new Item(people.get("Pierce"));
You could use various operations to check if a value exists in the collection, add it, etc. You might even extend the class to add your own operations which create one if it doesn't exist when trying to get it.
Java won't dynamically create variables for you if a variable doesn't exist, but operations on a Map (or potentially other similar structures) can check if an element exists, add it, remove it, etc.
For the following class I want to access an object if the name equals to something, let's say "you". Otherwise I want to create it.
I want to check if an object exists that has the name as 'you' and then add entries to the ArrayList contInstances. If such an instance doesn't already exist I want to create it. Next time I might have to use the same object so that I can add some more entries to the ArrayList.
public class Values {
String name;
ArrayList<anotherClass> classInstances = new ArrayList<anotherClass>();
}
This happens to be in a loop. How can I do that?
Edit: I'll quote an example here:
if (an object exists that contains field 'name' == 'YOU'){
add entries to the array list directly using the available object
}
else {
create a new object and set the 'name' = 'YOU';
add entries to the array list;
}
It sounds kind of like you want to have a cache by name. Instead of an ArrayList, consider using a Map<String, AnotherClass> to keep track of Name->Object mappings.
You can then use this approach:
Map<String, AnotherClass> instances = new LinkedHashMap<String, AnotherClass>();
for (...) {
String name = getNextName();
AnotherClass instance = instances.get(name);
if (instance == null) {
instance = makeInstance(name);
instances.put(name, instance);
}
useInstance(name, instance);
}
After that loop is finished, if you still want a List<AnotherClass>, you can use return new ArrayList<AnotherClass>(instances.values());