LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   [sed] "Advanced" sed question(s) (http://www.linuxquestions.org/questions/programming-9/%5Bsed%5D-advanced-sed-question-s-426353/)

G00fy 03-19-2006 05:31 PM

[sed] "Advanced" sed question(s)
 
Hi,


Basically what I try to do here is convert a slice-file (www.zeroc.com) to a C++ header file so DoxyGen can parse it without a glitch ;).
So I don't care about layouting in sed... As it will be interpreted by a machine anyway ;).


I have 3 questions for sed...

Let me first show the input file:
Code:

#ifndef TEST1
#define TEST1


module main
{
  local interface test1
        extends  ext1,
                  ext2
  {
                bool function( );
    idempotent  bool function( );

    nonmutating bool function( );
    nonmutating bool function( ) throws RangeError;
    nonmutating bool function( ) throws RangeError, NormalError;
    nonmutating bool function( ) throws RangeError,
                                        NormalError;
    nonmutating bool function( ) throws RangeError
                                        , NormalError;
  };
};


#endif // TEST1

Now what it has to look like:
Code:

#ifndef TEST1
#define TEST1


namespace main
{
  class test1
        : public ext1, public
                  ext2
  {
                bool function( );
    bool function( );

    bool function( ) const;
    bool function( ) const throw(RangeError);
    bool function( ) const throw(RangeError, NormalError);
    bool function( ) const throw (RangeError,
                                        NormalError);
    bool function( ) const throw (RangeError
                                        , NormalError);
  };
};


#endif // TEST1


I am trying to do this with 'sed'... Now I managed to get this script:
Code:

s/local//g
s/interface/class/g
s/extends/: public/g
s/module/namespace/g
s/sequence/vector/g
s/dictionary/map/g
/class/,/{/s/{/{public:/g
s/idempotent//g
s/nonmutating\(.*\);/\1 const;/g

now the problems I have are those:
  1. throws ...; -> throw(...); with support for multiple errors on multiple lines
  2. extends ..., ..., ... -> : public ..., public ..., public ...
  3. nonmutating ... () throws... -> ... () const throw...;


I have been looking around for something called 'N', but that seems like only running once, and what I need is something that even runs on multiple lines...


For (1) I need everything from 'throws' -> ';'. And then change the keyword 'throws' -> 'throw(', and the keyword ';' -> ');'. That would do this trick, but I don't know how to tell in sed.

For (2) I need to convert the extends <class>[, <class>] into : public <class>[, public <class]...

(3) is rather simple if I know how to do (1) in fact... So never mind about that one ;)


Could someone help me with this?


Thanks!

Frodak 03-19-2006 08:19 PM

you need to use multiple line addressing and stuff... this is kind of clunky, but I'm not a sed guru


Code:

#!/usr/bin/sed -f

s/module/namespace/

#parse local interface
/local interface/ , /{/    {
    /local interface/ {
        #change local interface to class
        s/local interface\(.*\)/class \1:/
        #branch to the end of script - do nothing else for local interface
        b
    }
#delete extends
    s/extends//
#add public before every keyword, but not {
    s/\([^ {]\+\)/public \1/g

}

s/nonmutating\(.*)\)/\1 const/

/throws.*;/ {
    s/throws/throw(/
    s/;/);/
    #print the line
    p
    #delete pattern space, start next cycle
    #don't process multi-line throws
    d
}

/throws/,/;/ {
    s/throws/throw(/
    s/;/);/
}

$ cat temp.lst
#ifndef TEST1
#define TEST1


module main
{
  local interface test1
        extends  ext1,
                  ext2
  {
                bool function( );
    idempotent  bool function( );

    nonmutating bool function( );
    nonmutating bool function( ) throws RangeError;
    nonmutating bool function( ) throws RangeError, NormalError;
    nonmutating bool function( ) throws RangeError,
                                        NormalError;
    nonmutating bool function( ) throws RangeError
                                        , NormalError;
  };
};


#endif // TEST1

e728075@NM75DTJYT4M81 ~
$ ./parse_file temp.lst
#ifndef TEST1
#define TEST1


namespace main
{
  class  test1:
          public ext1,
                  public ext2
  {
                bool function( );
    idempotent  bool function( );

    bool function( ) const;
    bool function( ) const throw( RangeError);
    bool function( ) const throw( RangeError, NormalError);
    bool function( ) const throw( RangeError,
                                        NormalError);
    bool function( ) const throw( RangeError
                                        , NormalError);
  };
};


#endif // TEST1



Frodak

G00fy 03-20-2006 01:34 AM

Thanks a lot! To me you're a Guru anyway :D.


What I came up with so far (after your great help):
Code:

#!/usr/bin/sed -f

# Skip C-style commenting
/\/\*/ , /\*\//b
/\/\/\(.*\)/b

s/module/namespace/
s/local//
s/idempotent//
s/dictionary/map/
s/sequence/vector/

#parse local interface
/interface/ , /{/    {
    /interface/ {
        #change interface to class
        s/interface\(.*\)/class \1/
    }
#change extends
    s/extends/: public/
#add public before every keyword, but not {
    /{/!s/,\(.*\)/, public \1/g
    s/{/{public:/
}

s/nonmutating\(.*)\)/\1 const/

/throws/,/;/ {
    s/throws/throw(/
    s/;/);/
}

This changes this file:
Code:

#ifndef TEST1
#define TEST1

/**
  module
  interface
  nonmutating
*/

// local interface extends
module main
{
  interface test2 extends ext2
  {
  };
 
  local interface test1
        extends  ext1,
                  ext2
  {
                bool function( );
    idempotent  bool function( );

    nonmutating bool function( );
    nonmutating bool function( ) throws RangeError;
    nonmutating bool function( ) throws RangeError, NormalError;
    nonmutating bool function( ) throws RangeError,
                                        NormalError;
    nonmutating bool function( ) throws RangeError
                                        , NormalError;
  };
};


#endif // TEST1

Into this output:
Code:

#ifndef TEST1
#define TEST1

/**
  module
  interface
  nonmutating
*/

// local interface extends
namespace main
{
  class  test2 : public ext2
  {public:
  };

  class  test1
        : public  ext1, public
                  ext2
  {public:
                bool function( );
      bool function( );

    bool function( ) const;
    bool function( ) const throw( RangeError);
    bool function( ) const throw( RangeError, NormalError);
    bool function( ) const throw( RangeError,
                                        NormalError);
    bool function( ) const throw( RangeError
                                        , NormalError);
  };
};


#endif // TEST1



All times are GMT -5. The time now is 03:50 AM.