Re: [classad-users] c++ & java inconsistency


Date: Sun, 8 Jun 2003 08:33:55 -0500 (CDT)
From: Marvin Solomon <solomon@xxxxxxxxxxx>
Subject: Re: [classad-users] c++ & java inconsistency
Alessandro Maraschini wrote:
> Here is one strange aspect in Java: when I build a classad from string
> it does not recognise the value as an integer, as it should be but,
> instead, the caught type is -7 which is  "a unary or binary operator" as
> your online documentation says:
>
>
> Java Code:
> ===========
>     ClassAdParser cp = new ClassAdParser( "[  one = -5  ]"  )  ;
>     RecordExpr re = ( RecordExpr)   cp.parse() ;
>     re.insertAttribute( "two" , (Expr) Constant.getInstance( -3 )   );
>     System.out.println( "OUTPUT: " + re  );
>     System.out.println("one:Which is the type?" + re.lookup
> ("one").type   );
>     System.out.println("two: Which is the type?" + re.lookup
> ("two").type   );
>
> Java Output:
> ==========
> OUTPUT: [ one = (-5); two = -3 ]
> one:Which is the type?-7
> two: Which is the type?3
>
>
>
> Whilest in C++ the behaviour seems to be the supposed one:
>
>
>
> C++ Code:
> =========
> ClassAdParser cp ;
> ClassAd* classAd ;
> classAd = (ClassAd*) cp.ParseExpression(  "[  one = -5 ]" ) ;
> Value val ;
> val.SetIntegerValue( -6 ) ;
> classAd->Insert( "two" ,   (ExprTree*)Literal::MakeLiteral (val)   );
> string       buffer="";
> PrettyPrint  unp ;
> unp.Unparse(buffer, classAd  ) ;
> cout << "OUTPUT = " << buffer << endl << flush ;
> classAd->EvaluateExpr ( classAd->Lookup("one")  , val ) ;
> cout << "one type: " << val.IsIntegerValue() << endl << flush ;
> classAd->EvaluateExpr ( classAd->Lookup("two")  , val ) ;
> cout << "two type: " <<  val.IsIntegerValue() << endl << flush ;
>
>
> C++ Output:
> ========
> OUTPUT =
>     [
>         two = -6;
>         one =  -5
>     ]
> one type: 1
> two type: 1

Alessandro Maraschini wrote:
> Hi, while  performing some test I've came across a different behaviour
> between java & c++ classad implementation.
>
> C++ code
> =====
>
> ClassAdParser cp ;
> ClassAd* classAd = new ClassAd ();
> classAd->Insert( "one" ,   cp.ParseExpression(  "-5" ) );
> string       buffer="";
> PrettyPrint  unp ;
> unp.Unparse(buffer, classAd  ) ;
> cout << "OUTPUT = " << buffer << endl << flush ;
>
> C++ output
> ======
>
> OUTPUT =
>     [
>         one =  -5
>     ]
>
>
>
>
> JAVA code
> ========
>
>     RecordExpr re = new RecordExpr() ;
>     ClassAdParser cp = new ClassAdParser( "-5"  )  ;
>     re.insertAttribute( "one" , cp.parse()  );
>     System.out.println( "OUTPUT: " + re  );
>
> JAVA output
> ==========
>
>
>   OUTPUT: [ one = (-5) ]
>
>
>
>
> ---------------
>
> As you can see the use of parentesys is different, I don't know wheter
> it has been fixed in the latest java release but if not, can you please
> check it?
>
> BTW, which should be the right representation ? (I guess it's the second
> one but... never know..)

The Java behavior matches the definitions of the C, C++, and Java langauges in
that there is no such thing as a negative integer constant.  Constants always
start with a digit.  The expression "-3" is parsed as the unary operator "-"
applied to the integer constant "3".  (See also the experiment at the end of
this message). The emerging ClassAd language standard endorses this behavior.
The behavior of the C++ implementation parses "-3" as a negative constant, but
that will probably be changed in the future.

The ClassAd language reference defines an expression as an abstract
tree-structured object, with operators applied to operands.  In general, there
may be many ways of displaying the same expression, depending on use
of parentheses, spaces, newlines, precision of real constants, etc.  Any
such string representation of an expression E is "correct" if parsing it
results in the same expression E.  Thus in a strict sense, the answer to your
question "which should be the right representation?" is "both representations
are right".

The next release of the classad reference manual defines a "canonical
unparsing" of an expression, for use in cases where you really need a
one-to-one correspondence between expressions and character strings.  In this
representation, there are no spaces (outside of string constants) and all
expressions are fully parenthesized.  For example, if the string "-x + y * z"
is parsed and then printed with the canonical unparsing, the result is
"((-x)+(y*z))".  In the Java implementation, the toString() method currently
converts a ClassAd to its canonical representation.  Since the toString()
method is implicitly invoked in

    System.out.println( "OUTPUT: " + re  ),

expression "re" is printed in the canonical representation.  [Actually, the
2.0 release of the Java implementation inserts extra spaces in toString().
The result should be "OUTPUT: [one=(-5)]".  This will be fixed in the
next release.]

However, you can use the class ClassAdWriter to choose a variety of
representations.  For example,
    ClassAdWriter caw = new ClassAdWriter(System.out);
    caw.setFormatFlags(ClassAdWriter.READABLE);
    caw.print("OUTPUT: ");
    caw.println(re);
    caw.flush();


The C++ implementation does not currently support the canonical unparsing,
but it will in the future.  When parsing a string, it remembers the placement
of parentheses in the internal data structure and displays them on unparsing.
Thus if you parse the string "x + (y * z)" and then convert the result
back to a string you will get "x + (y + z)".  However, if you create an
equivalent expression using the C++ api, you will get "x + y * z".   The Java
implementation does not support this feature, but it may in the future.

The ClassAd language syntax and semantics is defined by the reference manual.
The C++ and Java implementations both try to conform to this specification.
They don't exactly match yet, but we are working to get them closer.  The api,
on the other hand, is another matter.  The two implementations provide
very different programming interfaces for such operations as constructing
or navigating through a classad.  Remember that a ClassAd expression is
an abstract tree-structured object.  Both the C++ and Java implementations
represent expressions as data strucures, but the structures are different.
Such operations as

    val.IsIntegerValue() // in C++

or

    re.lookup("one").type

are looking at the implementations of the expressions.  By analogy, the Java
language standard specifies the externally visible behavior of a program.
It does not specify how the program is represented internally, or what
the generated bytecode must look like.  Two Java compliers may produce very
different .class files, so long as the externally visible behavior of
running the programs is the same.

Your exmample does raise an interesting question, however.  The api allows
you to create valid expressions that cannot be the result of parsing
any string representation.  One example is an expression containing the integer
constant negative 5.  What should the canonical unparsing of such an expression
be?  Currently, the Java implementation produces "-5".  Offhand, I would
say the expression should be displayed as if it was the result of parsing
"-5", which would be "(-5)".

You may find the following experiment instructive.  Compile this program

    #include <stdio.h>
    int main() {
        int x =  -2147483648;
        printf("%x %d\n", x, x);
        return 0;
    }

with "gcc -Wall".  The compiler issues the message

    warning: decimal constant is so large that it is unsigned

The compiler parses 2147483648 as an unsigned int, applies the "-" operator to
it at compile time (which has no effect) and then coerces the unsigned value to
a signed 32-bit integer.  The analogous Java program parses 2147483648 as a
long (64-bit) integer, applies the "-" operator to it at compile time
(producing a negative value) and then coerces the result back to int (32-bit).
The ClassAd language has neither an unsigned type nor a 64-bit integer type, so
there is no way to represent the value -2147483648 in the string representation
of a classad.  I'll have to give some thought how to deal with this case.

Condor Classads Info:
http://www.cs.wisc.edu/condor/classad/




[← Prev in Thread] Current Thread [Next in Thread→]