WIP: adjusting simple parser for C++17 (somewhat)

This commit is contained in:
Matthias Koefferlein 2021-11-27 00:08:50 +01:00
parent f4c0a43d49
commit aeba3f5df8
5 changed files with 85 additions and 53 deletions

View File

@ -7,13 +7,14 @@
# framework is based on a C++ parser and a configuration file that specifies details
# about the translation.
#
# By default, the script will take the Qt headers from /opt/qt/4.6.3 and /opt/qt/5.5.1
# for Qt4 and Qt5 respectively.
# By default, the script will take the Qt headers from /opt/qt/4.6.3, /opt/qt/5.5.1
# and /opt/qt/6.2.1 for Qt4, Qt5 and Qt6 respectively.
#
# Call it from project level as
#
# ./scripts/mkqtdecl.sh -update # Qt4
# ./scripts/mkqtdecl.sh -update -qt5 # Qt5
# ./scripts/mkqtdecl.sh -update -qt6 # Qt6
#
# For more options see
#
@ -43,14 +44,18 @@ diff=0
reuse=0
qt="/opt/qt/4.6.3/include"
qt5="/opt/qt/5.5.1/include"
qt6="/opt/qt/6.2.1/include"
inst_dir_common=`pwd`/scripts/mkqtdecl_common
inst_dir4=`pwd`/scripts/mkqtdecl4
inst_dir5=`pwd`/scripts/mkqtdecl5
inst_dir6=`pwd`/scripts/mkqtdecl6
src_dir=`pwd`/src
src_name4=gsiqt/qt4
src_name5=gsiqt/qt5
src_name6=gsiqt/qt6
qt_mods4="QtCore QtGui QtDesigner QtNetwork QtSql QtXml QtUiTools"
qt_mods5="QtCore QtGui QtWidgets QtDesigner QtNetwork QtPrintSupport QtSql QtSvg QtXml QtXmlPatterns QtMultimedia QtUiTools"
qt_mods6="QtCore QtGui QtWidgets QtDesigner QtNetwork QtPrintSupport QtSql QtSvg QtXml QtMultimedia QtUiTools QtCore5Compat"
src_name=$src_name4
inst_dir=$inst_dir4
@ -73,6 +78,7 @@ while [ "$1" != "" ]; do
echo " mkqtdecl.sh -diff Show differences - don't produce and don't synchronize"
echo " mkqtdecl.sh -qt path_to_include Use the specified include path"
echo " mkqtdecl.sh -qt5 Use setup for Qt 5.x (use before -qt)"
echo " mkqtdecl.sh -qt6 Use setup for Qt 6.x (use before -qt)"
echo " mkqtdecl.sh -reuse Don't parse C++ container again"
exit 0
;;
@ -102,6 +108,13 @@ while [ "$1" != "" ]; do
qt_mods="$qt_mods5"
src_name="$src_name5"
;;
-qt6)
qt="$qt6"
work_dir="mkqtdecl6.tmp"
inst_dir="$inst_dir6"
qt_mods="$qt_mods6"
src_name="$src_name6"
;;
*)
echo "*** ERROR: unknown command option $a"
exit 1
@ -181,7 +194,7 @@ if [ $update != 0 ]; then
echo "Running gcc preprocessor .."
# By using -D_GCC_LIMITS_H_ we make the gcc not include constants such as ULONG_MAX which will
# remain as such. This way the generated code is more generic.
gcc -std=gnu++98 -I$qt -fPIC -D_GCC_LIMITS_H_ -E -o allofqt.x allofqt.cpp
gcc -std=c++17 -I$qt -fPIC -D_GCC_LIMITS_H_ -E -o allofqt.x allofqt.cpp
echo "Stripping hash lines .."
egrep -v '^#' <allofqt.x >allofqt.e

View File

@ -50,7 +50,29 @@ grammar CPP
end
rule a
s ( "__attribute__" s attribute_value s / "__asm" s attribute_value s / "__extension__" s / "decltype" s attribute_value s )*
s ( "__attribute__" s attribute_value s /
"__asm" s attribute_value s /
"constexpr" ![a-zA-Z0-9_] s /
"__extension__" s /
"__inline" s /
"__m64" s /
"__m128" s /
"__m128d" s /
"__m128i" s /
"__m256" s /
"__m256d" s /
"__m256i" s /
"__m512" s /
"__m512d" s /
"__m512i" s /
"__mmask8" s /
"__mmask16" s /
"__v8df" s /
"__v8di" s /
"__v16sf" s /
"__v16si" s /
"decltype" s attribute_value s /
"[[" s block s "]]" s )*
end
rule unary_op
@ -147,13 +169,15 @@ grammar CPP
rule member_declaration_wo_semicolon
template:( d:template_decl s )?
attr:( ( explicit_key / mutable_key / storage_class / inline_spec / virtual_spec / constexpr_key ) s )*
a
attr:( ( explicit_key / mutable_key / storage_class / inline_spec / virtual_spec ) s )*
t:type
# type declaration ends with a } .. does not need a semicolon
# (i.e. nested struct or enum)
&{ |seq| seq[-1].text_value_ends_with_curly_brace }
s
( ":" s block_wo_curly_braces s )?
( trailing_return_type )?
a
(
"{" s block s "}" /
@ -163,13 +187,15 @@ grammar CPP
rule member_declaration_w_semicolon
template:( d:template_decl s )?
attr:( ( explicit_key / mutable_key / storage_class / inline_spec / virtual_spec / constexpr_key ) s )*
a
attr:( ( explicit_key / mutable_key / storage_class / inline_spec / virtual_spec ) s )*
t:type
# opposite case (member_see declaration_wo_semicolon)
# (i.e. nested struct or enum)
!{ |seq| seq[-1].text_value_ends_with_curly_brace }
s
( ":" s block_wo_curly_braces s )?
( trailing_return_type )?
a
(
"{" s block s "}" /
@ -202,7 +228,7 @@ grammar CPP
# In order to easily distinguish between constructor methods without
# a return type and class or typedef names we assume that all "name("
# constructs are considered constructor names but "name (*func_ptr) ()" is not.
qualified_id s !( "(" !( s "*" ) )
qualified_id s ( "..." s )? !( "(" !( s "*" ) )
end
rule typeof
@ -222,11 +248,11 @@ grammar CPP
end
rule concrete_type
( constexpr_key / class_or_struct_type / enum_type / float_type / char_type / int_type / bool_type / void_type / typeof / class_id )?
( class_or_struct_type / enum_type / float_type / char_type / int_type / bool_type / void_type / typeof / class_id )?
end
rule cv
( constexpr_key / "const" ![a-zA-Z0-9_] / "__const" ![a-zA-Z0-9_] / "volatile" ![a-zA-Z0-9_] / "__volatile" ![a-zA-Z0-9_] ) <PCV>
( "const" ![a-zA-Z0-9_] / "__const" ![a-zA-Z0-9_] / "volatile" ![a-zA-Z0-9_] / "__volatile" ![a-zA-Z0-9_] ) <PCV>
end
rule pointer
@ -256,11 +282,15 @@ grammar CPP
end
rule noexcept_spec
"noexcept" ( s "=" s block / s "(" s block ")" )?
"noexcept" ( s "(" s block s ")" )?
end
rule func_assign_spec
"=" s ( "delete" / "0" )?
end
rule func_spec
"(" s fa:( a:func_args )? s ")" cvspec:( s cv:cv )? ( s "throw" s "(" s ( type_wo_comma s )? ")" / s noexcept_spec )* ( s override_key )? a <PFuncSpec>
"(" s fa:( a:func_args )? s ")" cvspec:( s cv:cv )? ( s "throw" s "(" s ( type_wo_comma s )? ")" / s noexcept_spec / s func_assign_spec / s override_key )* a <PFuncSpec>
end
rule member_pointer
@ -278,7 +308,7 @@ grammar CPP
pointer /
reference /
member_pointer /
( "__restrict" ![a-zA-Z0-9_] s )? qualified_id
( "__restrict" ![a-zA-Z0-9_] s / "..." s )* qualified_id
)
pfx:( s spec:( array_spec / func_spec ) )*
<PInnerType>
@ -310,7 +340,7 @@ grammar CPP
rule type_for_template
cvspec:( cv:cv s )?
a
( "typename" ![a-zA-Z0-9_] s )?
( ( "typename" / "class" ) ![a-zA-Z0-9_] s ( "..." s )? )?
ct:concrete_type
il:( s t:inner_type )?
<PTypeForTemplate>
@ -324,19 +354,15 @@ grammar CPP
"override" ![a-zA-Z0-9_]
end
rule constexpr_key
"constexpr" ![a-zA-Z0-9_]
end
rule inline_spec
"inline" ![a-zA-Z0-9_] <PInline>
end
# parse over blocks as gracefully as possible ...
rule block_atom_wo_gt
"(" s block s ")" / "[" s block s "]" / "<" s block_wo_gt ( s "," s block_wo_gt )* s ">" /
"(" s block s ")" / "[" s block s "]" / "<" !"=" s block_wo_gt ( s "," s block_wo_gt )* s ">" /
numeric_const / hex_const / string_const / char_const /
id / unary_op / bin_op_wo_gt / "?" / "::" / "." / ":" / ";"
id ( s "{" s block s "}" )? / unary_op / bin_op_wo_gt / "?" / "::" / "." / ":" / ";"
end
rule block_wo_gt
@ -347,7 +373,7 @@ grammar CPP
rule block_atom
"(" s block s ")" / "[" s block s "]" / "<" s block_wo_gt ( s "," s block_wo_gt )* s ">" /
numeric_const / hex_const / string_const / char_const /
id / unary_op / bin_op / "?" / "::" / "." / ":"
id ( s "{" s block s "}" )? / unary_op / bin_op / "?" / "::" / "." / ":"
end
rule block
@ -375,25 +401,29 @@ grammar CPP
end
rule template_decl_arg
( "class" / "typename" ) ![a-zA-Z0-9_] s id:id dtspec:( s "=" s dt:type_for_template )? <PClassTemplateArg> /
t:type_for_template initspec:( s "=" s init:block_wo_gt )? <PDirectTemplateArg>
t:type_for_template dtspec:( s "=" s dt:block_wo_gt )? <PClassTemplateArg>
end
rule template_decl
"template" s "<" s ( !">" template_decl_arg s ( "," s template_decl_arg )* )? s ">" <PTemplateDecl>
end
rule trailing_return_type
"->" s ( "decltype" s "(" s block s ")" / type )
end
rule declaration_w_semicolon
template:( d:template_decl s )?
template_member:( d_member:template_decl s )?
attr:( ( storage_class / inline_spec / constexpr_key ) s )*
a
( constexpr_key s )?
attr:( ( storage_class / inline_spec ) s )*
a
t:type
# type declaration ends with a } .. does not need a semicolon
# (i.e. nested struct or enum)
!{ |seq| seq[-1].text_value_ends_with_curly_brace }
s ( ":" s block_wo_curly_braces s )?
( trailing_return_type )?
a
(
"{" s block s "}" /
@ -403,14 +433,15 @@ grammar CPP
rule declaration_wo_semicolon
template:( d:template_decl s )?
attr:( ( storage_class / inline_spec / constexpr_key ) s )*
a
( constexpr_key s )?
attr:( ( storage_class / inline_spec ) s )*
a
t:type
# opposite case (see declaration_wo_semicolon)
# (i.e. nested struct or enum)
&{ |seq| seq[-1].text_value_ends_with_curly_brace }
s ( ":" s block_wo_curly_braces s )?
( trailing_return_type )?
a
(
"{" s block s "}" /
@ -432,8 +463,12 @@ grammar CPP
a "{" decls:( a ( ";" / typedef / namespace / extern_decl / declaration ) )* s "}" <PExternBlock>
end
rule asm
"asm" s "(" s block s ")"
end
rule module
( a ( ";" / static_assert / using / typedef / namespace / extern_decl / declaration ) )* s <PModule>
( a ( ";" / static_assert / using / typedef / namespace / extern_decl / declaration / asm ) )* s <PModule>
end
end

View File

@ -469,29 +469,19 @@ class CPPFriendDecl < CPPObject
end
# @brief A type template argument (with an optional initializer)
# @attribute id The name of the argument (a string)
# @attribute type The template argument (a type)
# @attribute def_type The default type (nil or a CPPType object)
class CPPClassTemplateArg < CPPObject
attr_accessor :id, :def_type
def_initializer :id, :def_type
attr_accessor :type, :def_type
def_initializer :type, :def_type
def to_s
self.id + (self.def_type ? ("=" + self.def_type.to_s) : "")
end
end
# @brief A value template argument (with an optional initializer)
# @attribute type A CPPType object describing the type
# @attribute def_expr The initializer expression (a string) or nil if no initializer is given
class CPPDirectTemplateArg < CPPObject
attr_accessor :type, :def_expr
def_initializer :type, :def_expr
def to_s
self.type.to_s + (self.def_expr ? ("=" + self.def_expr.to_s) : "")
if self.def_type
self.type.to_s + "=" + self.def_type.to_s
else
self.type.to_s
end
end
end

View File

@ -404,13 +404,7 @@ end
module PClassTemplateArg
def cpp
CPPClassTemplateArg::new(id.text_value, dtspec.nonterminal? ? dtspec.cpp : nil)
end
end
module PDirectTemplateArg
def cpp
CPPDirectTemplateArg::new(t.cpp, initspec.nonterminal? ? initspec.text_value : nil)
CPPClassTemplateArg::new(t.cpp, dtspec.nonterminal? ? dtspec.cpp : nil)
end
end

View File

@ -29,7 +29,7 @@ $:.push(File.dirname($0))
require 'oj'
require 'treetop'
Treetop.load "c++"
Treetop.load File.join(File.dirname($0), "c++")
input="all.e"
output="all.db"