We help IT Professionals succeed at work.

A simple question on JavaCC

I am using JavaCC utility to generate a parser. Now I am writing the grammar in ".JJ" file.
I have three tokens defined say TokenA: "A", TokenB: "B" and TokenC: "C".
I have to write a statement in my grammar(.JJ file) such that it should match the above tokens with the following all conditions,
1) All the tokens are optional
Example : ABC or AB or Ac or A or nothing
2)The tokens can appear in any order
Example: ABC or CBA or ACB or .....
3) A token can appear only once
Example: AAB ---> is wrong, becaue "A" appears twice.
Expecting an early reply...
Thanx in advance....
Regards,
Poorna.
Comment
Watch Question

Commented:
Sounds much like homework for JavaCC... Okay, here's a solution.

void Example1() : {}
{
  <TokenA>? <TokenB>? <TokenC>?
}
// valid sequences: ABC AB AC A BC B C nothing

void Example2() : {}
{
  ( <TokenA>? <TokenB>? <TokenC>? )*
}
// valid sequences: AAAA ABBBB BCCCA CBA A nothing ...


void Example3() : {}
{
  <TokenA> <TokenB> <TokenC>
|
  <TokenA> <TokenC> <TokenB>
|
  <TokenB> <TokenA> <TokenC>
|
  <TokenB> <TokenC> <TokenA>
|
  <TokenC> <TokenA> <TokenB>
|
  <TokenC> <TokenB> <TokenA>
}
// valid sequences: ABC ACB BAC BCA CAB CBA

Author

Commented:
Hi Dnoelpp,

Thanx for the early reply....

sorry fren, I want a SINGLE statement which should satisfy all the three conditions mentioned in my question. And one more thing is Pls. look at my third point, a token should not appear more than one in the sequence. like "AAB" is false.

If this is not possible or if there is any work arounds pls. Let me kno my MailID is poorna@fast.fujitsu.com.au

Expecting an another early reply form you....

Regards,
Poorna.

Commented:
I don't understand you. Let's have a look at the sets of token sequences which are accepted by Example1, Example2 and Example 3: you will discover that both sets for Example3 and Example1 are subsets of Example2.

Logically your question doesn't make sense. If you want to combine all Examples, just use Example2 because it covers the other two.

I am sorry.

Commented:
Let's try to guess what you mean.

You want the three tokens A B C to be matched optionally and in any order. Valid matches are for example: nothing, A, B, AC, BC, BAC.

The statement for this is:

void Example4() : {}
{
 <TokenA>? <TokenB>? <TokenC>?
|
 <TokenA>? <TokenC>? <TokenB>?
|
 <TokenB>? <TokenA>? <TokenC>?
|
 <TokenB>? <TokenC>? <TokenA>?
|
 <TokenC>? <TokenA>? <TokenB>?
|
 <TokenC>? <TokenB>? <TokenA>?
}

By the way, I looked at the JavaCC grammar for Java for the modifiers (private, protected, public, etc), and the grammar part is as follows:

  ( "public" | "protected" | "private" | "static" | "abstract" | "final" | "native" | "synchronized" )*

I have the opinion, they use lookaheads to limit the appearance of a modifier keyword to at most one time.

Author

Commented:
Hi Dnoelpp,

Thanx for the early reply again....

I understand that your example-1 and example-3 are subsets of example-3... but you see, I am clearly telling you that I don't want to have the redundant tokens to appear in the file that I am parsing...  

As you said I just want the example-1 and example-3 to be combined but the tokens should appear only once in the sequence.......

Reply to your third Comment :

Do u mean to say that Java parser or compiler will allow me to declare a class as below

public public public Class MyClass
{

}


I think that there is something got to do with Lookaheads
that's what I am expecting....

Author

Commented:
I think your example-4 looks okay... Is there any better ways of doing it..

Commented:
Copied from the JavaCC grammar for Java 1.0.2 (to avoid complication from nested classes and instance initializers, but the principle is the same (I checked the grammar of Java 1.2, too)).

void ClassBodyDeclaration() :
{}
{
  LOOKAHEAD(2)
  StaticInitializer()
|
  LOOKAHEAD( [ "public" | "protected" | "private" ] Name() "(" )
  ConstructorDeclaration()
|
  LOOKAHEAD( MethodDeclarationLookahead() )
  MethodDeclaration()
|
  FieldDeclaration()
}

This is the production for all members in a class. A member of a class can be: a static initializer, a constructor, a method or a field declaration (4 alternatives).

You see, for the method declaration they use a lookahead. But as you will see, this lookahead doesn't solve our problem, I am sorry. Let's look at the lookahead production.

void MethodDeclarationLookahead() :
{}
{
  ( "public" | "protected" | "private" | "static" | "abstract" | "final" | "native" | "synchronized" )*
  ResultType() <IDENTIFIER> "("
}

The lookahead is valid only if any number of modifiers is followed by a result type specification, an identifier and an opening parenthese.

Let's look at the method declaration production.

void MethodDeclaration() :
{}
{
  ( "public" | "protected" | "private" | "static" | "abstract" | "final" | "native" | "synchronized" )*
  ResultType() MethodDeclarator() [ "throws" NameList() ]
  ( Block() | ";" )
}

Neither the lookahead nor the declaration prevent that one modifier can be repeated. So, I am afraid, either you use the Example4 solution from me (the number of alternatives is the faculty of the number of the different tokens, so, if you have 4 token, you need 24 alternatives, if you have 5 token, you need 120 alternatives, etc.). If the number of alternatives is too high, then you need a separate step outside of a grammar to limit the number of modifiers.

But this is a bit more difficult. If you really need a complete solution from me, I am ready to hack an working example, compile it and give it to you to work at. But, please, increase the points (I would like 100 or even 200 points). Thanks.

Author

Commented:
I think your example-4 looks okay... Is there any better ways of doing it..
Commented:
To the heck with the points! You decide whether you are satisfied with the answers I provided.

Here's an example how to solve the problem with the repeated modifiers. I compiled it and it run fine. Try to enter ABCD then Return, you should see just "finished parsing". If you enter ABCDA, you should see "repeated modifier". This example should get you started with your problem.

Here's the completed and tested example code!

options {
  LOOKAHEAD = 1;
  CHOICE_AMBIGUITY_CHECK = 2;
  OTHER_AMBIGUITY_CHECK = 1;
  STATIC = true;
  DEBUG_PARSER = false;
  DEBUG_LOOKAHEAD = false;
  DEBUG_TOKEN_MANAGER = false;
  ERROR_REPORTING = true;
  JAVA_UNICODE_ESCAPE = true;
  UNICODE_INPUT = false;
  IGNORE_CASE = false;
  USER_TOKEN_MANAGER = false;
  USER_CHAR_STREAM = false;
  BUILD_PARSER = true;
  BUILD_TOKEN_MANAGER = true;
  SANITY_CHECK = true;
  FORCE_LA_CHECK = false;
}

PARSER_BEGIN(Test)


public class Test {

    public static void main(String args[]) throws ParseException {
        Test test = new Test(System.in);
        test.Start();
        System.out.println("finished parsing");
    }

    public static boolean check(boolean value) {
        if (value) System.out.println("error: repeated modifier");
AB        return true;
    }
}

PARSER_END(Test)

void Start() :
{
    boolean matchedA = false;
    boolean matchedB = false;
    boolean matchedC = false;
    boolean matchedD = false;
}
{
    (
        "A" { matchedA = check(matchedA); }
    |
        "B" { matchedB = check(matchedB); }
    |
        "C" { matchedC = check(matchedC); }
    |
        "D" { matchedD = check(matchedD); }
    )*
    "\n"
}


Cheers and good luck!

Commented:
Please delete the AB in the line with return true;

Author

Commented:
Hi Dnoelpp,

Thanx for the Comment.... I will accept this as a solution. This is good wrok around right? You have introduced a flag for every token and checking... It works quite well...  

It seems your are good at JavaCC....... I am just a beginner. I have started learning from a couple of days.

I will certaily increase the points, If u clear my one more very small doubt... I think you can clear it in no time..

My Doubt is

Commented:
Yes?

Author

Commented:
Hooooo sorry man Can I tell u tomorrow... It's already 9:40PM here... sorry about this...

Commented:
Ok.

Author

Commented:
Thanks a lot.............

Commented:
Thanks a lot for the points.

A small question, why a grade B?

If you weren't THIS satisfied to give me a grade A, you could have made more detailed requests till you are satisfied... You know, it doesn't make a difference for YOU between grade A and grade B. But it makes a difference for me. I need the points to keep up the EE pro. And my rank doesn't look as well with many B grades. I am sorry.

So, what's still not okay for you?

Author

Commented:
I have posted another question... u can have a look at it