aboutsummaryrefslogtreecommitdiffstats
path: root/src/java
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2015-03-25 12:45:41 +0100
committerSven Gothel <[email protected]>2015-03-25 12:45:41 +0100
commitd30a3ea54e26978d6ff199cba0fd79c5c0cef483 (patch)
treee772b1e8acf627e2e7ad4bec56148f75dd5e7d7b /src/java
parent6058af19f2929a39deb0dbcc48040a4bb53bb559 (diff)
Bug 1149: Fix parsing of hexadecimal w/ binary exponent floats in regexp-constant and java-parser. (Due to PCPP -> JCPP)
Lack of parsing binary exponent floats is exposed due to using JCPP and correct constant-definitions. - JavaParser.g: - Add support for hexadecimal w/ binary exponent floats - TAB -> 4 spaces - ConstantDefinition.java: - Add RegExp 'fpRegexp', patternDecimalNumber: decimal number w/ support for hexadecimal w/ binary exponent floats. - isDecimalNumber(..): Use patternDecimalNumber instead of try-and-error (NumberFormatException) - patternCPPOperand: exclude patternDecimalNumber! - JavaEmitter.java: - Respect explicit suffix [dD] for double type. - Drop floating point suffixes [fF] - Test: Added tests for hexadecimal w/ binary exponent floats
Diffstat (limited to 'src/java')
-rw-r--r--src/java/com/jogamp/gluegen/ConstantDefinition.java121
-rw-r--r--src/java/com/jogamp/gluegen/JavaEmitter.java9
2 files changed, 94 insertions, 36 deletions
diff --git a/src/java/com/jogamp/gluegen/ConstantDefinition.java b/src/java/com/jogamp/gluegen/ConstantDefinition.java
index e88bb9c..f8f4973 100644
--- a/src/java/com/jogamp/gluegen/ConstantDefinition.java
+++ b/src/java/com/jogamp/gluegen/ConstantDefinition.java
@@ -33,6 +33,8 @@
package com.jogamp.gluegen;
+import java.util.regex.Pattern;
+
import com.jogamp.gluegen.ASTLocusTag.ASTLocusTagProvider;
import com.jogamp.gluegen.cgram.types.AliasedSymbol.AliasedSymbolImpl;
import com.jogamp.gluegen.cgram.types.TypeComparator.AliasedSemanticSymbol;
@@ -198,38 +200,6 @@ public class ConstantDefinition extends AliasedSymbolImpl implements AliasedSema
}
return false;
}
- public static boolean isNumber(final String s) {
- if( isHexNumber(s) ) {
- return true;
- } else {
- return isDecimalNumber(s);
- }
- }
- public static boolean isHexNumber(final String s) {
- return patternHexNumber.matcher(s).matches();
- }
- public static java.util.regex.Pattern patternHexNumber =
- java.util.regex.Pattern.compile("0[xX][0-9a-fA-F]+[lLfFuU]?");
-
- public static boolean isDecimalNumber(final String s) {
- try {
- Float.valueOf(s);
- } catch (final NumberFormatException e) {
- // not parsable as a number
- return false;
- }
- return true;
- }
-
-
- public static boolean isCPPOperand(final String s) {
- return patternCPPOperand.matcher(s).matches();
- }
- /**
- * One of: {@code +} {@code -} {@code *} {@code /} {@code |} {@code &} {@code (} {@code )} {@code <<} {@code >>}
- */
- public static java.util.regex.Pattern patternCPPOperand =
- java.util.regex.Pattern.compile("[\\+\\-\\*\\/\\|\\&\\(\\)]|(\\<\\<)|(\\>\\>)");
public static boolean isIdentifier(final String value) {
boolean identifier = false;
@@ -251,4 +221,91 @@ public class ConstantDefinition extends AliasedSymbolImpl implements AliasedSema
}
return identifier;
}
+
+ public static boolean isNumber(final String s) {
+ if( isHexNumber(s) ) {
+ return true;
+ } else {
+ return isDecimalNumber(s);
+ }
+ }
+ public static boolean isHexNumber(final String s) {
+ return patternHexNumber.matcher(s).matches();
+ }
+ public static Pattern patternHexNumber = Pattern.compile("0[xX][0-9a-fA-F]+[lLfFuU]?");
+
+ /**
+ * Complete pattern for <code>floating point</code> number,
+ * compatible and described in {@link Double#valueOf(String)}.
+ */
+ public static Pattern patternDecimalNumber;
+ private static String fpRegex;
+ static {
+ final String Digits = "(\\p{Digit}+)";
+ final String HexDigits = "(\\p{XDigit}+)";
+ // an exponent is 'e' or 'E' followed by an optionally
+ // signed decimal integer.
+ final String Exp = "[eE][+-]?"+Digits;
+ fpRegex =
+ ("[\\x00-\\x20]*"+ // Optional leading "whitespace"
+ "[+-]?" + // Optional sign character
+ "("+
+ "NaN|" + // "NaN" string
+ "Infinity|" + // "Infinity" string
+
+ // A decimal floating-point string representing a finite positive
+ // number without a leading sign has at most five basic pieces:
+ // Digits . Digits ExponentPart FloatTypeSuffix
+ //
+ // Since this method allows integer-only strings as input
+ // in addition to strings of floating-point literals, the
+ // two sub-patterns below are simplifications of the grammar
+ // productions from the Java Language Specification, 2nd
+ // edition, section 3.10.2.
+
+ "("+
+ "("+
+ // Digits ._opt Digits_opt ExponentPart_opt FloatTypeSuffix_opt
+ "("+Digits+"(\\.)?("+Digits+"?)("+Exp+")?)|"+
+
+ // . Digits ExponentPart_opt FloatTypeSuffix_opt
+ "(\\.("+Digits+")("+Exp+")?)|"+
+
+ // Hexadecimal w/ binary exponent
+ "(" +
+ "(" +
+ // Hexadecimal strings
+ // 0[xX] HexDigits ._opt BinaryExponent FloatTypeSuffix_opt
+ "(0[xX]" + HexDigits + "(\\.)?)|" +
+
+ // 0[xX] HexDigits_opt . HexDigits BinaryExponent FloatTypeSuffix_opt
+ "(0[xX]" + HexDigits + "?(\\.)" + HexDigits + ")" +
+ ")" +
+
+ // binary exponent
+ "[pP][+-]?" + Digits +
+ ")" +
+ ")" +
+ "[fFdD]?"+
+ ")"+
+ ")" +
+ "[\\x00-\\x20]*"// Optional trailing "whitespace"
+ );
+ patternDecimalNumber = Pattern.compile(fpRegex);
+ }
+ public static boolean isDecimalNumber(final String s) {
+ return patternDecimalNumber.matcher(s).matches();
+ }
+
+ public static boolean isCPPOperand(final String s) {
+ return patternCPPOperand.matcher(s).matches();
+ }
+ /**
+ * One of: {@code +} {@code -} {@code *} {@code /} {@code |} {@code &} {@code (} {@code )} {@code <<} {@code >>}
+ * <p>
+ * Expression excludes {@link #patternDecimalNumber}.
+ * </p>
+ */
+ public static Pattern patternCPPOperand = Pattern.compile("(?!"+fpRegex+")[\\+\\-\\*\\/\\|\\&\\(\\)]|(\\<\\<)|(\\>\\>)");
+
}
diff --git a/src/java/com/jogamp/gluegen/JavaEmitter.java b/src/java/com/jogamp/gluegen/JavaEmitter.java
index ae4ed2a..5fb281f 100644
--- a/src/java/com/jogamp/gluegen/JavaEmitter.java
+++ b/src/java/com/jogamp/gluegen/JavaEmitter.java
@@ -384,7 +384,7 @@ public class JavaEmitter implements GlueEmitter {
final double dVal = Double.parseDouble(value);
final double absVal = Math.abs(dVal);
// if constant is small enough, store it as a float instead of a double
- if (absVal < Float.MIN_VALUE || absVal > Float.MAX_VALUE) {
+ if (absVal < Float.MIN_VALUE || absVal > Float.MAX_VALUE || lastChar == 'd' || lastChar == 'D' ) {
return new Double(dVal);
}
return new Float((float) dVal);
@@ -448,10 +448,11 @@ public class JavaEmitter implements GlueEmitter {
javaWriter().println(" /** " + optionalComment + " */");
}
String suffix = "";
- if(!value.endsWith(")")) {
- if (type.equals("float") && !value.endsWith("f")) {
+ final char lastChar = value.charAt(value.length()-1);
+ if( lastChar != ')' ) {
+ if (type.equals("float") && lastChar != 'f' && lastChar != 'F' ) {
suffix = "f";
- }else if(value.endsWith("u") || value.endsWith("U")) {
+ }else if( lastChar == 'u' || lastChar == 'U' ) {
value = value.substring(0, value.length()-1);
}
}