Java JDT UI: How to infix expression from a VariableDeclarationStatement - java

I have been stuck on a particular problem that is to extract an infixexpression from a VariableDeclarationStatement. for example:
String s = 'a'+'b'+'c';
This is an instance of VariableDeclarationStatement. and i need to get the infixexpression 'a'+'b'+'c' out of it.
I have tried : 1.Tried converting to string.But no conversion back is possible.
2.Tried converting to list but still not possible.
I have tried above methods to try and manipulate and extract InfixExpression out of it.Please help me.
EDIT
here is what i have done :
if (node instanceof InfixExpression) {
infixExpression= (InfixExpression) node;
} else if (node.getParent() instanceof InfixExpression) {
infixExpression= (InfixExpression) node.getParent();
} else { //while trying to get this proposal with spaces its reaching here.
String nodeString =node.toString();
String infixExp="s";
int t;
for (t=0;nodeString.charAt(t)!='=';t++);
infixExp.concat(nodeString.substring(t+1, nodeString.length()));
infixExpression = (InfixExpression)infixExp; //this cast doesn't work here
}

Its still unclear what you want to do.
public class InfixVisitor extends ASTVisitor {
#Override
public boolean visit(InfixExpression node) {
// NOTE: node.toString() should only be used debugging.
// Probably you could use it anyway.
...
return super.visit(node);
}
}
With above visitor you can access all InfixExpression nodes with e.g.:
ASTNode sourceNode = ...
sourceNode.accept(new InfixVisitor());

Related

Highlight text from jdt java text editor using line numbers in eclipse plugin

I am trying to write an eclipse plugin which highlights some text in java editor after user save the text (ResourceChangeListener). I am implementing ILightweightLabelDecorator and extending BaseLabelProvider, The method
public void decorate(Object arg0, IDecoration arg1)
getting called but I am getting Objects of type org.eclipse.jdt.internal.core.*
e.g org.eclipse.jdt.internal.core.PackageDeclaration.
I need line numbers from that object so I can highlight that text.
ASTNode object has a property to get the position (line numbers) but I am not getting that one. How can I get ASTNode from org.eclipse.jdt.internal.core.*
objects?
Thanks in advance.
PackageDeclaration is part of the JDT Java Model which is a lighter weight version of the AST used by a lot of the Java code. As such it isn't related to ASTNode.
Many Java Model objects (including PackageDeclaration) implement ISourceReference which tells you about the source code. This includes getSource and getSourceRange methods.
We can use the following method for accessing line number,
private int getLineNumberInSource(SourceRefElement member) throws
JavaModelException {
if (member == null || !member.exists()) {
return -1;
}
ICompilationUnit compilationUnit = member.getCompilationUnit();
if (compilationUnit == null) {
return -1;
}
String fullSource = compilationUnit.getBuffer().getContents();
if (fullSource == null) {
return -1;
}
ISourceRange nameRange = member.getNameRange();
if (nameRange == null) {
return -1;
}
String string2 = fullSource.substring(0, nameRange.getOffset());
return
string2.split(compilationUnit.findRecommendedLineSeparator()).length;
}

Ternary string to Node class

I have an interview question that still kills my mind, please help.
You have to write a method in Java with a String parameter.
That String should be a tree of ternary operators (a?b:c). So basically it can be something like:a? g?h:j ? u?v:w : p : r?s:t
a
/ \
g?h:j r?s:t
/ \
u?v:w p
Something like that, I hope I even wrote it right, because I am really confused.
Then we have a class Node that has 2 fields: left and right:
class Node {
char variableName;
Node left, right;
}
So you have to return a Node with all the Nodes(left, right) from that String.
I hope this is understandable. If you need more information I will provide, but the basic idea here is to get all the nodes right. I was trying to do this using recursion and I still believe that this is right. But I cannot figure out how to do it right.
This question can be solved with a very simple recursive descent parser. The intention behind asking this question is to see if you can implement a recursive algorithm where recursion makes sense, as opposed to asking you to code up a boring recursive factorial to see if you have heard of recursion before.
Here is one possible implementation:
static class Parser {
private int pos = 0;
private String s;
public Parser(String s) {
this.s = s;
}
private void skipSpace() {
while (pos != s.length() && Character.isWhitespace(s.charAt(pos))) {
pos++;
}
}
public Node parse() {
skipSpace();
Node res = new Node();
res.variableName = s.charAt(pos++);
skipSpace();
if (pos == s.length()) return res;
if (s.charAt(pos) == '?') {
pos++;
res.left = parse();
skipSpace();
if (pos == s.length() || s.charAt(pos) != ':') {
System.err.println("Syntax error");
return null;
}
pos++;
res.right = parse();
}
return res;
}
}
public static Node parse(String s) {
Parser p = new Parser(s);
return p.parse();
}
Demo.
The idea is to use parse() method as if it's already written: first we parse the variable name, then we check if it is followed by a question mark. If it is, we consume the question mark, parse from the current position what becomes our left node, skip the colon (or error out if the colon is missing), and finally parse the right node. Skip whitespace as you go.

Stackoverflow error when recursively searching in a tree

I am implementing the Shannon/Fano algorithm using Java and I am doing this by calculating the frequencies of symbols in a text file, and after that I put all these values in a tree. The problem is that when I am searching for a certain symbol in a tree I also have to update the code of the respective symbol (e.g If I go to left append 0, otherwise 1) and doing this recursively I am getting a stackoverflow error. Below is my code :
private String getNodeValue(Node node, String symbol) {
if (node.getLeftChild() != null) {
if (node.getLeftChild().getData().equalsIgnoreCase(symbol)) {
node.updateCode(0);
return node.getData() + "";
}
} else if (node.getRightChild() != null) {
if (node.getRightChild().getData().equalsIgnoreCase(symbol)) {
node.updateCode(1);
return node.getData() + "";
}
}
Node nextLeftNode = node.getLeftChild().getLeftChild();
if (nextLeftNode != null) {
getNodeValue(nextLeftNode, symbol);
}
Node nextRightNode = node.getRightChild().getRightChild();
if (nextRightNode != null) {
getNodeValue(nextRightNode, symbol);
}
// if symbol is not found return null
return null;
}
and the stackoverflow error is triggered at the very first line of the method when the call to node.getData() takes place. This is my stack trace:
Exception in thread "main" java.lang.StackOverflowError
at ro.uvt.it.datastractures.Node.getData(Node.java:47)
at ro.uvt.it.datastractures.Node.getData(Node.java:47)
at ro.uvt.it.datastractures.Node.getData(Node.java:47)
And this is my getData() method:
public String getData() {
return this.getData();
}
Any help or hint would be appreciated,
Thank you.
There are many mistakes in your code.
As you showed in your stacktrace, the infinite recursion is in the getData method and not in the getNodeValue method, so you need to post the source code of the getData method.
But the getNodeValue method has many bugs as well.
Your first two if statements have exactly the same condition:
if (node.getData().equalsIgnoreCase(symbol)) {
and
else if (((String) node.getData()).equalsIgnoreCase(symbol)) {
the returns inside these if statements append an empty string to the result of getData(), which already returns String. Replace each of them with:
return node.getData();
are just a different way of writing the same, since getData() already returns a String so casting to String again doesn't make a difference.
Your next to if statements recursively call getNodeValue on leftChild and rightChild, but they never return anything, so you always end up returning null in your code once you're past the first two identical if statements in your method.
You code should probably read:
if (node.getLeftChild() != null) {
String found = getNodeValue(node.getLeftChild(), symbol);
if (found != null) {
return found;
}
}
if (node.getRightChild() != null) {
String found = getNodeValue(node.getRightChild(), symbol);
if (found != null) {
return found;
}
}
Almost certainly unbounded recursion. At a guess I'd say it was a mistake in the implementation of getLeftChild or getRightChild. I would suggest you step through in the debugger, and I'll bet you will quickly see where this goes.
However, if you have a very deep tree, you may discover that the stack overflow exception is legitimate, in which case you will need to revisit the algorithm. And the traditional technique of tail recursion appears to be hard to achieve in Java.

HTML Well-formedness parser

Heyy guys, I need to determine if a given HTML Document is well formed or not.
I just need a simple implementation using only Java core API classes i.e. no third party stuff like JTIDY or something.
Actually, what is exactly needed is an algorithm that scans a list of TAGS. If it finds an open tag, and the next tag isn't its corresponding close tag, then it should be another open tag which in turn should have its close tag as the next tag, and if not it should be another open tag and then its corresponding close tag next, and the close tags of the previous open tags in reverse order coming one after the other on the list. If the list conforms to this order then it returns true or else false. I've already written methods to convert a tag to a close tag.
Here is the skeleton code of what I've started working on already. Its not too neat, but it should give you guys a basic idea of what I'm trying to do.
public boolean validateHtml(){
ArrayList<String> tags = fetchTags();
//fetchTags returns this [<html>, <head>, <title>, </title>, </head>, <body>, <h1>, </h1>, </body>, </html>]
//I create another ArrayList to store tags that I haven't found its corresponding close tag yet
ArrayList<String> unclosedTags = new ArrayList<String>();
String temp;
for (int i = 0; i < tags.size(); i++) {
temp = tags.get(i);
if(!tags.get(i+1).equals(TagOperations.convertToCloseTag(tags.get(i)))){
unclosedTags.add(tags.get(i));
if(){
}
}else{
return true;//well formed html
}
}
return true;
}
Two thoughts. First off maybe you could get away with using an XML parser on the html? Potentially easier and vastly less time consuming.
I havn't put a whole lot of thought into this but to me it sounds like recursion and stack would be the way to go. Something like
public myClass(String htmlInput)
{
openedTags = new Stack<String>();
this.htmlInput = htmlInput;
}
public boolean validate()
{
return validate(this.htmlInput);
}
private boolean validate(String html)
{
boolean result = true;
String curTag;
while(htmlLeft) //worker loop
{
if(isOneOffTag(curTag)) //matches <tags />
continue;
else if(isOpenTag(curTag)) //matches <tags>
{
openedTags.push(curTag);
if(!validate(innerHtml))
return false;
}
else if(isCloseTag(curTag)) //matches </tags>
{
String lastTag = (String)openedTags.peek();
if(!tagIsSimiliar(curTag, lastTag))
return false;
openedTags.pop();
}
}
return result;
}
private String nextTag(){return null;}
private boolean isOpenTag(String tag){ return true;}
private boolean isCloseTag(String tag){ return true;}
private boolean isOneOffTag(String tag){ return true;}
private boolean tagIsSimiliar(String curTag, String lastTag){return true;}
*edit 1: probably should have pushed onto the stack.
**edit 2: I suppose the issue here would be to determine where when returning solely a boolean you've left off. This would require some kind of pointer so that you know where you've left off. The idea though i believe would still work.

how to instance a non-static method, that has a wired object and is from another file

I'm having trouble calling a non-static method from an another file. My main file is called jroff.java, and the other file (which has the two methods I need) is called linkedqueue.java
In linkedqueue.java I have the following code:
class linkedqueue <item_t> {
private class node{
item_t item;
node link;
}
private node front = null;
private node rear = null;
public boolean empty (){
return front == null;
}
public void insert (item_t any) {
node temp = new node();
temp.item = any;
temp.link = null;
if(rear == null) front = temp;
else rear.link = temp;
rear = temp;
}
public item_t remove (){
item_t value;
if (empty ()) throw new NoSuchElementException ();
value = front.item;
front = front.link;
if(front == null) return null;
else return value;
}
}
this is how i'm trying to run insert in my main file:
for (String word: words) linkedqueue.insert(word);
I got the file name thing right, but how exactly do I make an instance of something like this?
Here is where I use insert:
String value;
while(value != null){
value = linkedqueue.remove().toString();
remove returns a item_t, and i want that in a string. the last node will have a value of null, thats when the loop should stop.
Thanks for the help.
There is no such thing as calling a method from another file.
In Java you are defining classes and you can interact with the non-static methods of a class by creating an instance of this class with the new keyword.
I highly recommend either reading Java in a Nutshell or doing the Java tutorial. It will make things a lot clearer.
There are a couple issues with this code:
The naming convention in Java is to have class names starting with a capital letter, and variables starting with a lowercase. This is important here because it might be a source of confusion for you.
linkedqueue.insert(word); looks like a legal command, but you are in fact trying to call a non-static method on a Class object. This is not possible. You should create an instance of the class before trying this:
linkedqueue lq = new linkedqueue();
and then perform all of your actions on lq.
Based on your own spec, the following will throw a NullPointerException by design, if it ever got past a few issues:
String value;
while(value != null){
value = linkedqueue.remove().toString();
}
a variable in a method needs to be initialized before it is used.
if it were initialized to null, your body of your while will never execute. Consider a do{}while() instead.

Categories