1
0
mirror of https://github.com/ThrowTheSwitch/CMock synced 2025-05-29 03:29:35 -04:00

fixed up parser to handle custom types whose names begin with primitive types; fixed holes in handling of spaces

git-svn-id: http://cmock.svn.sourceforge.net/svnroot/cmock/trunk@131 bf332499-1b4d-0410-844d-d2d48d5cc64c
This commit is contained in:
mkarlesky 2009-06-19 21:35:06 +00:00
parent 3e1651c937
commit f06f500dab
5 changed files with 2220 additions and 2177 deletions

@ -282,7 +282,7 @@ module CMockFunctionPrototype
end
class NameNode < Treetop::Runtime::SyntaxNode
class NameWithSpaceNode < Treetop::Runtime::SyntaxNode
def text_value
return super.strip
end
@ -296,12 +296,12 @@ module CMockFunctionPrototype
type = super
type.gsub!(/\s+/, ' ') # remove extra spaces
type.gsub!(/\s\*/, '*') # remove space preceding '*'
type.gsub!(/const\*/, 'const *') # space out 'const' & '*'
type.gsub!(/const\*/, 'const *') # space out 'const' and '*'
return type.strip
end
def text_value_no_const
return text_value.gsub(/\s*const\s*/, '')
return text_value.gsub(/(^|\s+)const($|\s+)/, '')
end
def brackets?

File diff suppressed because it is too large Load Diff

@ -10,7 +10,7 @@ grammar CMockFunctionPrototype
rule function_prototype_function_pointer_return
# ex. float (*GetPtr(const char opCode))(float, float)
# const: tag so we can always access its nodes in programming even if blank.
# const: tag so we can always access its nodes in programming even if blank
return_type
left_paren asterisk name function_arglist:argument_list right_paren
function_return_arglist:argument_list
@ -35,7 +35,7 @@ grammar CMockFunctionPrototype
end
rule variable_argument
'...' space <VarArgNode>
'...' space_optional <VarArgNode>
end
rule func_ptr_prototype
@ -44,77 +44,75 @@ grammar CMockFunctionPrototype
end
rule parenthesized_func_ptr_name_with_arglist
# allow nested parentheses around name and arglist
# use labels 'const:' and 'name:' to give programmatic access even if nodes aren't found in string
# - allow nested parentheses around name and arglist
# - use labels 'const:' and 'name:' to give programmatic access even if nodes aren't found in string
(left_paren name_and_args:parenthesized_func_ptr_name_with_arglist right_paren) /
(left_paren asterisk const:const? name:name? right_paren argument_list)
end
rule type_and_name
# add name: tag to name? so we can always access it in programming even if blank.
# tell parser that type and optional name will always be followed by ',' '(' or ')' but don't consume them;
# this helps enforce the limits on what can be parsed in argument lists
# - name? tagged with name: so we can always access it in programming even if blank
# - tell parser that type and optional name will always be followed by ',' '(' or ')' but don't consume them;
# this helps enforce the limits on what can be parsed in argument lists
type name:name_with_brackets? &( comma / left_paren / right_paren ) <TypeWithNameNode>
end
rule type
const?
( type_struct /
type_union /
type_enum /
( type_struct_union_enum /
type_void_ptr /
type_primitive /
type_custom )
type_custom )
brackets:array_brackets? <TypeNode>
end
rule type_struct
'struct' space name space type_const_and_ptr_suffix?
end
rule type_union
'union' space name space type_const_and_ptr_suffix?
end
rule type_enum
'enum' space name space type_const_and_ptr_suffix?
rule type_struct_union_enum
('struct' / 'union' / 'enum') space_mandatory name_no_space type_const_and_ptr_suffix? space_optional
end
rule type_void_ptr
'void' space type_const_and_ptr_suffix
# note that type_const_and_ptr_suffix is mandatory unlike other type rules because
# rule represents void pointer (i.e. must contain a '*' by definition)
'void' type_const_and_ptr_suffix space_optional
end
rule type_primitive
# at least one clause has to exist, not all can be '?' optional;
# hence the long and int variations instead of an optional long followed by optional everything else
(('unsigned' / 'signed') space)?
(('long' space 'int') / ('long' space 'long') / 'long' / 'int' / 'short' / 'char' / 'float' / 'double') space
# - at least one clause has to exist, not all can be '?' optional;
# hence the long and int variations instead of an optional long followed by optional everything else
# - !name_no_space limits matches to only primitives (allowing custom types to begin with primitive names)
(('unsigned' / 'signed') space_mandatory)?
(('long' space_mandatory 'int') / ('long' space_mandatory 'long') / 'long' / 'int' / 'short' / 'char' / 'float' / 'double') !name_no_space
type_const_and_ptr_suffix?
space_optional
end
rule type_custom
name space type_const_and_ptr_suffix?
name_no_space type_const_and_ptr_suffix? space_optional
end
rule type_const_and_ptr_suffix
# variants of "const", "const *", "* const", "const * const", & "*"
# (of course, more than one asterisk possible in pointer cases)
(const asterisk+ lookahead_const) /
(const asterisk+) /
(asterisk+ lookahead_const) /
(asterisk+) /
(lookahead_const)
(space_mandatory const asterisk+ lookahead_const) /
(space_mandatory const asterisk+) /
(space_optional asterisk+ lookahead_const) /
(space_optional asterisk+) /
(space_optional lookahead_const)
end
rule lookahead_const
# fancy lookahead statement that allows const type suffix to be distinguished
# from a parameter name that might begin with word 'const'
# (e.g. "int const_param" or "char* const constant")
'const' ( (' '+ &name) / (space &comma) / (space &right_paren) / (space &left_paren) )
# (ex. "int const_param" or "char* const constant")
'const' ( (space_mandatory &name) / (space_optional &comma) / (space_optional &right_paren) / (space_optional &left_paren) )
end
rule name
[a-zA-Z0-9_]+ space <NameNode>
alpha_numeric+ space_optional <NameWithSpaceNode>
end
rule name_no_space
alpha_numeric+
end
rule name_with_brackets
@ -124,7 +122,7 @@ grammar CMockFunctionPrototype
rule void
# in reality, 'void' is something different than the 'void*' type so limit to 'void' here and handle 'void*' in type rule;
# recognizing the VoidNode uniquely in programming is helpful
'void' space !asterisk <VoidNode>
'void' space_optional !asterisk <VoidNode>
end
rule array_brackets
@ -132,38 +130,46 @@ grammar CMockFunctionPrototype
end
rule const
'const' space
'const' space_optional
end
rule asterisk
'*' space
'*' space_optional
end
rule left_paren
'(' space
'(' space_optional
end
rule right_paren
')' space
')' space_optional
end
rule left_bracket
'[' space
'[' space_optional
end
rule right_bracket
']' space
']' space_optional
end
rule comma
',' space
',' space_optional
end
rule alpha_numeric
[a-zA-Z0-9_]
end
rule number
[0-9] space
[0-9] space_optional
end
rule space
rule space_mandatory
' '+
end
rule space_optional
' '*
end

@ -18,6 +18,7 @@
:header: |
UINT32 function_a(int a, int b);
void function_b(void);
void function_c(void);
:code: |
UINT32 function_a(int a, int b)

@ -120,7 +120,7 @@ class CMockFunctionPrototypeParserTest < Test::Unit::TestCase
parsed.get_arguments)
assert_nil(parsed.get_var_arg)
# make sure known types in param names don't gum up the parsing works
# make sure primitve types in param names don't gum up the parsing works
parsed = @parser.parse("void foo_bar(const unsigned int const_param, int int_param, int integer, char character, int* const constant)")
assert_equal('const unsigned int const_param, int int_param, int integer, char character, int* const constant', parsed.get_argument_list)
assert_equal([
@ -132,6 +132,17 @@ class CMockFunctionPrototypeParserTest < Test::Unit::TestCase
parsed.get_arguments)
assert_nil(parsed.get_var_arg)
# make sure custom types containing primitive names don't gum up the parsing works
parsed = @parser.parse("void foo_bar(integer param, character thing, longint * junk, constant value)")
assert_equal('integer param, character thing, longint* junk, constant value', parsed.get_argument_list)
assert_equal([
{:type => 'integer', :name => 'param'},
{:type => 'character', :name => 'thing'},
{:type => 'longint*', :name => 'junk'},
{:type => 'constant', :name => 'value'}],
parsed.get_arguments)
assert_nil(parsed.get_var_arg)
parsed = @parser.parse("void foo_bar(signed char * abc, const unsigned long int xyz_123, unsigned int const abc_123, long long arm_of_the_law)")
assert_equal('signed char* abc, const unsigned long int xyz_123, unsigned int const abc_123, long long arm_of_the_law', parsed.get_argument_list)
assert_equal([