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
+59 -24
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
+8 -18
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
@@ -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
+1 -1
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"