Skip to content

Commit ce7029f

Browse files
committed
ansi-c: introduce conditional_keyword(c, t)
This introduces a helper function in the C scanner to deal with a larger number of cases to enable or disable keywords of the various C/C++ dialects.
1 parent 10a14c9 commit ce7029f

File tree

1 file changed

+109
-117
lines changed

1 file changed

+109
-117
lines changed

src/ansi-c/scanner.l

+109-117
Original file line numberDiff line numberDiff line change
@@ -149,26 +149,17 @@ int MSC_Keyword(int token)
149149
return make_identifier();
150150
}
151151

152-
int cpp98_keyword(int token)
152+
/// Exits the scanner with the current yytext. If the condition holds,
153+
/// yytext is returned as keyword, and otherwise as an identifier.
154+
int conditional_keyword(bool condition, int token)
153155
{
154-
if(PARSER.cpp98)
156+
if(condition)
155157
{
156158
loc();
157159
return token;
158160
}
159161
else
160-
return make_identifier();
161-
}
162-
163-
int cpp11_keyword(int token)
164-
{
165-
if(PARSER.cpp11)
166-
{
167-
loc();
168-
return token;
169-
}
170-
else
171-
return make_identifier();
162+
return make_identifier();
172163
}
173164

174165
int MSC_cpp_keyword(int token)
@@ -843,75 +834,73 @@ enable_or_disable ("enable"|"disable")
843834
/* C++ Keywords and Operators */
844835
%}
845836

846-
alignas { return cpp11_keyword(TOK_ALIGNAS); } // C++11
847-
alignof { return cpp11_keyword(TOK_ALIGNOF); } // C++11
848-
and { return cpp98_keyword(TOK_ANDAND); }
849-
and_eq { return cpp98_keyword(TOK_ANDASSIGN); }
850-
bool { return cpp98_keyword(TOK_BOOL); }
851-
catch { return cpp98_keyword(TOK_CATCH); }
837+
alignas { return conditional_keyword(PARSER.cpp11, TOK_ALIGNAS); } // C++11
838+
alignof { return conditional_keyword(PARSER.cpp11, TOK_ALIGNOF); } // C++11
839+
and { return conditional_keyword(PARSER.cpp98, TOK_ANDAND); }
840+
and_eq { return conditional_keyword(PARSER.cpp98, TOK_ANDASSIGN); }
841+
bool { return conditional_keyword(PARSER.cpp98, TOK_BOOL); }
842+
catch { return conditional_keyword(PARSER.cpp98, TOK_CATCH); }
852843
char16_t { // C++11, but Visual Studio uses typedefs
853-
if(PARSER.mode == configt::ansi_ct::flavourt::VISUAL_STUDIO)
854-
return make_identifier();
855-
else
856-
return cpp11_keyword(TOK_CHAR16_T);
844+
return conditional_keyword(
845+
PARSER.cpp11 &&
846+
PARSER.mode != configt::ansi_ct::flavourt::VISUAL_STUDIO,
847+
TOK_CHAR16_T);
857848
}
858849
char32_t { // C++11, but Visual Studio uses typedefs
859-
if(PARSER.mode == configt::ansi_ct::flavourt::VISUAL_STUDIO)
860-
return make_identifier();
861-
else
862-
return cpp11_keyword(TOK_CHAR32_T);
850+
return conditional_keyword(
851+
PARSER.cpp11 &&
852+
PARSER.mode != configt::ansi_ct::flavourt::VISUAL_STUDIO,
853+
TOK_CHAR32_T);
863854
}
864-
class { return cpp98_keyword(TOK_CLASS); }
865-
compl { return cpp98_keyword('~'); }
866-
constexpr { return cpp11_keyword(TOK_CONSTEXPR); } // C++11
867-
delete { return cpp98_keyword(TOK_DELETE); }
868-
decltype { return cpp11_keyword(TOK_DECLTYPE); } // C++11
869-
explicit { return cpp98_keyword(TOK_EXPLICIT); }
870-
false { return cpp98_keyword(TOK_FALSE); }
871-
friend { return cpp98_keyword(TOK_FRIEND); }
872-
mutable { return cpp98_keyword(TOK_MUTABLE); }
873-
namespace { return cpp98_keyword(TOK_NAMESPACE); }
874-
new { return cpp98_keyword(TOK_NEW); }
875-
nodiscard { return cpp11_keyword(TOK_NODISCARD); } // C++11
876-
noexcept { return cpp11_keyword(TOK_NOEXCEPT); } // C++11
877-
noreturn { return cpp11_keyword(TOK_NORETURN); } // C++11
878-
not { return cpp98_keyword('!'); }
879-
not_eq { return cpp98_keyword(TOK_NE); }
880-
nullptr { return cpp11_keyword(TOK_NULLPTR); } // C++11
881-
operator { return cpp98_keyword(TOK_OPERATOR); }
882-
or { return cpp98_keyword(TOK_OROR); }
883-
or_eq { return cpp98_keyword(TOK_ORASSIGN); }
884-
private { return cpp98_keyword(TOK_PRIVATE); }
885-
protected { return cpp98_keyword(TOK_PROTECTED); }
886-
public { return cpp98_keyword(TOK_PUBLIC); }
855+
class { return conditional_keyword(PARSER.cpp98, TOK_CLASS); }
856+
compl { return conditional_keyword(PARSER.cpp98, '~'); }
857+
constexpr { return conditional_keyword(PARSER.cpp11, TOK_CONSTEXPR); } // C++11
858+
delete { return conditional_keyword(PARSER.cpp98, TOK_DELETE); }
859+
decltype { return conditional_keyword(PARSER.cpp11, TOK_DECLTYPE); } // C++11
860+
explicit { return conditional_keyword(PARSER.cpp98, TOK_EXPLICIT); }
861+
false { return conditional_keyword(PARSER.cpp98, TOK_FALSE); }
862+
friend { return conditional_keyword(PARSER.cpp98, TOK_FRIEND); }
863+
mutable { return conditional_keyword(PARSER.cpp98, TOK_MUTABLE); }
864+
namespace { return conditional_keyword(PARSER.cpp98, TOK_NAMESPACE); }
865+
new { return conditional_keyword(PARSER.cpp98, TOK_NEW); }
866+
nodiscard { return conditional_keyword(PARSER.cpp11, TOK_NODISCARD); } // C++11
867+
noexcept { return conditional_keyword(PARSER.cpp11, TOK_NOEXCEPT); } // C++11
868+
noreturn { return conditional_keyword(PARSER.cpp11, TOK_NORETURN); } // C++11
869+
not { return conditional_keyword(PARSER.cpp98, '!'); }
870+
not_eq { return conditional_keyword(PARSER.cpp98, TOK_NE); }
871+
nullptr { return conditional_keyword(PARSER.cpp11, TOK_NULLPTR); } // C++11
872+
operator { return conditional_keyword(PARSER.cpp98, TOK_OPERATOR); }
873+
or { return conditional_keyword(PARSER.cpp98, TOK_OROR); }
874+
or_eq { return conditional_keyword(PARSER.cpp98, TOK_ORASSIGN); }
875+
private { return conditional_keyword(PARSER.cpp98, TOK_PRIVATE); }
876+
protected { return conditional_keyword(PARSER.cpp98, TOK_PROTECTED); }
877+
public { return conditional_keyword(PARSER.cpp98, TOK_PUBLIC); }
887878
static_assert { // C++11, but Visual Studio supports it in all modes
888879
// as a keyword, even though the documentation claims
889880
// it's a macro.
890-
if(PARSER.mode == configt::ansi_ct::flavourt::VISUAL_STUDIO)
891-
{
892-
loc(); return TOK_STATIC_ASSERT;
893-
}
894-
else
895-
return cpp11_keyword(TOK_STATIC_ASSERT);
881+
return conditional_keyword(
882+
PARSER.cpp11 ||
883+
PARSER.mode == configt::ansi_ct::flavourt::VISUAL_STUDIO,
884+
TOK_STATIC_ASSERT);
896885
}
897-
template { return cpp98_keyword(TOK_TEMPLATE); }
898-
this { return cpp98_keyword(TOK_THIS); }
899-
thread_local { return cpp11_keyword(TOK_THREAD_LOCAL); } // C++11
900-
throw { return cpp98_keyword(TOK_THROW); }
901-
true { return cpp98_keyword(TOK_TRUE); }
902-
typeid { return cpp98_keyword(TOK_TYPEID); }
903-
typename { return cpp98_keyword(TOK_TYPENAME); }
904-
using { return cpp98_keyword(TOK_USING); }
905-
virtual { return cpp98_keyword(TOK_VIRTUAL); }
886+
template { return conditional_keyword(PARSER.cpp98, TOK_TEMPLATE); }
887+
this { return conditional_keyword(PARSER.cpp98, TOK_THIS); }
888+
thread_local { return conditional_keyword(PARSER.cpp11, TOK_THREAD_LOCAL); } // C++11
889+
throw { return conditional_keyword(PARSER.cpp98, TOK_THROW); }
890+
true { return conditional_keyword(PARSER.cpp98, TOK_TRUE); }
891+
typeid { return conditional_keyword(PARSER.cpp98, TOK_TYPEID); }
892+
typename { return conditional_keyword(PARSER.cpp98, TOK_TYPENAME); }
893+
using { return conditional_keyword(PARSER.cpp98, TOK_USING); }
894+
virtual { return conditional_keyword(PARSER.cpp98, TOK_VIRTUAL); }
906895
wchar_t { // CodeWarrior doesn't have wchar_t built in,
907896
// and MSC has a command-line option to turn it off
908-
if(PARSER.mode==configt::ansi_ct::flavourt::CODEWARRIOR)
909-
return make_identifier();
910-
else
911-
return cpp98_keyword(TOK_WCHAR_T);
897+
return conditional_keyword(
898+
PARSER.cpp98 &&
899+
PARSER.mode!=configt::ansi_ct::flavourt::CODEWARRIOR,
900+
TOK_WCHAR_T);
912901
}
913-
xor { return cpp98_keyword('^'); }
914-
xor_eq { return cpp98_keyword(TOK_XORASSIGN); }
902+
xor { return conditional_keyword(PARSER.cpp98, '^'); }
903+
xor_eq { return conditional_keyword(PARSER.cpp98, TOK_XORASSIGN); }
915904
".*" { return cpp_operator(TOK_DOTPM); }
916905
"->*" { return cpp_operator(TOK_ARROWPM); }
917906
"::" { if(PARSER.cpp98)
@@ -925,12 +914,11 @@ xor_eq { return cpp98_keyword(TOK_XORASSIGN); }
925914
}
926915
}
927916

928-
__decltype { if(PARSER.cpp98 &&
929-
(PARSER.mode==configt::ansi_ct::flavourt::GCC ||
930-
PARSER.mode==configt::ansi_ct::flavourt::CLANG))
931-
return cpp98_keyword(TOK_DECLTYPE);
932-
else
933-
return make_identifier();
917+
__decltype { return conditional_keyword(
918+
PARSER.cpp98 &&
919+
(PARSER.mode==configt::ansi_ct::flavourt::GCC ||
920+
PARSER.mode==configt::ansi_ct::flavourt::CLANG),
921+
TOK_DECLTYPE);
934922
}
935923

936924
%{
@@ -943,35 +931,35 @@ __decltype { if(PARSER.cpp98 &&
943931
"__has_assign" { loc(); return MSC_cpp_keyword(TOK_UNARY_TYPE_PREDICATE); }
944932
"__has_copy" { loc(); return MSC_cpp_keyword(TOK_UNARY_TYPE_PREDICATE); }
945933
"__has_finalizer" { loc(); return MSC_cpp_keyword(TOK_UNARY_TYPE_PREDICATE); }
946-
"__has_nothrow_assign" { loc(); return cpp98_keyword(TOK_UNARY_TYPE_PREDICATE); }
947-
"__has_nothrow_constructor" { loc(); return cpp98_keyword(TOK_UNARY_TYPE_PREDICATE); }
948-
"__has_nothrow_copy" { loc(); return cpp98_keyword(TOK_UNARY_TYPE_PREDICATE); }
949-
"__has_trivial_assign" { loc(); return cpp98_keyword(TOK_UNARY_TYPE_PREDICATE); }
950-
"__has_trivial_constructor" { loc(); return cpp98_keyword(TOK_UNARY_TYPE_PREDICATE); }
951-
"__has_trivial_copy" { loc(); return cpp98_keyword(TOK_UNARY_TYPE_PREDICATE); }
952-
"__has_trivial_destructor" { loc(); return cpp98_keyword(TOK_UNARY_TYPE_PREDICATE); }
934+
"__has_nothrow_assign" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNARY_TYPE_PREDICATE); }
935+
"__has_nothrow_constructor" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNARY_TYPE_PREDICATE); }
936+
"__has_nothrow_copy" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNARY_TYPE_PREDICATE); }
937+
"__has_trivial_assign" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNARY_TYPE_PREDICATE); }
938+
"__has_trivial_constructor" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNARY_TYPE_PREDICATE); }
939+
"__has_trivial_copy" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNARY_TYPE_PREDICATE); }
940+
"__has_trivial_destructor" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNARY_TYPE_PREDICATE); }
953941
"__has_user_destructor" { loc(); return MSC_cpp_keyword(TOK_UNARY_TYPE_PREDICATE); }
954-
"__has_virtual_destructor" { loc(); return cpp98_keyword(TOK_UNARY_TYPE_PREDICATE); }
955-
"__is_abstract" { loc(); return cpp98_keyword(TOK_UNARY_TYPE_PREDICATE); }
956-
"__is_base_of" { loc(); return cpp98_keyword(TOK_BINARY_TYPE_PREDICATE); }
957-
"__is_class" { loc(); return cpp98_keyword(TOK_UNARY_TYPE_PREDICATE); }
958-
"__is_convertible_to" { loc(); return cpp98_keyword(TOK_BINARY_TYPE_PREDICATE); }
942+
"__has_virtual_destructor" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNARY_TYPE_PREDICATE); }
943+
"__is_abstract" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNARY_TYPE_PREDICATE); }
944+
"__is_base_of" { loc(); return conditional_keyword(PARSER.cpp98, TOK_BINARY_TYPE_PREDICATE); }
945+
"__is_class" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNARY_TYPE_PREDICATE); }
946+
"__is_convertible_to" { loc(); return conditional_keyword(PARSER.cpp98, TOK_BINARY_TYPE_PREDICATE); }
959947
"__is_delegate" { loc(); return MSC_cpp_keyword(TOK_UNARY_TYPE_PREDICATE); }
960-
"__is_empty" { loc(); return cpp98_keyword(TOK_UNARY_TYPE_PREDICATE); }
961-
"__is_enum" { loc(); return cpp98_keyword(TOK_UNARY_TYPE_PREDICATE); }
962-
"__is_interface_class" { loc(); return cpp98_keyword(TOK_UNARY_TYPE_PREDICATE); }
963-
"__is_pod" { loc(); return cpp98_keyword(TOK_UNARY_TYPE_PREDICATE); }
964-
"__is_polymorphic" { loc(); return cpp98_keyword(TOK_UNARY_TYPE_PREDICATE); }
948+
"__is_empty" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNARY_TYPE_PREDICATE); }
949+
"__is_enum" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNARY_TYPE_PREDICATE); }
950+
"__is_interface_class" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNARY_TYPE_PREDICATE); }
951+
"__is_pod" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNARY_TYPE_PREDICATE); }
952+
"__is_polymorphic" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNARY_TYPE_PREDICATE); }
965953
"__is_ref_array" { loc(); return MSC_cpp_keyword(TOK_UNARY_TYPE_PREDICATE); }
966954
"__is_ref_class" { loc(); return MSC_cpp_keyword(TOK_UNARY_TYPE_PREDICATE); }
967955
"__is_sealed" { loc(); return MSC_cpp_keyword(TOK_UNARY_TYPE_PREDICATE); }
968956
"__is_simple_value_class" { loc(); return MSC_cpp_keyword(TOK_UNARY_TYPE_PREDICATE); }
969-
"__is_union" { loc(); return cpp98_keyword(TOK_UNARY_TYPE_PREDICATE); }
957+
"__is_union" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNARY_TYPE_PREDICATE); }
970958
"__is_value_class" { loc(); return MSC_cpp_keyword(TOK_UNARY_TYPE_PREDICATE); }
971959

972960
"__if_exists" { loc(); return MSC_cpp_keyword(TOK_MSC_IF_EXISTS); }
973961
"__if_not_exists" { loc(); return MSC_cpp_keyword(TOK_MSC_IF_NOT_EXISTS); }
974-
"__underlying_type" { loc(); return cpp98_keyword(TOK_UNDERLYING_TYPE); }
962+
"__underlying_type" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNDERLYING_TYPE); }
975963

976964
"["{ws}"repeatable" |
977965
"["{ws}"source_annotation_attribute" |
@@ -994,32 +982,36 @@ __decltype { if(PARSER.cpp98 &&
994982
}
995983
}
996984

997-
"__char16_t" { if(PARSER.mode==configt::ansi_ct::flavourt::GCC ||
998-
PARSER.mode==configt::ansi_ct::flavourt::CLANG)
999-
return cpp98_keyword(TOK_CHAR16_T); // GNU extension
1000-
else
1001-
return make_identifier();
985+
"__char16_t" { // GNU extension
986+
return conditional_keyword(
987+
PARSER.cpp98 &&
988+
(PARSER.mode==configt::ansi_ct::flavourt::GCC ||
989+
PARSER.mode==configt::ansi_ct::flavourt::CLANG),
990+
TOK_CHAR16_T);
1002991
}
1003992

1004-
"__nullptr" { if(PARSER.mode==configt::ansi_ct::flavourt::GCC ||
1005-
PARSER.mode==configt::ansi_ct::flavourt::CLANG)
1006-
return cpp98_keyword(TOK_NULLPTR); // GNU extension
1007-
else
1008-
return make_identifier();
993+
"__nullptr" { // GNU extension
994+
return conditional_keyword(
995+
PARSER.cpp98 &&
996+
(PARSER.mode==configt::ansi_ct::flavourt::GCC ||
997+
PARSER.mode==configt::ansi_ct::flavourt::CLANG),
998+
TOK_NULLPTR);
1009999
}
10101000

1011-
"__null" { if(PARSER.mode==configt::ansi_ct::flavourt::GCC ||
1012-
PARSER.mode==configt::ansi_ct::flavourt::CLANG)
1013-
return cpp98_keyword(TOK_NULLPTR); // GNU extension
1014-
else
1015-
return make_identifier();
1001+
"__null" { // GNU extension
1002+
return conditional_keyword(
1003+
PARSER.cpp98 &&
1004+
(PARSER.mode==configt::ansi_ct::flavourt::GCC ||
1005+
PARSER.mode==configt::ansi_ct::flavourt::CLANG),
1006+
TOK_NULLPTR);
10161007
}
10171008

1018-
"__char32_t" { if(PARSER.mode==configt::ansi_ct::flavourt::GCC ||
1019-
PARSER.mode==configt::ansi_ct::flavourt::CLANG)
1020-
return cpp98_keyword(TOK_CHAR32_T); // GNU extension
1021-
else
1022-
return make_identifier();
1009+
"__char32_t" { // GNU extension
1010+
return conditional_keyword(
1011+
PARSER.cpp98 &&
1012+
(PARSER.mode==configt::ansi_ct::flavourt::GCC ||
1013+
PARSER.mode==configt::ansi_ct::flavourt::CLANG),
1014+
TOK_CHAR32_T);
10231015
}
10241016

10251017
"__declspec" |

0 commit comments

Comments
 (0)