Index: src/Parser/DeclarationNode.cc
===================================================================
--- src/Parser/DeclarationNode.cc	(revision e3e16bcf91a7300a6d1f71eaad04e2f3f498cfc2)
+++ src/Parser/DeclarationNode.cc	(revision 982832e24b58f99cf8d892fbb03bfd2c5cd57b15)
@@ -333,8 +333,8 @@
 DeclarationNode * DeclarationNode::newTypeDecl( string * name, DeclarationNode * typeParams ) {
 	DeclarationNode * newnode = new DeclarationNode;
+	newnode->name = name;
 	newnode->type = new TypeData( TypeData::Symbolic );
 	newnode->type->symbolic.isTypedef = false;
 	newnode->type->symbolic.params = typeParams;
-	newnode->type->symbolic.name = name;
 	return newnode;
 } // DeclarationNode::newTypeDecl
Index: src/Parser/ExpressionNode.cc
===================================================================
--- src/Parser/ExpressionNode.cc	(revision e3e16bcf91a7300a6d1f71eaad04e2f3f498cfc2)
+++ src/Parser/ExpressionNode.cc	(revision 982832e24b58f99cf8d892fbb03bfd2c5cd57b15)
@@ -10,6 +10,6 @@
 // Created On       : Sat May 16 13:17:07 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sun Sep  3 22:21:21 2017
-// Update Count     : 639
+// Last Modified On : Tue Sep 12 10:00:29 2017
+// Update Count     : 672
 //
 
@@ -49,8 +49,10 @@
 // type.
 
-extern const Type::Qualifiers noQualifiers;		// no qualifiers on constants
-
+extern const Type::Qualifiers noQualifiers;				// no qualifiers on constants
+
+static inline bool checkH( char c ) { return c == 'h' || c == 'H'; }
+static inline bool checkL( char c ) { return c == 'l' || c == 'L'; }
+static inline bool checkZ( char c ) { return c == 'z' || c == 'Z'; }
 static inline bool checkU( char c ) { return c == 'u' || c == 'U'; }
-static inline bool checkL( char c ) { return c == 'l' || c == 'L'; }
 static inline bool checkF( char c ) { return c == 'f' || c == 'F'; }
 static inline bool checkD( char c ) { return c == 'd' || c == 'D'; }
@@ -67,7 +69,8 @@
 
 Expression * build_constantInteger( string & str ) {
-	static const BasicType::Kind kind[2][3] = {
-		{ BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt },
-		{ BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt },
+	static const BasicType::Kind kind[2][5] = {
+		// short (h) must be before char (hh)
+		{ BasicType::ShortSignedInt, BasicType::SignedChar, BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt },
+		{ BasicType::ShortUnsignedInt, BasicType::UnsignedChar, BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt },
 	};
 
@@ -76,10 +79,9 @@
 
 	bool dec = true, Unsigned = false;					// decimal, unsigned constant
-	int size;											// 0 => int, 1 => long, 2 => long long
+	int size;											// 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => size_t
 	unsigned long long int v;							// converted integral value
 	size_t last = str.length() - 1;						// last character of constant
 	Expression * ret;
 
-	// ROB: what do we do with units on 0 and 1?
 	// special constants
 	if ( str == "0" ) {
@@ -107,43 +109,69 @@
 
 	if ( v <= INT_MAX ) {								// signed int
-		size = 0;
+		size = 2;
 	} else if ( v <= UINT_MAX && ! dec ) {				// unsigned int
-		size = 0;
+		size = 2;
 		Unsigned = true;								// unsigned
 	} else if ( v <= LONG_MAX ) {						// signed long int
-		size = 1;
+		size = 3;
 	} else if ( v <= ULONG_MAX && ( ! dec || LONG_MAX == LLONG_MAX ) ) { // signed long int
-		size = 1;
+		size = 3;
 		Unsigned = true;								// unsigned long int
 	} else if ( v <= LLONG_MAX ) {						// signed long long int
-		size = 2;
+		size = 4;
 	} else {											// unsigned long long int
-		size = 2;
+		size = 4;
 		Unsigned = true;								// unsigned long long int
 	} // if
+
+	// At least one digit in integer constant, so safe to backup while looking for suffix.
 
 	if ( checkU( str[last] ) ) {						// suffix 'u' ?
 		Unsigned = true;
-		if ( last > 0 && checkL( str[last - 1] ) ) {	// suffix 'l' ?
-			size = 1;
-			if ( last > 1 && checkL( str[last - 2] ) ) { // suffix 'll' ?
-				size = 2;
+		if ( checkL( str[last - 1] ) ) {				// suffix 'l' ?
+			size = 3;
+			if ( checkL( str[last - 2] ) ) {			// suffix "ll" ?
+				size = 4;
 			} // if
+		} else if ( checkH( str[last - 1] ) ) {			// suffix 'h' ?
+			size = 0;
+			if ( checkH( str[last - 2] ) ) {			// suffix "hh" ?
+				size = 1;
+			} // if
+			str.erase( last - size - 1, size + 1 );		// remove 'h'/"hh"
 		} // if
 	} else if ( checkL( str[ last ] ) ) {				// suffix 'l' ?
-		size = 1;
-		if ( last > 0 && checkL( str[last - 1] ) ) {	// suffix 'll' ?
-			size = 2;
-			if ( last > 1 && checkU( str[last - 2] ) ) { // suffix 'u' ?
+		size = 3;
+		if ( checkL( str[last - 1] ) ) {				// suffix 'll' ?
+			size = 4;
+			if ( checkU( str[last - 2] ) ) {			// suffix 'u' ?
 				Unsigned = true;
 			} // if
-		} else {
-			if ( last > 0 && checkU( str[last - 1] ) ) { // suffix 'u' ?
+		} else if ( checkU( str[last - 1] ) ) {			// suffix 'u' ?
+			Unsigned = true;
+		} // if
+	} else if ( checkH( str[ last ] ) ) {				// suffix 'h' ?
+		size = 0;
+		if ( checkH( str[last - 1] ) ) {				// suffix "hh" ?
+			size = 1;
+			if ( checkU( str[last - 2] ) ) {			// suffix 'u' ?
 				Unsigned = true;
 			} // if
-		} // if
+		} else if ( checkU( str[last - 1] ) ) {			// suffix 'u' ?
+			Unsigned = true;
+		} // if
+		str.erase( last - size, size + 1 );				// remove 'h'/"hh"
+	} else if ( checkZ( str[last] ) ) {					// suffix 'z' ?
+		size = 5;
+		str.erase( last, 1 );							// remove 'z'
 	} // if
 
 	ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[Unsigned][size] ), str, v ) );
+	if ( Unsigned && size < 2 ) {						// less than int ?
+		// int i = -1uh => 65535 not -1, so cast is necessary for unsigned, which eliminates warnings for large values.
+		ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][size] ) );
+	} else if ( size == 5 ) {							// explicit cast to size_t
+		ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), "size_t", false ) );
+	} // if
   CLEANUP:
 	if ( units.length() != 0 ) {
@@ -247,4 +275,18 @@
 } // build_constantStr
 
+Expression * build_field_name_FLOATING_FRACTIONconstant( const string & str ) {
+	if ( str.find_first_not_of( "0123456789", 1 ) != string::npos ) throw SemanticError( "invalid tuple index " + str );
+	Expression * ret = build_constantInteger( *new string( str.substr(1) ) );
+	delete &str;
+	return ret;
+} // build_field_name_FLOATING_FRACTIONconstant
+
+Expression * build_field_name_FLOATING_DECIMALconstant( const string & str ) {
+	if ( str[str.size()-1] != '.' ) throw SemanticError( "invalid tuple index " + str );
+	Expression * ret = build_constantInteger( *new string( str.substr( 0, str.size()-1 ) ) );
+	delete &str;
+	return ret;
+} // build_field_name_FLOATING_DECIMALconstant
+
 Expression * build_field_name_FLOATINGconstant( const string & str ) {
 	// str is of the form A.B -> separate at the . and return member expression
@@ -273,18 +315,4 @@
 	return make_field_name_fraction_constants( fieldName, maybeMoveBuild< Expression >( fracts ) );
 } // build_field_name_fraction_constants
-
-Expression * build_field_name_REALFRACTIONconstant( const string & str ) {
-	if ( str.find_first_not_of( "0123456789", 1 ) != string::npos ) throw SemanticError( "invalid tuple index " + str );
-	Expression * ret = build_constantInteger( *new string( str.substr(1) ) );
-	delete &str;
-	return ret;
-} // build_field_name_REALFRACTIONconstant
-
-Expression * build_field_name_REALDECIMALconstant( const string & str ) {
-	if ( str[str.size()-1] != '.' ) throw SemanticError( "invalid tuple index " + str );
-	Expression * ret = build_constantInteger( *new string( str.substr( 0, str.size()-1 ) ) );
-	delete &str;
-	return ret;
-} // build_field_name_REALDECIMALconstant
 
 NameExpr * build_varref( const string * name ) {
Index: src/Parser/ParseNode.h
===================================================================
--- src/Parser/ParseNode.h	(revision e3e16bcf91a7300a6d1f71eaad04e2f3f498cfc2)
+++ src/Parser/ParseNode.h	(revision 982832e24b58f99cf8d892fbb03bfd2c5cd57b15)
@@ -10,6 +10,6 @@
 // Created On       : Sat May 16 13:28:16 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sun Sep  3 19:24:34 2017
-// Update Count     : 799
+// Last Modified On : Sun Sep 10 09:56:32 2017
+// Update Count     : 801
 //
 
@@ -166,8 +166,8 @@
 Expression * build_constantChar( std::string &str );
 Expression * build_constantStr( std::string &str );
+Expression * build_field_name_FLOATING_FRACTIONconstant( const std::string & str );
+Expression * build_field_name_FLOATING_DECIMALconstant( const std::string & str );
 Expression * build_field_name_FLOATINGconstant( const std::string & str );
 Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts );
-Expression * build_field_name_REALFRACTIONconstant( const std::string & str );
-Expression * build_field_name_REALDECIMALconstant( const std::string & str );
 
 NameExpr * build_varref( const std::string * name );
Index: src/Parser/lex.ll
===================================================================
--- src/Parser/lex.ll	(revision e3e16bcf91a7300a6d1f71eaad04e2f3f498cfc2)
+++ src/Parser/lex.ll	(revision 982832e24b58f99cf8d892fbb03bfd2c5cd57b15)
@@ -10,6 +10,6 @@
  * Created On       : Sat Sep 22 08:58:10 2001
  * Last Modified By : Peter A. Buhr
- * Last Modified On : Thu Aug 31 21:30:10 2017
- * Update Count     : 598
+ * Last Modified On : Sun Sep 10 22:29:15 2017
+ * Update Count     : 620
  */
 
@@ -93,33 +93,35 @@
 				// numeric constants, CFA: '_' in constant
 hex_quad {hex}("_"?{hex}){3}
-integer_suffix_opt ("_"?(([uU](("ll"|"LL"|[lL])[iI]|[iI]?("ll"|"LL"|[lL])?))|([iI](("ll"|"LL"|[lL])[uU]|[uU]?("ll"|"LL"|[lL])?))|(("ll"|"LL"|[lL])([iI][uU]|[uU]?[iI]?))))?
+length ("ll"|"LL"|[lL])|("hh"|"HH"|[hH])
+integer_suffix_opt ("_"?(([uU]({length}?[iI]?)|([iI]{length}))|([iI]({length}?[uU]?)|([uU]{length}))|({length}([iI]?[uU]?)|([uU][iI]))|[zZ]))?{user_suffix_opt}
 
 octal_digits ({octal})|({octal}({octal}|"_")*{octal})
 octal_prefix "0""_"?
-octal_constant (("0")|({octal_prefix}{octal_digits})){integer_suffix_opt}{user_suffix_opt}
+octal_constant (("0")|({octal_prefix}{octal_digits})){integer_suffix_opt}
 
 nonzero_digits ({nonzero})|({nonzero}({decimal}|"_")*{decimal})
-decimal_constant {nonzero_digits}{integer_suffix_opt}{user_suffix_opt}
+decimal_constant {nonzero_digits}{integer_suffix_opt}
 
 hex_digits ({hex})|({hex}({hex}|"_")*{hex})
 hex_prefix "0"[xX]"_"?
-hex_constant {hex_prefix}{hex_digits}{integer_suffix_opt}{user_suffix_opt}
+hex_constant {hex_prefix}{hex_digits}{integer_suffix_opt}
 
 				// GCC: D (double) and iI (imaginary) suffixes, and DL (long double)
-floating_suffix_opt ("_"?([fFdDlL][iI]?|[iI][lLfFdD]?|"DL"))?
+exponent "_"?[eE]"_"?[+-]?{decimal_digits}
+floating_suffix ([fFdDlL]?[iI]?)|([iI][lLfFdD])
+floating_suffix_opt ("_"?({floating_suffix}|"DL"))?{user_suffix_opt}
 decimal_digits ({decimal})|({decimal}({decimal}|"_")*{decimal})
-real_decimal {decimal_digits}"."{exponent}?{floating_suffix_opt}{user_suffix_opt}
-real_fraction "."{decimal_digits}{exponent}?{floating_suffix_opt}{user_suffix_opt}
-real_constant {decimal_digits}{real_fraction}
-exponent "_"?[eE]"_"?[+-]?{decimal_digits}
-floating_constant (({real_constant}{exponent}?)|({decimal_digits}{exponent})){floating_suffix_opt}{user_suffix_opt}
+floating_decimal {decimal_digits}"."{exponent}?{floating_suffix_opt}
+floating_fraction "."{decimal_digits}{exponent}?{floating_suffix_opt}
+floating_constant ({decimal_digits}{exponent}{floating_suffix_opt})|({decimal_digits}{floating_fraction})
 
 binary_exponent "_"?[pP]"_"?[+-]?{decimal_digits}
-hex_fractional_constant ({hex_digits}?"."{hex_digits})|({hex_digits}".")
-hex_floating_constant {hex_prefix}(({hex_fractional_constant}{binary_exponent})|({hex_digits}{binary_exponent})){floating_suffix_opt}
+hex_floating_suffix_opt ("_"?({floating_suffix}))?{user_suffix_opt}
+hex_floating_fraction ({hex_digits}?"."{hex_digits})|({hex_digits}".")
+hex_floating_constant {hex_prefix}(({hex_floating_fraction}{binary_exponent})|({hex_digits}{binary_exponent})){hex_floating_suffix_opt}
 
 				// character escape sequence, GCC: \e => esc character
 simple_escape "\\"[abefnrtv'"?\\]
-				// ' stop highlighting
+				// ' stop editor highlighting
 octal_escape "\\"{octal}("_"?{octal}){0,2}
 hex_escape "\\""x""_"?{hex_digits}
@@ -154,5 +156,5 @@
 				/* line directives */
 ^{h_white}*"#"{h_white}*[0-9]+{h_white}*["][^"\n]+["].*"\n" {
-	/* " stop highlighting */
+	/* " stop editor highlighting */
 	static char filename[FILENAME_MAX];					// temporarily store current source-file name
 	char *end_num;
@@ -310,6 +312,6 @@
 {octal_constant} { NUMERIC_RETURN(INTEGERconstant); }
 {hex_constant}	{ NUMERIC_RETURN(INTEGERconstant); }
-{real_decimal}	{ NUMERIC_RETURN(REALDECIMALconstant); } // must appear before floating_constant
-{real_fraction}	{ NUMERIC_RETURN(REALFRACTIONconstant); } // must appear before floating_constant
+{floating_decimal}	{ NUMERIC_RETURN(FLOATING_DECIMALconstant); } // must appear before floating_constant
+{floating_fraction}	{ NUMERIC_RETURN(FLOATING_FRACTIONconstant); } // must appear before floating_constant
 {floating_constant}	{ NUMERIC_RETURN(FLOATINGconstant); }
 {hex_floating_constant}	{ NUMERIC_RETURN(FLOATINGconstant); }
@@ -319,5 +321,5 @@
 <QUOTE>[^'\\\n]* { strtext->append( yytext, yyleng ); }
 <QUOTE>['\n]{user_suffix_opt}	{ BEGIN 0; strtext->append( yytext, yyleng ); RETURN_STR(CHARACTERconstant); }
-				/* ' stop highlighting */
+				/* ' stop editor highlighting */
 
 				/* string constant */
@@ -325,5 +327,5 @@
 <STRING>[^"\\\n]* { strtext->append( yytext, yyleng ); }
 <STRING>["\n]{user_suffix_opt}	{ BEGIN 0; strtext->append( yytext, yyleng ); RETURN_STR(STRINGliteral); }
-				/* " stop highlighting */
+				/* " stop editor highlighting */
 
 				/* common character/string constant */
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision e3e16bcf91a7300a6d1f71eaad04e2f3f498cfc2)
+++ src/Parser/parser.yy	(revision 982832e24b58f99cf8d892fbb03bfd2c5cd57b15)
@@ -10,6 +10,6 @@
 // Created On       : Sat Sep  1 20:22:55 2001
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sun Sep  3 20:43:19 2017
-// Update Count     : 2742
+// Last Modified On : Mon Sep 11 18:12:00 2017
+// Update Count     : 2787
 //
 
@@ -43,4 +43,5 @@
 #define YYDEBUG_LEXER_TEXT (yylval)						// lexer loads this up each time
 #define YYDEBUG 1										// get the pretty debugging code to compile
+#define YYERROR_VERBOSE
 
 #undef __GNUC_MINOR__
@@ -62,7 +63,34 @@
 stack< LinkageSpec::Spec > linkageStack;
 
-void appendStr( string *to, string *from ) {
-	// "abc" "def" "ghi" => "abcdefghi", remove new text from quotes and insert before last quote in old string.
-	to->insert( to->length() - 1, from->substr( 1, from->length() - 2 ) );
+bool appendStr( string & to, string & from ) {
+	// 1. Multiple strings are concatenated into a single string but not combined internally. The reason is that
+	//    "\x12" "3" is treated as 2 characters versus 1 because "escape sequences are converted into single members of
+	//    the execution character set just prior to adjacent string literal concatenation" (C11, Section 6.4.5-8). It is
+	//    easier to let the C compiler handle this case.
+	//
+	// 2. String encodings are transformed into canonical form (one encoding at start) so the encoding can be found
+	//    without searching the string, e.g.: "abc" L"def" L"ghi" => L"abc" "def" "ghi". Multiple encodings must match,
+	//    i.e., u"a" U"b" L"c" is disallowed.
+
+	if ( from[0] != '"' ) {								// encoding ?
+		if ( to[0] != '"' ) {							// encoding ?
+			if ( to[0] != from[0] || to[1] != from[1] ) { // different encodings ?
+				yyerror( "non-matching string encodings for string-literal concatenation" );
+				return false;							// parse error, must call YYERROR in action
+			} else if ( from[1] == '8' ) {
+				from.erase( 0, 1 );						// remove 2nd encoding
+			} // if
+		} else {
+			if ( from[1] == '8' ) {						// move encoding to start
+				to = "u8" + to;
+				from.erase( 0, 1 );						// remove 2nd encoding
+			} else {
+				to = from[0] + to;
+			} // if
+		} // if
+		from.erase( 0, 1 );								// remove 2nd encoding
+	} // if
+	to += " " + from;									// concatenated into single string
+	return true;
 } // appendStr
 
@@ -88,4 +116,6 @@
 bool forall = false;									// aggregate have one or more forall qualifiers ?
 %}
+
+%define parse.error verbose
 
 // Types declaration
@@ -146,5 +176,5 @@
 // overloading constants 0/1, e.g., x.1 is lexed as (x)(.1), where (.1) is a factional constant, but is semantically
 // converted into the tuple index (.)(1). e.g., 3.x
-%token<tok>	REALDECIMALconstant	REALFRACTIONconstant	FLOATINGconstant
+%token<tok>	FLOATING_DECIMALconstant	FLOATING_FRACTIONconstant	FLOATINGconstant
 
 // multi-character operators
@@ -315,4 +345,5 @@
 %precedence ELSE	// token precedence for start of else clause in IF/WAITFOR statement
 
+
 %start translation_unit									// parse-tree root
 
@@ -321,7 +352,7 @@
 
 // The grammar in the ANSI C standard is not strictly context-free, since it relies upon the distinct terminal symbols
-// "identifier" and "TYPEDEFname" that are lexically identical.  While it is possible to write a purely context-free
-// grammar, such a grammar would obscure the relationship between syntactic and semantic constructs.  Hence, this
-// grammar uses the ANSI style.
+// "identifier", "TYPEDEFname", and "TYPEGENname" that are lexically identical.  While it is possible to write a purely
+// context-free grammar, such a grammar would obscure the relationship between syntactic and semantic constructs.
+// Hence, this grammar uses the ANSI style.
 //
 // Cforall compounds this problem by introducing type names local to the scope of a declaration (for instance, those
@@ -360,6 +391,6 @@
 		// ENUMERATIONconstant is not included here; it is treated as a variable with type "enumeration constant".
 	INTEGERconstant								{ $$ = new ExpressionNode( build_constantInteger( *$1 ) ); }
-	| REALDECIMALconstant						{ $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }
-	| REALFRACTIONconstant						{ $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }
+	| FLOATING_DECIMALconstant					{ $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }
+	| FLOATING_FRACTIONconstant					{ $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }
 	| FLOATINGconstant							{ $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }
 	| CHARACTERconstant							{ $$ = new ExpressionNode( build_constantChar( *$1 ) ); }
@@ -390,5 +421,5 @@
 	| string_literal_list STRINGliteral
 		{
-			appendStr( $1, $2 );						// append 2nd juxtaposed string to 1st
+			if ( ! appendStr( *$1, *$2 ) ) YYERROR;		// append 2nd juxtaposed string to 1st
 			delete $2;									// allocated by lexer
 			$$ = $1;									// conversion from tok to str
@@ -434,6 +465,6 @@
 	| postfix_expression '.' '[' push field_list pop ']' // CFA, tuple field selector
 		{ $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $5 ) ) ); }
-	| postfix_expression REALFRACTIONconstant			// CFA, tuple index
-		{ $$ = new ExpressionNode( build_fieldSel( $1, build_field_name_REALFRACTIONconstant( *$2 ) ) ); }
+	| postfix_expression FLOATING_FRACTIONconstant		// CFA, tuple index
+		{ $$ = new ExpressionNode( build_fieldSel( $1, build_field_name_FLOATING_FRACTIONconstant( *$2 ) ) ); }
 	| postfix_expression ARROW no_attr_identifier
 		{
@@ -479,8 +510,8 @@
 field:													// CFA, tuple field selector
 	field_name
-	| REALDECIMALconstant field
-		{ $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_REALDECIMALconstant( *$1 ) ), maybeMoveBuild<Expression>( $2 ) ) ); }
-	| REALDECIMALconstant '[' push field_list pop ']'
-		{ $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_REALDECIMALconstant( *$1 ) ), build_tuple( $4 ) ) ); }
+	| FLOATING_DECIMALconstant field
+		{ $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), maybeMoveBuild<Expression>( $2 ) ) ); }
+	| FLOATING_DECIMALconstant '[' push field_list pop ']'
+		{ $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), build_tuple( $4 ) ) ); }
 	| field_name '.' field
 		{ $$ = new ExpressionNode( build_fieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); }
@@ -507,7 +538,7 @@
 	// empty
 		{ $$ = nullptr; }
-	| fraction_constants REALFRACTIONconstant
-		{
-			Expression * constant = build_field_name_REALFRACTIONconstant( *$2 );
+	| fraction_constants FLOATING_FRACTIONconstant
+		{
+			Expression * constant = build_field_name_FLOATING_FRACTIONconstant( *$2 );
 			$$ = $1 != nullptr ? new ExpressionNode( build_fieldSel( $1,  constant ) ) : new ExpressionNode( constant );
 		}
