2 Replies Latest reply on Jan 4, 2017 6:54 AM by bugman184 bugman184

    How to use literal 'long' primitive value

    bugman184 bugman184 Newbie

      Hello.

       

      Is it possible to use literal 'long' primitives values in byteman rules, or even float values for that matter? I'm trying to assign a variable with the BIND keyword. If I add 'L' to the numeric literal, byteman detects a syntax error. To test out if the value without the 'L' is a long or an int, I assigned a value of 20 billion, which is outside the range of a int. bmcheck produces an error for this. Here's what won't work:

       

      RULE Test

      CLASS TestMethods

      METHOD myMethod

      BIND var:long = 2000000000L;

      IF true

      DO

          System.out.println(var)

      ENDRULE

       

      I'm using Byteman 3.0.6.

       

      Thanks.

        • 1. Re: How to use literal 'long' primitive value
          Andrew Dinn Master

          Hi,

           

          That's a very good question and highlights a long-standing oversight that I only just noticed. Thank you for reporting this problem.

           

          The tokeniser and grammar recognise signed integral and floating literals in the expected text format. Here are the tokeniser rules

           

          PosInteger = 0 | [1-9][0-9]*
          Sign = [+-]
          Exp = [Ee]
          Dot = "."
          DotTrailing = {Dot} {PosInteger}?
          ExpTrailing = {Exp} {Sign}? {PosInteger}
          FloatTrailing = {ExpTrailing} | {DotTrailing} {ExpTrailing}?
          PosFloat = {PosInteger} {FloatTrailing}
          
          Integer = {Sign}? {PosInteger}
          Float = {Sign}? {PosFloat}
          
          {Integer} { return symbol(sym.INTEGER_LITERAL, Integer.valueOf(yytext())); }
          
          {Float} { return symbol(sym.FLOAT_LITERAL, Float.valueOf(yytext())); }
          

           

          and the corresponding grammar rules

           

          simple_expr
            ::= INTEGER_LITERAL:i
              {: RESULT = node(ParseNode.INTEGER_LITERAL, ileft, iright, i); :}
            | FLOAT_LITERAL:f
              {: RESULT = node(ParseNode.FLOAT_LITERAL, fleft, fright, f); :}
            | BOOLEAN_LITERAL:b
              ...
          

           

          So

           

          • You can write any integral literal value within the int range and it will be parsed correctly as an int.
            n.b. If you employ an int literal in a long context (e.g. to initialise a long) Byteman will auto-coerce it to a long.
          • If you try to write an integral literal value which falls inside the long range and outside the int range tokenising will fail when it calls Integer.valueOf(yytext()).
          • You cannot get round this by adding suffix L.
          • You can write any floating literal value within the float range and it will be parsed correctly as an float.
            n.b. If you employ a float literal in a double context (e.g. to initialise a double) Byteman will auto-coerce it to a double.
          • If you try to write a floating literal value which falls inside the double range and outside the long range tokenising will fail when it calls Float.valueOf(yytext()).
          • You cannot get round this by adding suffix D.

           

          I have raised issue  BYTEMAN-333  to cover this missing functionality.

           

          As a workaround I suggest you use something like

           

          BIND var:long = Long.valueOf("2000000000L");

           

          regards,

           

           

          Andrew Dinn

          • 2. Re: How to use literal 'long' primitive value
            bugman184 bugman184 Newbie

            That's great Andrew, thanks a lot for the helpful reply.