Do not change a loop variable inside a for-loop block - javacc

I want to implement the rule coding in my parser generated by javaCC :
Do not change a loop variable inside a for-loop block.
the Rule Production javacc of for-loop block is :
void MyMethod () : {}
{
"(" Argument () ")" {}
(Statement ()) *
}
void Statement () : {}
{
expressionFOR()
}
void expressionFOR() :{}
{
<For> <id> "= " 1 <to> 100
int J
int kk =SUM( , J)
......
}
thank you very much in advance

Assuming you are using JJTree with MULTI=false and VISITOR=true, you could write a visitor along this line
public void visit(SimpleNode node, Object data) {
if( this is a for loop node ) {
push the for loop variable onto a stack of variables
node.childrenAccept(this, null) ;
pop the stack }
else {
if( this is an assignment statement node
and the target variable is on the stack )
report rule violated
node.childrenAccept(this, null) ;
}
}

Related

JavaCC simple example not working

I am trying javacc for the first time with a simple naive example which is not working. My BNF is as follows:
<exp>:= <num>"+"<num>
<num>:= <digit> | <digit><num>
<digit>:= [0-9]
Based on this BNF, I am writing the SimpleAdd.jj as follows:
options
{
}
PARSER_BEGIN(SimpleAdd)
public class SimpleAdd
{
}
PARSER_END(SimpleAdd)
SKIP :
{
" "
| "\r"
| "\t"
| "\n"
}
TOKEN:
{
< NUMBER: (["0"-"9"])+ >
}
int expr():
{
int leftValue ;
int rightValue ;
}
{
leftValue = num()
"+"
rightValue = num()
{ return leftValue+rightValue; }
}
int num():
{
Token t;
}
{
t = <NUMBER> { return Integer.parseInt(t.toString()); }
}
using the above file, I am generating the java source classes. My main class is as follows:
public class Main {
public static void main(String [] args) throws ParseException {
SimpleAdd parser = new SimpleAdd(System.in);
int x = parser.expr();
System.out.println(x);
}
}
When I am entering the expression via System.in, I am getting the following error:
11+11^D
Exception in thread "main" SimpleAddTest.ParseException: Encountered "<EOF>" at line 0, column 0.
Was expecting:
<NUMBER> ...
at SimpleAddTest.SimpleAdd.generateParseException(SimpleAdd.java:200)
at SimpleAddTest.SimpleAdd.jj_consume_token(SimpleAdd.java:138)
at SimpleAddTest.SimpleAdd.num(SimpleAdd.java:16)
at SimpleAddTest.SimpleAdd.expr(SimpleAdd.java:7)
at SimpleAddTest.Main.main(Main.java:9)
Any hint to solve the problem ?
Edit Note that this answer answers an earlier version of the question.
When a BNF production uses a nonterminal that returns a result, you can record that result in a variable.
First declare the variables in the declaration part of the BNF production
int expr():
{
int leftValue ;
int rightValue ;
}
{
Second, in the main body of the production, record the results in the variables.
leftValue = num()
"+"
rightValue = num()
Finally, use the values of those variables to compute the result of this production.
{ return leftValue+rightValue; }
}

Count the number of nodes of a doubly linked list using recursion

Here is what I've done so far:
struct rep_list {
struct node *head;
struct node *tail;
}
typedef rep_list *list;
int length(const list lst) {
if (lst->head == NULL) {
return 0;
}
else {
lst->head = lst->head->next;
return 1 + length(lst);
}
}
This works, but the head of the list the function accepts as a parameter gets changed. I don't know how to fix that.
I'm not allowed to change the function definition so it should always accept a list variable.
Any ideas?
EDIT: I tried to do what Tyler S suggested in the comments but I encountered another problem. If I create a node* variable at the beginning, it should point to lst->head. But then every recursive call to the function changes the value back to lst->head and I cannot move forward.
You don't need a local node: just don't change the list head. Instead, pass the next pointer as the recursion head.
int length(const list lst) {
if (lst->head == NULL) {
return 0;
}
else {
return 1 + length(lst->head-next);
}
}
I see. Okay; this gets a bit clunky because of the chosen representation. You need a temporary variable to contain the remaining list. This iscludes changing the head.
int length(const list lst) {
if (lst->head == NULL) {
return 0;
}
else {
new_lst = new(list)
new_lst->head = lst->head->next;
var result = 1 + length(new_lst);
free(new_lst)
return result
}
}
At each recursion step, you create a new list object, point it to the 2nd element of the current list, and continue. Does this do the job for you?
Although this solution is clunky and I hate it, its the only way I can see to accomplish what you're asking without modifying the method signature. We create a temporary node * as member data of the class and modify it when we start.
struct rep_list {
struct node *head;
struct node *tail;
}
node *temp = NULL;
bool didSetHead = false;
typedef rep_list *list;
int length(const list lst) {
if ((didSetHead) && (lst->head != temp)) {
temp = lst->head;
didSetHead = false;
}
if (temp == NULL) {
didSetHead = true;
return 0;
}
else {
temp = temp->next;
return 1 + length(temp);
}
}
Please note, I haven't tested this code and you may have to play with a bit, but the idea will work.

Issue with Recursive Methods ("missing return statement")

so I have a program that is running a bunch of different recursive methods, and I cannot get it to compile/run. The error is in this method, according to my computer:
public static int fibo(int n)
// returns the nth Fibonacci number
{
if (n==0)
{
return 0;
}
else if (n==1)
{
return 1;
}
else if (n>1)
{
return fibo(n-1) + fibo(n-2);
}
}
I have this method called correctly in my main method, so the issue is in this bit of code.
I think I can help you in this. Add return n; after your else if. Outside of the code but before the last curlicue.
The code will work as long as n ≥ 0 btw; another poster here is right in that you may want to add something to catch that error.
Make sure all possible paths have a return statement. In your code, if n < 0, there is no return statement, the compiler recognizes this, and throws the error.
public static int fibo(int n)
// returns the nth Fibonacci number
{
if (n<=0)
{
return 0;
}
else if (n==1)
{
return 1;
}
else // All other cases, i.e. n >= 1
{
return fibo(n-1) + fibo(n-2);
}
}

Recursion : method which takes a string, and for each repeating sequence of characters in the string, removes all but one of them

Complete the following method which takes a string, and for each repeating sequence of characters in the string, removes all but one of them. For example, given the input string "AAAABCCDDDDAACCCCCC", the method should return "ABCDAC".
YOUR CODE MUST BE RECURSIVE. Do not use any loops (while, do/while, or for). Do not declare any variables outside of the method. You may declare local variables inside the method.
public static String eliminateRepeats (String s)
{
The trick here is that you need a loop to solve this, so you just fake a loop by calling the method recursively with smaller and smaller parts of the string.
There is no way to divide the work into smaller parts, as one usually does when using recursion (like for example split the string in half). You just have to process one character at a time, and call the method with the rest of the string.
Example in C#:
public static string EliminateRepeats(string s) {
return
s.Length == 1 ?
s
:
(s[0] != s[1] ? s.Substring(0, 1) : "")
+ EliminateRepeats(s.Substring(1));
}
(Code inspired by Jonathan Paynes code.)
public class Recurse
{
public static void main( String args[] )
{
System.out.println( recurse( "AAAABCCDDDDAACCCCCC" ) );
}
private static String recurse( String s )
{
if ( s == null || s.equalsIgnoreCase("") )
{
return "";
}
else if ( s.length() > 1 )
{
if ( !s.substring( 0 , 1 ).equalsIgnoreCase( s.substring( 1 , 2 ) ) )
{
return s.substring( 0 , 1 ) + recurse( s.substring( 1 ) );
}
return recurse( s.substring( 1 ) );
}
else
{
return s.substring( 0 , 1 );
}
}
}
// use a default value for the lastchar for the first char,
// which is impossible to meet in an regular string
def concentrate (s: String, lastchar: Char = 0) : String = {
// recursive methods always need to know when it is enough
if (s.length == 0) s else
if (s(0) == lastchar) concentrate (s.substring (1), lastchar) else
s(0) + concentrate (s.substring (1), s(0)) }
concentrate ("AAAABCCDDDDAACCCCCC")
Here is a tailrecursive variation:
#tailrec
def concentrate (s: String, carry:String = "", lastchar: Char = 0) : String = {
if (s.length == 0) carry else
if (s(0) == lastchar) concentrate (s.substring (1), carry, lastchar) else
concentrate (s.substring (1), carry + s(0), s(0)) }
It has the recursive call in the last position, since the resulting string gets glued together on the fly, and passed as parameter. In Scala, this can be optimized by the compiler to run nearly as fast as a loop with mutable variables, and it will not blow the stack - not even for very long Strings.

Print matched token in JavaCC

I need to print the token that was matched by javacc, but I don't know how to "store it".
Let's say my token definition is:
TOKEN :
{
< BLAH: ["0"-"9"]>
}
and my parser.input() function is:
void Input():
{}
{ (<BLAH> { System.out.println("I recognize BLAH"); } )
}
However what I really want to output, given some input, let's say 5, is:
I recognize that BLAH is 5.
Any tips? Thanks
Basically you declare variables in the first curly braces and use them in the second:
void Input():
{ Token t; }
{
(t=<BLAH> { System.out.println("I recognize BLAH is " + t.image); } )
}

Resources