summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
authorMichi Henning <michi@zeroc.com>2002-07-02 07:36:44 +0000
committerMichi Henning <michi@zeroc.com>2002-07-02 07:36:44 +0000
commite4fe14cf93b5f9dd28027193b7bf9529b218e517 (patch)
treee57f7f9427b2f8ece33b9bb30c67010cef3cb390 /cpp
parentFixed over-zealous case-insensitivity check lookupTypeNoBuiltin, (diff)
downloadice-e4fe14cf93b5f9dd28027193b7bf9529b218e517.tar.bz2
ice-e4fe14cf93b5f9dd28027193b7bf9529b218e517.tar.xz
ice-e4fe14cf93b5f9dd28027193b7bf9529b218e517.zip
Changed [] syntax to disallow empty metadata: you now have to either have
metadata with at least one string in the list, or no metadata at all. Updated scanner so backslash-escaped keywords can be used as identifiers. Removed ''-style strings from scanner -- only ""-style is now legal. Changed string literals to fully conform with ISO-C++ rules. (Not all legal escape sequences were supported previously.) Changed grammar to support concatenation of adjacent string literals. Added support for constants. Parser and scanner are complete, but the action for a constant definition is empty for now. Constant definitions are supported for bool, byte, integers, floating point, strings, and enums. Constants can be defined at global scope and module scope (nowhere else). Syntax follows C++ syntax as much as it makes sense (e.g., the l and u suffixes for integer constants are not supported).
Diffstat (limited to 'cpp')
-rw-r--r--cpp/src/Slice/Grammar.y164
-rw-r--r--cpp/src/Slice/GrammarUtil.h28
-rw-r--r--cpp/src/Slice/Scanner.l160
3 files changed, 315 insertions, 37 deletions
diff --git a/cpp/src/Slice/Grammar.y b/cpp/src/Slice/Grammar.y
index 0a04428c39c..42784f560a1 100644
--- a/cpp/src/Slice/Grammar.y
+++ b/cpp/src/Slice/Grammar.y
@@ -60,6 +60,9 @@ yyerror(const char* s)
%token ICE_OBJECT
%token ICE_LOCAL_OBJECT
%token ICE_LOCAL
+%token ICE_CONST
+%token ICE_FALSE
+%token ICE_TRUE
//
// Other tokens.
@@ -67,6 +70,8 @@ yyerror(const char* s)
%token ICE_SCOPE_DELIMITOR
%token ICE_IDENTIFIER
%token ICE_STRING_LITERAL
+%token ICE_INTEGER_LITERAL
+%token ICE_FLOATING_POINT_LITERAL
//
// One shift/reduce conflict is caused by the presence of ICE_OUT
@@ -103,10 +108,6 @@ meta_data
{
$$ = $2;
}
-| '[' ']'
-{
- $$ = new StringListTok;
-}
|
{
$$ = new StringListTok;
@@ -177,6 +178,9 @@ definition
| enum_def
{
}
+| const_def
+{
+}
;
// ----------------------------------------------------------------------
@@ -1236,16 +1240,30 @@ type
;
// ----------------------------------------------------------------------
+string_literal
+// ----------------------------------------------------------------------
+: ICE_STRING_LITERAL string_literal // Adjacent string literals are concatenated
+{
+ StringTokPtr str1 = StringTokPtr::dynamicCast($1);
+ StringTokPtr str2 = StringTokPtr::dynamicCast($2);
+ str1->v += str2->v;
+}
+| ICE_STRING_LITERAL
+{
+}
+;
+
+// ----------------------------------------------------------------------
string_list
// ----------------------------------------------------------------------
-: ICE_STRING_LITERAL ',' string_list
+: string_literal ',' string_list
{
StringTokPtr str = StringTokPtr::dynamicCast($1);
StringListTokPtr stringList = StringListTokPtr::dynamicCast($3);
stringList->v.push_back(str->v);
$$ = stringList;
}
-| ICE_STRING_LITERAL
+| string_literal
{
StringTokPtr str = StringTokPtr::dynamicCast($1);
StringListTokPtr stringList = new StringListTok;
@@ -1272,6 +1290,131 @@ local
;
// ----------------------------------------------------------------------
+const_type
+// ----------------------------------------------------------------------
+: ICE_BYTE
+{
+}
+//
+// Note ICE_BOOL is deal with in const_def
+//
+| ICE_SHORT
+{
+}
+| ICE_INT
+{
+}
+| ICE_LONG
+{
+}
+| ICE_FLOAT
+{
+}
+| ICE_DOUBLE
+{
+}
+| ICE_STRING
+{
+}
+| ICE_ENUM
+{
+}
+;
+
+// ----------------------------------------------------------------------
+unary_plus_minus
+// ----------------------------------------------------------------------
+: '+'
+{
+ IntegerTokPtr itp = new IntegerTok;
+ itp->v = 1;
+ $$ = itp;
+}
+| '-'
+{
+ IntegerTokPtr itp = new IntegerTok;
+ itp->v = -1;
+ $$ = itp;
+}
+|
+{
+ IntegerTokPtr itp = new IntegerTok;
+ itp->v = 1;
+ $$ = itp;
+}
+;
+
+// ----------------------------------------------------------------------
+numeric_literal
+// ----------------------------------------------------------------------
+: ICE_INTEGER_LITERAL
+{
+}
+| ICE_FLOATING_POINT_LITERAL
+{
+}
+;
+
+// ----------------------------------------------------------------------
+const_literal
+// ----------------------------------------------------------------------
+: unary_plus_minus numeric_literal
+{
+ IntegerTokPtr sign = IntegerTokPtr::dynamicCast($1);
+ IntegerTokPtr integer = IntegerTokPtr::dynamicCast($2);
+ if(integer)
+ {
+ if(sign->v == -1)
+ {
+ if(integer->v < 0 && integer->v == LONG_MIN)
+ {
+ string msg = "integer constant `" + integer->v;
+ msg += "' is too large in magnitude to convert to a positive number";
+ unit->error(msg);
+ }
+ integer->v *= -1;
+ }
+ }
+ else
+ {
+ FloatingTokPtr floating = FloatingTokPtr::dynamicCast($2);
+ assert(floating);
+ floating->v *= sign->v;
+ }
+ $$ = $2;
+}
+| enumerator
+{
+}
+| ICE_STRING_LITERAL
+{
+}
+;
+
+// ----------------------------------------------------------------------
+const_def
+// ----------------------------------------------------------------------
+: ICE_CONST const_type ICE_IDENTIFIER '=' const_literal
+{
+ //
+ //TODO: createConst, including semantic checks
+ //
+}
+| ICE_CONST ICE_BOOL ICE_IDENTIFIER '=' ICE_FALSE
+{
+ //
+ //TODO: createConst, including semantic checks
+ //
+}
+| ICE_CONST ICE_BOOL ICE_IDENTIFIER '=' ICE_TRUE
+{
+ //
+ //TODO: createConst, including semantic checks
+ //
+}
+;
+
+// ----------------------------------------------------------------------
keyword
// ----------------------------------------------------------------------
: ICE_MODULE
@@ -1346,6 +1489,15 @@ keyword
| ICE_LOCAL
{
}
+| ICE_CONST
+{
+}
+| ICE_FALSE
+{
+}
+| ICE_TRUE
+{
+}
;
%%
diff --git a/cpp/src/Slice/GrammarUtil.h b/cpp/src/Slice/GrammarUtil.h
index 591fa976eed..bc349184dc0 100644
--- a/cpp/src/Slice/GrammarUtil.h
+++ b/cpp/src/Slice/GrammarUtil.h
@@ -22,6 +22,8 @@ class StringListTok;
class TypeStringTok;
class TypeStringListTok;
class BoolTok;
+class IntegerTok;
+class FloatingTok;
class ExceptionListTok;
class ClassListTok;
class EnumeratorListTok;
@@ -31,6 +33,8 @@ typedef ::IceUtil::Handle<StringListTok> StringListTokPtr;
typedef ::IceUtil::Handle<TypeStringTok> TypeStringTokPtr;
typedef ::IceUtil::Handle<TypeStringListTok> TypeStringListTokPtr;
typedef ::IceUtil::Handle<BoolTok> BoolTokPtr;
+typedef ::IceUtil::Handle<IntegerTok> IntegerTokPtr;
+typedef ::IceUtil::Handle<FloatingTok> FloatingTokPtr;
typedef ::IceUtil::Handle<ExceptionListTok> ExceptionListTokPtr;
typedef ::IceUtil::Handle<ClassListTok> ClassListTokPtr;
typedef ::IceUtil::Handle<EnumeratorListTok> EnumeratorListTokPtr;
@@ -84,6 +88,30 @@ public:
};
// ----------------------------------------------------------------------
+// IntegerTok
+// ----------------------------------------------------------------------
+
+class SLICE_API IntegerTok : public GrammarBase
+{
+public:
+
+ IntegerTok() { }
+ long v;
+};
+
+// ----------------------------------------------------------------------
+// FloatingTok
+// ----------------------------------------------------------------------
+
+class SLICE_API FloatingTok : public GrammarBase
+{
+public:
+
+ FloatingTok() { }
+ double v;
+};
+
+// ----------------------------------------------------------------------
// BoolTok
// ----------------------------------------------------------------------
diff --git a/cpp/src/Slice/Scanner.l b/cpp/src/Slice/Scanner.l
index 4fdc7b58d59..35264150d91 100644
--- a/cpp/src/Slice/Scanner.l
+++ b/cpp/src/Slice/Scanner.l
@@ -12,6 +12,7 @@
#include <Slice/GrammarUtil.h> // Before Grammer.h, so that YYSTYPE is defined
#include <Slice/Grammar.h>
+#include <math.h>
using namespace std;
using namespace Slice;
@@ -36,6 +37,11 @@ void initScanner();
%option noyywrap
%option never-interactive
+integer_constant (\+|-)?(0[0-7]+)|(0x[[:xdigit:]]+)|([[:digit:]]+)
+fractional_constant ([[:digit:]]*\.[[:digit:]]+)|([[:digit:]]+\.)
+exponent_part (e|E)(\+|-)?[[:digit:]]+
+floating_literal (({fractional_constant}{exponent_part}?)|([[:digit:]]+{exponent_part}))[fFlL]?
+
%%
^"#"[[:blank:]]*[[:digit:]]+[[:blank:]]*$ {
@@ -114,15 +120,17 @@ void initScanner();
\\?[[:alpha:]_][[:alnum:]_]* {
StringTokPtr ident = new StringTok;
- if (*yytext == '\\')
+ if(*yytext == '\\') // Backslash escapes keyword meaning
{
ident->v = yytext + 1;
+ *yylvalp = ident;
+ return ICE_IDENTIFIER;
}
else
{
ident->v = yytext;
+ *yylvalp = ident;
}
- *yylvalp = ident;
StringTokenMap::const_iterator pos = keywordMap.find(ident->v);
if(pos != keywordMap.end())
@@ -141,7 +149,6 @@ void initScanner();
}
\" {
- // "..."-type strings
StringTokPtr str = new StringTok;
while(true)
{
@@ -152,13 +159,12 @@ void initScanner();
}
else if(c == EOF)
{
- unit->warning("EOF in string");
+ unit->error("EOF in string");
break;
}
else if(c == '\n')
{
- str->v += c;
- unit->nextLine();
+ unit->error("newline in string");
}
else if(c == '\\')
{
@@ -167,6 +173,7 @@ void initScanner();
{
case '\\':
case '"':
+ case '\'':
{
str->v += next;
break;
@@ -201,6 +208,77 @@ void initScanner();
str->v += '\f';
break;
}
+
+ case 'a':
+ {
+ str->v += '\a';
+ break;
+ }
+
+ case 'b':
+ {
+ str->v += '\b';
+ break;
+ }
+
+ case '?':
+ {
+ str->v += '\?';
+ break;
+ }
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ {
+ static string octalDigits = "01234567";
+ unsigned short us = next - '0';
+ if(octalDigits.find_first_of(next = static_cast<char>(yyinput())) != string::npos)
+ {
+ us = us * 8 + next - '0';
+ if(octalDigits.find_first_of(next = static_cast<char>(yyinput())) != string::npos)
+ {
+ us = us * 8 + next - '0';
+ }
+ else
+ {
+ unput(next);
+ }
+ }
+ else
+ {
+ unput(next);
+ }
+ str->v += static_cast<char>(us);
+ break;
+ }
+ case 'x':
+ {
+ unsigned long ul = 0;
+ next = static_cast<char>(yyinput());
+ if(isxdigit(next))
+ {
+ ul *= 16;
+ if(isdigit(next))
+ {
+ ul += next - '0';
+ }
+ else if(islower(next))
+ {
+ ul += next - 'a';
+ }
+ else
+ {
+ ul += next - 'A';
+ }
+ }
+ unput(next);
+ str->v += static_cast<char>(ul);
+ break;
+ }
+
+ // TODO: add universal character names
default:
{
@@ -218,33 +296,50 @@ void initScanner();
return ICE_STRING_LITERAL;
}
-\' {
- // '...'-type strings
- StringTokPtr str = new StringTok;
- while(true)
+{integer_constant} {
+ IntegerTokPtr itp = new IntegerTok;
+ *yylvalp = itp;
+ errno = 0;
+ itp->v = strtol(yytext, 0, 0);
+//
+// TODO: strtol() is broken under gcc: it returns an error for -2147483648 (but shouldn't)
+//
+ if(errno == ERANGE && (itp->v == LONG_MAX || itp->v == LONG_MIN))
{
- char c = static_cast<char>(yyinput());
- if(c == '\'')
- {
- break;
- }
- else if(c == EOF)
- {
- unit->warning("EOF in string");
- break;
- }
- else if(c == '\n')
- {
- str->v += c;
- unit->nextLine();
- }
- else
- {
- str->v += c;
- }
+ string msg = "integer constant `";
+ msg += yytext;
+ msg += "' too ";
+ msg += itp->v == LONG_MAX ? "large (overflow)" : "small (underflow)";
+ unit->error(msg);
}
- *yylvalp = str;
- return ICE_STRING_LITERAL;
+ return ICE_INTEGER_LITERAL;
+}
+
+{floating_literal} {
+ FloatingTokPtr ftp = new FloatingTok;
+ *yylvalp = ftp;
+ errno = 0;
+ ftp->v = strtod(yytext, 0);
+ //
+ // TODO: think about what to do with infinity and NaN. Probably nothing because the slice compiler
+ // doesn't necessarily run on the same architecture as the compiled stubs/skeletons, but NaN and INF are
+ // architecture dependent...
+ //
+ if((ftp->v == HUGE_VAL || ftp->v == -HUGE_VAL) && errno == ERANGE)
+ {
+ string msg = "floating-point constant `";
+ msg += yytext;
+ msg += "' too large (overflow)";
+ unit->error(msg);
+ }
+ else if(ftp->v == 0 && errno == ERANGE)
+ {
+ string msg = "floating-point constant `";
+ msg += yytext;
+ msg += "' too small (underflow)";
+ unit->error(msg);
+ }
+ return ICE_FLOATING_POINT_LITERAL;
}
[[:space:]] {
@@ -295,6 +390,9 @@ initScanner()
keywordMap["Object"] = ICE_OBJECT;
keywordMap["LocalObject"] = ICE_LOCAL_OBJECT;
keywordMap["local"] = ICE_LOCAL;
+ keywordMap["const"] = ICE_CONST;
+ keywordMap["false"] = ICE_FALSE;
+ keywordMap["true"] = ICE_TRUE;
}
}