Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Change the data to have the format which is like a C struct.

by dwslovedh (Novice)
on Apr 28, 2013 at 14:53 UTC ( [id://1031082]=perlquestion: print w/replies, xml ) Need Help??

dwslovedh has asked for the wisdom of the Perl Monks concerning the following question:

Hi there, I need to convert non-standard C struct data into standard C struct. I want change the data to have the format which is like a C struct. Here is the data, for example:

_____________________________________________ mm struct a = 1 b = 3 m1 struct = c = 4 d = 5 __________________________________________
I want to change the data to:
_____________________________________________ mm struct { a = 1; b = 3; m1 struct = { c = 4; d = 5; } } _________________________________________________

This is my code:

sub change_to_normal { my $str = shift; my $find = "(.*)=(.*)"; my $replace = '"$1 = $2;"'; $str =~ s/$find/$replace/eeg; #add ; my $replace = '"$1 = \{"'; #add { $str =~ s/(.*)=\s*;/$replace/eeg; }

Now I have the problem with how to add the corresponding "}". Can any one helps? Thanks!

Replies are listed 'Best First'.
Re: Convert Non-standard C struct data to standard C struct
by BrowserUk (Patriarch) on Apr 28, 2013 at 16:11 UTC

    That doesn't look like any "standard C" I've ever seen?

    mm struct { a = 1; b = 3; m1 struct = { c = 4; d = 5; } }

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      That doesn't look like any "standard C" I've ever seen?

      Yeah, I agree. I haven't written C code for the last five or six years, but, to me, a standard C struct declaration usually looks more like this:

      struct date { int day; int month; int year; } struct my_record_type { long key; int size; char text[128]; struct date birthdate; }

        Yup! Pre-ANSI C allowed untyped vars to default to ints, but that did not extend to struct members; you cannot initialise struct members individually; and you don't assign the curlies to the tagname


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
      Yes, sorry for the unclear expression, but I can not find a more proper way to elaborate my problem. I want to change the data to have the format which is like C struct. This is the data I got from other guys which turn the original C struct into this.

        I think a more proper way to elaborate your problem would be to provide an accurate explanation of what the output should look like. Is it supposed to be valid C? Or is it supposed to be exactly the syntax that you provided as an example output? Because if it's supposed to be valid C, what you provided isn't. And if it's not, then why confuse the issue by calling something that isn't C, C?


        Dave

Re: Convert Non-standard C struct data to standard C struct
by hdb (Monsignor) on Apr 28, 2013 at 15:17 UTC

    For the simple example above, this here works

    use strict; use warnings; my $struct = <<STRUCT; mm struct a = 1 b = 3 m1 struct = c = 4 d = 5 STRUCT sub change_to_normal { my @lines = split /\n/, shift; my $str; my @indent; for my $line (@lines) { if( $line =~ /struct/ ) { $line =~ /^(\s*)/; push @indent, length( $1 ); $line =~ s/=//g; $str .= $line."= {\n"; } elsif( $line =~ /.*=.*/ ) { $str .= $line.";\n"; } else { $str .= $line."\n"; } } while( @indent ) { my $ind = pop @indent; $str .= " "x$ind."}\n"; } return $str; } print change_to_normal( $struct );

    but I assume that you can have more complex cases as well? For example:

    mm struct a = 1 b = 3 m1 struct = c = 4 d = 5 e = 7

    what would you expect?

      Yes, the data I have is a little similar with C struct. I would expect:

      mm struct { a = 1; b = 3; m1 struct = { c = 4; d = 5; } e = 7; }
Re: Convert Non-standard C struct data to standard C struct
by LanX (Saint) on Apr 28, 2013 at 15:55 UTC
    I'm not a C-programmer...

    ... but if this syntax is based on indentation, then you should keep track of the leading whitespace.

    Push a closing delimiter like '}' to a @stack for each step forward, and pop it after each step backwards.

    BTW: you asked this already didn't you?

    Cheers Rolf

    ( addicted to the Perl Programming Language)

      No, I have not asked this~
Re: Change the data to have the format which is like a C struct.
by hdb (Monsignor) on Apr 29, 2013 at 12:12 UTC

    Now it works for more complex structures as well as long as they are wellformed.

    use strict; use warnings; my $string = <<STRUCT; a = 0 mm struct a = 1 b = 3 m1 struct = c = 4 d = 5 m2 struct = f = 9 e = 7 m3 struct = h = 124 STRUCT my @lines = split /\n/, $string; my @levels; my $ind = 0; my $oldind; for( my $i=0; $i<@lines; ++$i ) { $oldind = $ind; $lines[$i] =~ /^(\s*)/; $ind = length( $1 ); push @levels, $ind if $i==0; $lines[$i] .= ";" if $lines[$i] =~ /\S+\s*=\s*\S+/; next if $i==0 or $ind == $oldind; if( $ind > $oldind ) { $lines[$i-1] .= " {"; push @levels, $ind; } elsif( $ind < $oldind ) { while( $levels[-1] > $ind ) { pop @levels; $lines[$i-1] .= "\n"." "x$levels[-1]."}"; } } } while( $levels[-1] > $levels[0] ) { pop @levels; $lines[-1] .= "\n"." "x$levels[-1]."}"; } print join "\n", @lines, "\n";

      It works, Thanks!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1031082]
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others exploiting the Monastery: (4)
As of 2024-03-29 12:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found