mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-19 15:43:56 +00:00
Improvements of parse_cxx tool
This patch improves the C++ parser to accommodate the tools for generating the functional specification from source code: * Added support for class definitions prefixed with a namespace as promoted by Genode's coding style. * Improves robustness of the parsing of function arguments by considering nameless arguments in function declarations, default values, varargs. * Consider const qualfiers in return types. * Added support for the override, constexpr keywords. * Parsing of overloaded operators. * Improved handling of type definitions. * Added parsing of template arguments. * Handling of template constructors.
This commit is contained in:
committed by
Christian Helmuth
parent
e1b4408090
commit
7441df33c9
151
tool/parse_cxx
151
tool/parse_cxx
@ -45,16 +45,6 @@ if {[catch {
|
||||
# do not stop parsing (this variable is only used for debugging)
|
||||
set stop 0
|
||||
|
||||
#
|
||||
# Detect occurence of magic characters that we
|
||||
# use to mark substitutions in the syntax tree.
|
||||
#
|
||||
if {[regexp {[<5B><><EFBFBD>]} $txt(0) magic_char]} {
|
||||
puts stderr "Error: Source code contains reserved character '$magic_char'."
|
||||
puts stderr " The following characters are reserved: '<27>', '<27>', '<27>'"
|
||||
exit -1;
|
||||
}
|
||||
|
||||
#
|
||||
# Replace all '&' characters from the original input
|
||||
# because they cause trouble with the regexp command.
|
||||
@ -336,7 +326,7 @@ foreach keyword {
|
||||
using namespace class struct union enum template
|
||||
const inline static virtual friend explicit
|
||||
volatile case default operator new throw
|
||||
try catch continue sizeof asm
|
||||
try catch continue sizeof asm override typename constexpr
|
||||
GENODE_RPC GENODE_RPC_THROW
|
||||
GENODE_RPC_INTERFACE GENODE_RPC_INTERFACE_INHERIT
|
||||
GENODE_TYPE_LIST
|
||||
@ -365,55 +355,55 @@ extract tplargs {<[^<>{}]*>$} {content block parenblk}
|
||||
extract tplargs {<[^<>{}]*>(?=[^>])} {content block parenblk}
|
||||
|
||||
# extract special characters
|
||||
extract equal {==} {content block parenblk}
|
||||
extract assignopplus {\+=} {content block parenblk}
|
||||
extract assignopminus {\-=} {content block parenblk}
|
||||
extract assignopmult {\*=} {content block parenblk}
|
||||
extract assignopdiv {\/=} {content block parenblk}
|
||||
extract assignopmod {%=} {content block parenblk}
|
||||
extract assignopbitor {\|=} {content block parenblk}
|
||||
extract assignopbitand {<7B>=} {content block parenblk}
|
||||
extract assignopbitxor {\^=} {content block parenblk}
|
||||
extract assignopneq {\!=} {content block parenblk}
|
||||
extract assignoplshift {<<=} {content block parenblk}
|
||||
extract assignoprshift {>>=} {content block parenblk}
|
||||
extract incr {\+\+} {content block parenblk}
|
||||
extract decr {\-\-} {content block parenblk}
|
||||
extract doublecolon {::} {content block parenblk}
|
||||
extract or {\|\|} {content block parenblk}
|
||||
extract bitor {\|} {content block parenblk}
|
||||
extract and {<7B><>} {content block parenblk}
|
||||
extract amper {<7B>} {content block parenblk}
|
||||
extract plus {\+} {content block parenblk}
|
||||
extract div {\/} {content block parenblk}
|
||||
extract star {\*} {content block parenblk}
|
||||
extract notequal {\!=} {content block parenblk}
|
||||
extract not {\!} {content block parenblk}
|
||||
extract deref {\->} {content block parenblk}
|
||||
extract dot {\.} {content block parenblk}
|
||||
extract tilde {~} {content block parenblk}
|
||||
extract lshift {<<} {content block parenblk}
|
||||
extract rshift {>>} {content block parenblk}
|
||||
extract greaterequal {>=} {content block parenblk}
|
||||
extract lessequal {<=} {content block parenblk}
|
||||
extract greater {>} {content block parenblk}
|
||||
extract less {<} {content block parenblk}
|
||||
extract minus {\-} {content block parenblk}
|
||||
extract mod {%} {content block parenblk}
|
||||
extract xor {\^} {content block parenblk}
|
||||
extract question {\?} {content block parenblk}
|
||||
extract comma {,} {content block parenblk}
|
||||
extract assign {=} {content block parenblk}
|
||||
extract equal {==} {content block parenblk tplargs}
|
||||
extract assignopplus {\+=} {content block parenblk tplargs}
|
||||
extract assignopminus {\-=} {content block parenblk tplargs}
|
||||
extract assignopmult {\*=} {content block parenblk tplargs}
|
||||
extract assignopdiv {\/=} {content block parenblk tplargs}
|
||||
extract assignopmod {%=} {content block parenblk tplargs}
|
||||
extract assignopbitor {\|=} {content block parenblk tplargs}
|
||||
extract assignopbitand {<7B>=} {content block parenblk tplargs}
|
||||
extract assignopbitxor {\^=} {content block parenblk tplargs}
|
||||
extract assignopneq {\!=} {content block parenblk tplargs}
|
||||
extract assignoplshift {<<=} {content block parenblk tplargs}
|
||||
extract assignoprshift {>>=} {content block parenblk tplargs}
|
||||
extract incr {\+\+} {content block parenblk tplargs}
|
||||
extract decr {\-\-} {content block parenblk tplargs}
|
||||
extract doublecolon {::} {content block parenblk tplargs}
|
||||
extract or {\|\|} {content block parenblk tplargs}
|
||||
extract bitor {\|} {content block parenblk tplargs}
|
||||
extract and {<7B><>} {content block parenblk tplargs}
|
||||
extract amper {<7B>} {content block parenblk tplargs}
|
||||
extract plus {\+} {content block parenblk tplargs}
|
||||
extract div {\/} {content block parenblk tplargs}
|
||||
extract star {\*} {content block parenblk tplargs}
|
||||
extract notequal {\!=} {content block parenblk tplargs}
|
||||
extract not {\!} {content block parenblk tplargs}
|
||||
extract deref {\->} {content block parenblk tplargs}
|
||||
extract dot {\.} {content block parenblk tplargs}
|
||||
extract tilde {~} {content block parenblk tplargs}
|
||||
extract lshift {<<} {content block parenblk tplargs}
|
||||
extract rshift {>>} {content block parenblk tplargs}
|
||||
extract greaterequal {>=} {content block parenblk tplargs}
|
||||
extract lessequal {<=} {content block parenblk tplargs}
|
||||
extract greater {>} {content block parenblk tplargs}
|
||||
extract less {<} {content block parenblk tplargs}
|
||||
extract minus {\-} {content block parenblk tplargs}
|
||||
extract mod {%} {content block parenblk tplargs}
|
||||
extract xor {\^} {content block parenblk tplargs}
|
||||
extract question {\?} {content block parenblk tplargs}
|
||||
extract comma {,} {content block parenblk tplargs}
|
||||
extract assign {=} {content block parenblk tplargs}
|
||||
|
||||
extract attribute {__attribute__\s*<2A>parenblk\d+<2B>} {content block parenblk}
|
||||
|
||||
# extract identifiers
|
||||
extract identifier {([\w_][\w\d_]*)+(?=[^<5E>]*(<28>|$))} {content parenblk block}
|
||||
extract identifier {([\w_][\w\d_]*)+(?=[^<5E>]*(<28>|$))} {content parenblk block tplargs}
|
||||
|
||||
extract identifier {<7B>quotedchar\d+<2B>} {content parenblk block}
|
||||
extract identifier {<7B>quotedchar\d+<2B>} {content parenblk block tplargs}
|
||||
|
||||
# merge template arguments with the predecessing identifier
|
||||
extract identifier {<7B>identifier\d+<2B>\s*<2A>tplargs\d+<2B>} {content block parenblk}
|
||||
extract identifier {<7B>identifier\d+<2B>\s*<2A>tplargs\d+<2B>} {content block parenblk tplargs}
|
||||
|
||||
# extract using namespace
|
||||
extract using {<7B>keyusing\d+<2B>\s*<2A>keynamespace\d+<2B>\s*<2A>identifier\d+<2B>\s*;} {content block}
|
||||
@ -426,10 +416,10 @@ extract identifier {
|
||||
#
|
||||
|
||||
# extract namespaced identifiers
|
||||
extract identifier {<7B>identifier\d+<2B>\s*<2A>doublecolon\d+<2B>\s*<2A>identifier\d+<2B>} block
|
||||
extract identifier {<7B>identifier\d+<2B>\s*<2A>doublecolon\d+<2B>\s*<2A>identifier\d+<2B>} {content block}
|
||||
|
||||
# extract identifiers in the root namespace
|
||||
extract identifier {<7B>doublecolon\d+<2B>\s*<2A>identifier\d+<2B>} block
|
||||
extract identifier {<7B>doublecolon\d+<2B>\s*<2A>identifier\d+<2B>} {content block}
|
||||
|
||||
extract whilecond {<7B>keywhile\d+<2B>\s*<2A>parenblk\d+<2B>} block
|
||||
extract forcond {<7B>keyfor\d+<2B>\s*<2A>parenblk\d+<2B>} block
|
||||
@ -503,12 +493,13 @@ extract operatorfunction {
|
||||
extract funcptr {<7B>parenblk\d+<2B>\s*<2A>parenblk\d+<2B>(\s*<2A>attribute\d+<2B>)?} {content classblock block identifier parenblk}
|
||||
extract function {<7B>identifier\d+<2B>\s*<2A>parenblk\d+<2B>(\s*<2A>attribute\d+<2B>)?} {content classblock block initializer}
|
||||
|
||||
extract operator {<7B>keyoperator\d+<2B>\s*<2A>[^ ]+\d+<2B>} operatorfunction
|
||||
|
||||
extract destfunction {(<28>identifier\d+<2B><>doublecolon\d+<2B>)?<3F>tilde\d+<2B><>identifier\d+<2B>\s*<2A>parenblk\d+<2B>} {content classblock}
|
||||
extract identifier {(<28>identifier\d+<2B><>doublecolon\d+<2B>)?<3F>tilde\d+<2B><>identifier\d+<2B>} destfunction
|
||||
|
||||
extract identifier {<7B>identifier\d+<2B>\s*<2A>parenblk\d+<2B>} {parenblk block identifier initializer}
|
||||
extract identifier {<7B>identifier\d+<2B>\s*<2A>parenblk\d+<2B>} {parenblk block identifier initializer tplargs}
|
||||
extract identifier {<7B>parenblk\d+<2B>} {parenblk block}
|
||||
#extract_operations parenblk
|
||||
|
||||
# extract arrays
|
||||
extract array {(<28>identifier\d+<2B>\s*)(<28>arrayindex\d+<2B>\s*)+} {content classblock block}
|
||||
@ -530,18 +521,15 @@ extract identifier {
|
||||
extract return {<7B>keyreturn\d+<2B>[^;]*} {block}
|
||||
|
||||
# extract modifiers
|
||||
extract modifier {(<28>key(extern|externc|const|static|inline|virtual|volatile)\d+<2B>\s*)+} {content classblock block}
|
||||
extract modifier {(<28>key(extern|externc|constexpr|static|inline|virtual|volatile)\d+<2B>\s*)+} {content classblock block}
|
||||
|
||||
# extract function declarations
|
||||
extract funcdecl {(<28>mlcomment\d+<2B> *\n[ \t]*)?(<28>(modifier|keyunsigned)\d+<2B>\s*)*<2A>(identifier|keyunsigned)\d+<2B>(\s|(<28>amper\d+<2B>)|(<28>star\d+<2B>))*<2A>(operator)?function\d+<2B>\s*(<28>modifier\d+<2B>\s*)*(<28>assign\d+<2B>\s*<2A>identifier\d+<2B>)?\s*;} {content block classblock}
|
||||
extract funcdecl {(<28>mlcomment\d+<2B> *\n[ \t]*)?(<28>(modifier|keyunsigned|keyconst)\d+<2B>\s*)*<2A>(identifier|keyunsigned|keyconst)\d+<2B>(\s|(<28>amper\d+<2B>)|(<28>star\d+<2B>))*<2A>(operator)?function\d+<2B>\s*(<28>(keyconst|keyoverride)\d+<2B>\s*)*(<28>assign\d+<2B>\s*<2A>identifier\d+<2B>)?\s*;} {content block classblock}
|
||||
|
||||
# extract function implementations
|
||||
extract funcimpl {(<28>mlcomment\d+<2B> *\n[ \t]*)?(<28>(modifier|keyunsigned)\d+<2B>\s*)?<EFBFBD>(identifier|keyunsigned)\d+<2B>(\s|(<28>amper\d+<2B>)|(<28>star\d+<2B>))*<2A>(operator)?function\d+<2B>\s*(<28>modifier\d+<2B>\s*)?<EFBFBD>block\d+<2B>[;\t ]*} {content block classblock}
|
||||
extract funcimpl {(<28>mlcomment\d+<2B> *\n[ \t]*)?(<28>(modifier|keyunsigned|keyconst)\d+<2B>\s*)*(<EFBFBD>(identifier|keyunsigned|keyconst)\d+<2B>\s*)+(\s|(<28>amper\d+<2B>)|(<28>star\d+<2B>))*<2A>(operator)?function\d+<2B>\s*(<28>(keyconst|keyoverride)\d+<2B>\s*)*<EFBFBD>block\d+<2B>[;\t ]*} {content block classblock}
|
||||
extract funcimpl {(<28>mlcomment\d+<2B> *\n[ \t]*)?<3F>operatorfunction\d+<2B>\s*(<28>modifier\d+<2B>\s*)?<3F>block\d+<2B>[;\t ]*} {content block classblock}
|
||||
|
||||
# extract function implementations
|
||||
extract funcimpl {(<28>mlcomment\d+<2B> *\n[ \t]*)?(<28>(modifier|keyunsigned)\d+<2B>\s*)?<3F>(identifier|keyunsigned)\d+<2B>(\s|(<28>amper\d+<2B>)|(<28>star\d+<2B>))*<2A>(operator)?function\d+<2B>\s*(<28>modifier\d+<2B>\s*)?<3F>block\d+<2B>[;\t ]*} {content block classblock}
|
||||
|
||||
# extract template functions
|
||||
extract tplfunc {(<28>mlcomment\d+<2B> *\n[ \t]*)?<3F>keytemplate\d+<2B>\s*<2A>tplargs\d+<2B>\s*<2A>funcimpl\d+<2B>} {content block classblock}
|
||||
|
||||
@ -555,6 +543,9 @@ refine_sub_tokens destimpl destfunction function
|
||||
# extract constructor implementations
|
||||
extract constimpl {(<28>mlcomment\d+<2B> *\n[ \t]*)?(<28>(modifier|keyexplicit)\d+<2B>\s*)*<2A>function\d+<2B>\s*(<28>initializer\d+<2B>\s*)?\s*<2A>block\d+<2B>[;\t ]*} {content classblock}
|
||||
|
||||
# extract template constructors
|
||||
extract tplfunc {(<28>mlcomment\d+<2B> *\n[ \t]*)?<3F>keytemplate\d+<2B>\s*<2A>tplargs\d+<2B>\s*<2A>constimpl\d+<2B>} {content block classblock}
|
||||
|
||||
# extract destructor declarations
|
||||
extract destdecl {(<28>mlcomment\d+<2B> *\n[ \t]*)?(<28>modifier\d+<2B>\s*)?<3F>tilde\d+<2B><>function\d+<2B>\s*(<28>assign\d+<2B>\s+<2B>identifier\d+<2B>)?\s*;} {classblock}
|
||||
|
||||
@ -568,29 +559,43 @@ extract frienddecl {
|
||||
foreach env_type [list destdecl constdecl destimpl constimpl funcimpl funcdecl] {
|
||||
refine_sub_tokens $env_type function funcsignature }
|
||||
refine_sub_tokens funcsignature parenblk argparenblk
|
||||
refine_sub_tokens operatorfunction parenblk argparenblk
|
||||
|
||||
extract_operations parenblk
|
||||
extract modifier {(<28>key(const|volatile)\d+<2B>\s*)+} {argparenblk}
|
||||
extract argmodifier {(<28>key(const|volatile)\d+<2B>\s*)+} {argparenblk}
|
||||
|
||||
# extract pure-virtual assignments
|
||||
extract virtassign {<7B>assign\d+<2B>\s+<2B>identifier\d+<2B>} funcdecl
|
||||
|
||||
# extract return values
|
||||
extract retval {(<28>keyunsigned\d+<2B>\s*)*(<28>(identifier|keyunsigned)\d+<2B>)(\s|(<28>amper\d+<2B>)|(<28>star\d+<2B>))*} {funcdecl funcimpl}
|
||||
extract identifier {<7B>keyunsigned\d+<2B>\s*(<28>identifier\d+<2B>)?} {retval}
|
||||
extract retval {(<28>(identifier|keyunsigned|keyconst|star|amper)\d+<2B>\s*)+(?=<3D>funcsignature)} {funcdecl funcimpl}
|
||||
extract retval {(<28>(identifier|keyunsigned|keyconst|star|amper)\d+<2B>\s*)+(?=<3D>operatorfunction)} {funcdecl funcimpl}
|
||||
extract identifier {<7B>(keyunsigned|keyconst)\d+<2B>\s*(<28>identifier\d+<2B>)?} {retval}
|
||||
|
||||
# extract single argument declarations within argument-parenthesis blocks
|
||||
extract argdecl {(<28>(modifier|keyunsigned)\d+<2B>\s*)*(<28>(identifier|keyunsigned)\d+<2B>)(\s|(<28>amper\d+<2B>)|(<28>star\d+<2B>))*(<28>modifier\d+<2B>\s*)*<2A>identifier\d+<2B>} {argparenblk tplargs}
|
||||
# extract argument declarations separated by commas
|
||||
refine_sub_tokens tplargs greater closeparen
|
||||
refine_sub_tokens tplargs less openparen
|
||||
extract varargs {(<28>dot\d+<2B>){3}} {argparenblk tplargs}
|
||||
extract keytypename {<7B>keytypename\d+<2B>\s*<2A>varargs\d+<2B>} tplargs
|
||||
|
||||
extract argname {<7B>identifier\d+<2B>$} {argdecl}
|
||||
extract argtype {^(<28>(modifier|keyunsigned)\d+<2B>\s*)*(<28>(identifier|keyunsigned)\d+<2B>)(\s|(<28>amper\d+<2B>)|(<28>star\d+<2B>))*(<28>modifier\d+<2B>\s*)*} {argdecl}
|
||||
extract argdecl {(<28>(argmodifier|keytypename|keyunsigned|identifier|tilde|minus|amper|star|and|varargs|assign|string)\d+<2B>\s*)+(?=<3D>comma)} {argparenblk tplargs}
|
||||
extract argdecl {(<28>(argmodifier|keytypename|keyunsigned|identifier|tilde|minus|amper|star|and|varargs|assign|string)\d+<2B>\s*)+(?=<3D>closeparen)} {argparenblk tplargs}
|
||||
extract argdefault {<7B>assign\d+<2B>.*} argdecl
|
||||
|
||||
# extract argument-declaration types
|
||||
extract argdecltype {^<5E>(identifier|keyunsigned)\d+<2B>(\s|(<28>amper\d+<2B>)|(<28>star\d+<2B>))*} argdecl
|
||||
extract argname {<7B>identifier\d+<2B>\s*(?=<3D>argdefault)} {argdecl}
|
||||
|
||||
# there may be just a type and no name
|
||||
extract argtype {^\s*<2A>identifier\d+<2B>\s*$} {argdecl}
|
||||
|
||||
# the last identifier is the name
|
||||
extract argname {<7B>identifier\d+<2B>\s*$} {argdecl}
|
||||
extract argtype {^(<28>(argmodifier|keyunsigned)\d+<2B>\s*)*(<28>(identifier|keytypename|varargs|keyunsigned)\d+<2B>)(\s*|(<28>(amper|and|argmodifier)\d+<2B>)|(<28>star\d+<2B>))*(<28>argmodifier\d+<2B>\s*)*(<28>varargs\d+<2B>)?} argdecl
|
||||
|
||||
# extract typedefs
|
||||
extract typedef {(<28>mlcomment\d+<2B> *\n[ \t]*)?<3F>keytypedef\d+<2B>(\s*<2A>identifier\d+<2B>)+\s*;} {content classblock block}
|
||||
extract typedef {(<28>mlcomment\d+<2B> *\n[ \t]*)?<3F>keytypedef\d+<2B>(\s*<2A>(identifier|keyunsigned)\d+<2B>)+\s*;} {content classblock block}
|
||||
extract typename {<7B>identifier\d+<2B>(?=;)} typedef
|
||||
extract identifier {(\s*<2A>(identifier|keyunsigned)\d+<2B>){2,}} typedef
|
||||
extract identifier {\s*<2A>keyunsigned\d+<2B>} typedef
|
||||
|
||||
# extract function pointers
|
||||
extract vardecl {(<28>(modifier|keyunsigned)\d+<2B>\s*)*(<28>(identifier|keyunsigned)\d+<2B>)((\s|(<28>amper\d+<2B>)|(<28>star\d+<2B>))*(<28>modifier\d+<2B>\s*)*(<28>funcptr\d+<2B>)\s*(:\s*<2A>identifier\d+<2B>)?\s*(<28>assign\d+<2B>[^;]*?)?\s*(<28>comma\d+<2B>)?\s*)+;} {content classblock block}
|
||||
|
Reference in New Issue
Block a user