Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

C-like structures parsing and validation

by przemo (Scribe)
on Nov 16, 2009 at 12:38 UTC ( #807424=perlquestion: print w/replies, xml ) Need Help??
przemo has asked for the wisdom of the Perl Monks concerning the following question:


I'm writing LaTeX report about structural model of some optimization problem. I use C-like structures, e.g.

struct vertex_t { int id; double lon; double lat; } struct arc_t { vertex from; vertex to; double cost; } struct graph_t { vertex_t[] v; arc_t[] a; }

As I use PerlTeX already, I want to use Perl to validate my fragments of programs, e.g. a module that would recognize and remember declarations

int i; graph_t g;

and could validate -- to the level of structures elements and types used expressions like:


Before I start coding myself: has anyone heard of something similar on CPAN? Doesn't have to be exactly C-like language, although dot-notation is preferred.

Replies are listed 'Best First'.
Re: C-like structures parsing and validation
by jettero (Monsignor) on Nov 16, 2009 at 13:18 UTC
    Feels like an opportunity to use Inline::C.


      It crossed my mind, but it looks like a lot of magic. TeX runs Perl which compiles and runs C... I'll try a tiny example, thanks.

      Unfortunatelly, I have problems with using Inline in PerlTeX.

      Here's a little LaTeX code I wrote to test the concept:

      \documentclass{article} \usepackage{perltex} \perldo{ `rm -rf ./_Inline && mkdir ./_Inline`; use Inline Config => DIRECTORY => './_Inline/'; } \perlnewcommand{\compilec}[1]{ { my $cc = "void just_compile() { $_[0] };"; Inline->bind(C => $cc); just_compile(); ""; } } \begin{document} \compilec{1 + 1;} \end{document}

      It works fine, i.e. the code compiles. However, when I change the expression to something invalid, e.g.:

      \compilec{1 + nonexisting;}

      TeX spits no errors and just hangs at 100% CPU for both Perl and Tex.

      Running the corresponding "clean" Perl code outside PerlTeX and looking I see it dies:

      /home/jest/perl/perl-5.10.1/bin/perl /home/jest/perl/perl-5.10.1/lib/s +ite_perl/5.10.1/ExtUtils/xsubpp -typemap /home/jest/perl/perl-5.10.1 +/lib/5.10.1/ExtUtils/typemap perltext1_pl_f7f6.xs > perltext1_pl_f7 +f6.xsc && mv perltext1_pl_f7f6.xsc perltext1_pl_f7f6.c cc -c -I/home/jest/temp/t -D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fno-st +rict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFI +LE_SOURCE -D_FILE_OFFSET_BITS=64 -O2 -DVERSION=\"0.00\" -DXS_VERSIO +N=\"0.00\" -fPIC "-I/home/jest/perl/perl-5.10.1/lib/5.10.1/i486-linux +-gnu-thread-multi/CORE" perltext1_pl_f7f6.c perltext1_pl_f7f6.xs: In function ‘just_compile’: perltext1_pl_f7f6.xs:5: error: ‘bla’ undeclared (first use in this fun +ction) perltext1_pl_f7f6.xs:5: error: (Each undeclared identifier is reported + only once perltext1_pl_f7f6.xs:5: error: for each function it appears in.) make: *** [perltext1_pl_f7f6.o] Error 1 A problem was encountered while attempting to compile and install your + Inline C code. The command that failed was: make > out.make 2>&1 The build directory was: /home/jest/temp/t/_Inline/build/perltext1_pl_f7f6 To debug the problem, cd to the build directory, and inspect the outpu +t files. at line 8

      BTW, PerlTeX handles normal die-s just fine; but in this case it can't handle errors.

        I contacted Scott Pakin, author of PerlTeX. He corrected the program to be more robust under complicated environments, like Inline::C. It will soon hit CTAN. I checked the corrected PerlTeX, works with the above example just fine!

        However, I was in a (time-constrained) need to parse the mentioned structures, so I wrote a little module of my own, Data::Typed::Expression. The very early version should be on CPAN soon.

Re: C-like structures parsing and validation
by jmcnamara (Monsignor) on Nov 17, 2009 at 06:14 UTC

    Convert::Binary::C may do what you want.

    It will parse the C structs into Perl structures and you may be able to do your validation from there. From the docs:

    use Convert::Binary::C; #--------------------------------------------- # Create a new object and parse embedded code #--------------------------------------------- my $c = Convert::Binary::C->new->parse(<<ENDC); enum Month { JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC }; struct Date { int year; enum Month month; int day; }; ENDC #----------------------------------------------- # Pack Perl data structure into a binary string #----------------------------------------------- my $date = { year => 2002, month => 'DEC', day => 24 }; my $packed = $c->pack('Date', $date);


      This is nice! However, the module restricts one to use only constants as array indices, required to calculate offsets, etc. So it will not handle more complicated expressions:

      use Convert::Binary::C; use 5.010; my $structs = <<EOT; struct vertex { int id; double lon; double lat; }; struct arc { struct vertex from; struct vertex to; double cost; }; struct graph { struct vertex v[]; struct arc a[]; }; EOT $c = Convert::Binary::C->new; $c->parse($structs); # now we can validate say $c->typeof("graph"); # says "struct graph" say $c->typeof("graph.v[0].id"); # says "int" say $c->typeof("graph.v[graph.v[0].id].id"); # error: Array indices m +ust be constant decimal values

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://807424]
Approved by Corion
and a kettle whistles...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (6)
As of 2017-07-28 17:03 GMT
Find Nodes?
    Voting Booth?
    I came, I saw, I ...

    Results (431 votes). Check out past polls.