Version française
Home     About     Download     Resources     Contact us    
Browse thread
OCaml && COCOA-Environment (Mac-OS-X/GUI)
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Jeff Henrikson <jehenrik@y...>
Subject: Re: OCaml && COCOA-Environment (Mac-OS-X/GUI)
> >I have an email out with Mr. Casse regarding how he feels about 
> >merging these changes.  An Obj-C and/or C++ extension should 
> >preferably begin with a "blessed" starting point.
> >
> I agree, and wonder whether there's consensus as to whether 3.1 should 
> be that starting point, or whether we should (need to, for Forklift's 
> sake?) integrate the Cil and 3.1 changes.

Upon superficial examination, the Frontc 2.0 -> 3.1 changes seem to mostly revolve around XML output.  The Cil frontc changes are more about parsing header files "in the wild".  Look at the Cil manual chapter 17 for the level of energy put into parsing messy stuff:

http://manju.cs.berkeley.edu/cil/cil017.html

> This sounds very nice! How would you suggest that we proceed toward 
> Objective-C coverage in conjunction with your other requirements and 
> observations about the status of Frontc and Cil?

Well, I see three possible paths.  

1) get Frontc and Cil Frontc merged.  Extend the ast and parser for Obj-C and/or C++.  I know C++ much better than ObjC, but my sense is that ObjC is easier for this.

2) gccxml is a patch for gcc made for a java C++ stub generator.  The idea is that you specify some flags to gcc and it spews XML of the parse tree.  gccxml was build for doing C++, so there may be some additions necessary to get all the ObjC primitives.  Below I attach some output from gccxml on the semi-commercial C++ 3D toolkit Nebula2.  Messy as you can see, but vastly easier than dealing with raw text.  I personally mourn the fact that massive amounts of open source labor is wasted rewriting parsers.  In my mind a parser is a generic thing 

3) yaxx is an extension to yacc which takes any .y file, and generates a modified C program which outputs .xml and a .dtd instead of just running.  This means that one can take, for example the gcc .y file, and get a .xml output C program without modifying gcc.  I really like this approach, the beauty is that it holds promise for maybe someday not needing to write a parser for every last target language.  (It seems wrong to me that we need an ocamlyacc to begin with.  There needs to be available some standard behavior which ignores the actions of a .y file and just spews an AST.  Not to mention tree walkers and other useful things.)  They have tried the gcc parser hack, and the comments say it is supposed to handle C and Obj-C (not C++?) but I can't get that part to work.  I can get the ansic, sql and java parts to work.  I copy paste below xml output for the ansi parser.  Incidentally, there's some incompatibility in the build for darwin, I needed to use a linux box.  If you search and replace all instances of stdout to another identifier in the generated ansic/gram.tab.c, it compiles on darwin but I haven't checked if the behavior is right.

Any of the three solutions basically entail getting the output back to a Cabs (frontc) similar representation.  It will be necessary to add a named attributes for parent class, language and so on, but that would be my basic strategy.

Cheers,


Jeff


gccxml on nebula2 test:


****************************gfx2/nmesh2.h***********************************

class N_PUBLIC nMesh2 : public nResource
{
public:
    enum Usage
    {
        WriteOnce,      // (default) CPU only fills the vertex buffer once, and 
never touches it again
        ReadOnly,       // CPU reads from the vertex buffer, which can never be 
rendered
        WriteOnly,      // CPU writes frequently to vertex buffer, but never rea
d data back
    };

    enum VertexComponent
    {
        Coord    = (1<<0),
        Normal   = (1<<1),
        Tangent  = (1<<2),
        Binormal = (1<<3),

    /// constructor
    nMesh2();
    /// destructor
    virtual ~nMesh2();
    /// unload mesh resource
    virtual void Unload();
    /// lock vertex buffer
    virtual float* LockVertices();
    /// unlock vertex buffer
    virtual void UnlockVertices();

******************************XML output****************************************

  <Class id="_4" name="nMesh2" context="_1" mangled="6nMesh2" location="f0:90" f
ile="f0" line="90" members="_560 _561 _562 _563 _564 _565 _566 _567 _568 _569 _5
70 _571 _572 _573 _574 _575 _576 _577 _578 _579 _580 _581 _582 _583 _584 _585 _5
86 _587 _588 _589 _590 _591 _592 _593 _594 _595 _596 _597 _598 _599 " bases="_19
1 "/>

..

  <Enumeration id="_571" name="Usage" context="_4" location="f0:93" file="f0" li
ne="93">
    <EnumValue name="WriteOnce" init="0"/>
    <EnumValue name="ReadOnly" init="1"/>
    <EnumValue name="WriteOnly" init="2"/>
  </Enumeration>

...
  <Enumeration id="_572" name="VertexComponent" context="_4" location="f0:100" f
ile="f0" line="100">
    <EnumValue name="Coord" init="1"/>
    <EnumValue name="Normal" init="2"/>
    <EnumValue name="Tangent" init="4"/>
    <EnumValue name="Binormal" init="8"/>
...
  </Enumeration>
...

  <Constructor id="_573" name="nMesh2" artificial="1" context="_4" mangled="_ZN6
nMesh2C1ERKS_ *INTERNAL* " location="f0:90" file="f0" line="90">
    <Argument name="_ctor_arg" type="_1296"/>
  </Constructor>
  <Constructor id="_574" name="nMesh2" context="_4" mangled="_ZN6nMesh2C1Ev *INT
ERNAL* " location="f0:115" file="f0" line="115" extern="1"/>
  <Destructor id="_575" name="nMesh2" virtual="1" context="_4" mangled="_ZN6nMes
h2D1Ev *INTERNAL* " location="f0:117" file="f0" line="117" extern="1">
  </Destructor>
  <Method id="_576" name="Unload" returns="_729" virtual="1" context="_4" mangle
d="_ZN6nMesh26UnloadEv" location="f0:119" file="f0" line="119" extern="1"/>
  <Method id="_577" name="LockVertices" returns="_833" virtual="1" context="_4" 
mangled="_ZN6nMesh212LockVerticesEv" location="f0:121" file="f0" line="121" exte
rn="1"/>
  <Method id="_578" name="UnlockVertices" returns="_729" virtual="1" context="_4
" mangled="_ZN6nMesh214UnlockVerticesEv" location="f0:123" file="f0" line="123" 
extern="1"/>



yaxx on hello world test, xml, dtd follows:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="yaxx.xsl"?><!DOCTYPE file SYSTEM "yyyaxx.dtd">
<yaxx:file xmlns:yaxx="urn:YAcc-Xml-eXtension">
<yaxx:external_definition>
<yaxx:function_definition>
<yaxx:declaration_specifiers>
<yaxx:type_specifier>
<yaxx:INT>int</yaxx:INT>
</yaxx:type_specifier>
</yaxx:declaration_specifiers>
<yaxx:declarator>
<yaxx:declarator2>
<yaxx:declarator2>
<yaxx:identifier>
<yaxx:IDENTIFIER>main</yaxx:IDENTIFIER>
</yaxx:identifier>
</yaxx:declarator2>
<yaxx:PUNCT_LPAR>(</yaxx:PUNCT_LPAR>
<yaxx:PUNCT_RPAR>)</yaxx:PUNCT_RPAR>
</yaxx:declarator2>
</yaxx:declarator>
<yaxx:function_body>
<yaxx:compound_statement>
<yaxx:PUNCT_LBRACE>{</yaxx:PUNCT_LBRACE>
<yaxx:statement_list>
<yaxx:statement>
<yaxx:jump_statement>
<yaxx:RETURN>return</yaxx:RETURN>
<yaxx:expr>
<yaxx:assignment_expr>
<yaxx:conditional_expr>
<yaxx:logical_or_expr>
<yaxx:logical_and_expr>
<yaxx:inclusive_or_expr>
<yaxx:exclusive_or_expr>
<yaxx:and_expr>
<yaxx:equality_expr>
<yaxx:relational_expr>
<yaxx:shift_expr>
<yaxx:additive_expr>
<yaxx:multiplicative_expr>
<yaxx:cast_expr>
<yaxx:unary_expr>
<yaxx:postfix_expr>
<yaxx:primary_expr>
<yaxx:PUNCT_LPAR>(</yaxx:PUNCT_LPAR>
<yaxx:expr>
<yaxx:assignment_expr>
<yaxx:conditional_expr>
<yaxx:logical_or_expr>
<yaxx:logical_and_expr>
<yaxx:inclusive_or_expr>
<yaxx:exclusive_or_expr>
<yaxx:and_expr>
<yaxx:equality_expr>
<yaxx:relational_expr>
<yaxx:shift_expr>
<yaxx:additive_expr>
<yaxx:multiplicative_expr>
<yaxx:cast_expr>
<yaxx:unary_expr>
<yaxx:postfix_expr>
<yaxx:postfix_expr>
<yaxx:primary_expr>
<yaxx:identifier>
<yaxx:IDENTIFIER>yyparse</yaxx:IDENTIFIER>
</yaxx:identifier>
</yaxx:primary_expr>
</yaxx:postfix_expr>
<yaxx:PUNCT_LPAR>(</yaxx:PUNCT_LPAR>
<yaxx:PUNCT_RPAR>)</yaxx:PUNCT_RPAR>
</yaxx:postfix_expr>
</yaxx:unary_expr>
</yaxx:cast_expr>
</yaxx:multiplicative_expr>
</yaxx:additive_expr>
</yaxx:shift_expr>
</yaxx:relational_expr>
</yaxx:equality_expr>
</yaxx:and_expr>
</yaxx:exclusive_or_expr>
</yaxx:inclusive_or_expr>
</yaxx:logical_and_expr>
</yaxx:logical_or_expr>
</yaxx:conditional_expr>
</yaxx:assignment_expr>
</yaxx:expr>
<yaxx:PUNCT_RPAR>)</yaxx:PUNCT_RPAR>
</yaxx:primary_expr>
</yaxx:postfix_expr>
</yaxx:unary_expr>
</yaxx:cast_expr>
</yaxx:multiplicative_expr>
</yaxx:additive_expr>
</yaxx:shift_expr>
</yaxx:relational_expr>
</yaxx:equality_expr>
</yaxx:and_expr>
</yaxx:exclusive_or_expr>
</yaxx:inclusive_or_expr>
</yaxx:logical_and_expr>
</yaxx:logical_or_expr>
</yaxx:conditional_expr>
</yaxx:assignment_expr>
</yaxx:expr>
<yaxx:PUNCT_SEMICOLON>;</yaxx:PUNCT_SEMICOLON>
</yaxx:jump_statement>
</yaxx:statement>
</yaxx:statement_list>
<yaxx:PUNCT_RBRACE>}</yaxx:PUNCT_RBRACE>
</yaxx:compound_statement>
</yaxx:function_body>
</yaxx:function_definition>
</yaxx:external_definition>
</yaxx:file>





dtd, hmm this doesn't seem to match much:


<!ELEMENT primary_expr (identifier | CONSTANT | STRING_LITERAL | (PUNCT_LPAR,expr,PUNCT_RPAR))>
<!ELEMENT postfix_expr (primary_expr | (postfix_expr,PUNCT_LBRACKET,expr,PUNCT_RBRACKET) | (postfix_expr,PUNCT_LPAR,PUNCT_RPAR) | (postfix_expr,PUNCT_LPAR,argument_expr_list,PUNCT_RPAR) | (postfix_expr,PUNCT_DOT,identifier) | (postfix_expr,PTR_OP,identifier) | (postfix_expr,INC_OP) | (postfix_expr,DEC_OP))>
<!ELEMENT argument_expr_list (assignment_expr | (argument_expr_list,PUNCT_COMMA,assignment_expr))>
<!ELEMENT unary_expr (postfix_expr | (INC_OP,unary_expr) | (DEC_OP,unary_expr) | (unary_operator,cast_expr) | (SIZEOF,unary_expr) | (SIZEOF,PUNCT_LPAR,type_name,PUNCT_RPAR))>
<!ELEMENT unary_operator (PUNCT_AMBLE | PUNCT_STAR | PUNCT_PLUS | PUNCT_MINUS | PUNCT_TILDE | PUNCT_EXCLAIM)>
<!ELEMENT cast_expr (unary_expr | (PUNCT_LPAR,type_name,PUNCT_RPAR,cast_expr))>
<!ELEMENT multiplicative_expr (cast_expr | (multiplicative_expr,PUNCT_STAR,cast_expr) | (multiplicative_expr,PUNCT_DIV,cast_expr) | (multiplicative_expr,PUNCT_PERCENT,cast_expr))>
<!ELEMENT additive_expr (multiplicative_expr | (additive_expr,PUNCT_PLUS,multiplicative_expr) | (additive_expr,PUNCT_MINUS,multiplicative_expr))>
<!ELEMENT shift_expr (additive_expr | (shift_expr,LEFT_OP,additive_expr) | (shift_expr,RIGHT_OP,additive_expr))>
<!ELEMENT relational_expr (shift_expr | (relational_expr,PUNCT_LT,shift_expr) | (relational_expr,PUNCT_GT,shift_expr) | (relational_expr,LE_OP,shift_expr) | (relational_expr,GE_OP,shift_expr))>
<!ELEMENT equality_expr (relational_expr | (equality_expr,EQ_OP,relational_expr) | (equality_expr,NE_OP,relational_expr))>
<!ELEMENT and_expr (equality_expr | (and_expr,PUNCT_AMBLE,equality_expr))>
<!ELEMENT exclusive_or_expr (and_expr | (exclusive_or_expr,PUNCT_CARET,and_expr))>
<!ELEMENT inclusive_or_expr (exclusive_or_expr | (inclusive_or_expr,PUNCT_OR,exclusive_or_expr))>
<!ELEMENT logical_and_expr (inclusive_or_expr | (logical_and_expr,AND_OP,inclusive_or_expr))>
<!ELEMENT logical_or_expr (logical_and_expr | (logical_or_expr,OR_OP,logical_and_expr))>
<!ELEMENT conditional_expr (logical_or_expr | (logical_or_expr,PUNCT_QUESTION,logical_or_expr,PUNCT_COLON,conditional_expr))>
<!ELEMENT assignment_expr (conditional_expr | (unary_expr,assignment_operator,assignment_expr))>
<!ELEMENT assignment_operator (PUNCT_EQUAL | MUL_ASSIGN | DIV_ASSIGN | MOD_ASSIGN | ADD_ASSIGN | SUB_ASSIGN | LEFT_ASSIGN | RIGHT_ASSIGN | AND_ASSIGN | XOR_ASSIGN | OR_ASSIGN)>
<!ELEMENT expr (assignment_expr | (expr,PUNCT_COMMA,assignment_expr))>
<!ELEMENT constant_expr (conditional_expr)>
<!ELEMENT declaration ((declaration_specifiers,PUNCT_SEMICOLON) | (declaration_specifiers,init_declarator_list,PUNCT_SEMICOLON))>
<!ELEMENT declaration_specifiers (storage_class_specifier | (storage_class_specifier,declaration_specifiers) | type_specifier | (type_specifier,declaration_specifiers))>
<!ELEMENT init_declarator_list (init_declarator | (init_declarator_list,PUNCT_COMMA,init_declarator))>
<!ELEMENT init_declarator (declarator | (declarator,PUNCT_EQUAL,initializer))>
<!ELEMENT storage_class_specifier (TYPEDEF | EXTERN | STATIC | AUTO | REGISTER)>
<!ELEMENT type_specifier (CHAR | SHORT | INT | LONG | SIGNED | UNSIGNED | FLOAT | DOUBLE | CONST | VOLATILE | VOID | struct_or_union_specifier | enum_specifier | TYPE_NAME)>
<!ELEMENT struct_or_union_specifier ((struct_or_union,identifier,PUNCT_LBRACE,struct_declaration_list,PUNCT_RBRACE) | (struct_or_union,PUNCT_LBRACE,struct_declaration_list,PUNCT_RBRACE))>
<!ELEMENT IDENTIFIER (#PCDATA)>
<!ELEMENT CONSTANT (#PCDATA)>
<!ELEMENT STRING_LITERAL (#PCDATA)>
<!ELEMENT SIZEOF (#PCDATA)>
<!ELEMENT PTR_OP (#PCDATA)>
<!ELEMENT INC_OP (#PCDATA)>
<!ELEMENT DEC_OP (#PCDATA)>
<!ELEMENT LEFT_OP (#PCDATA)>
<!ELEMENT RIGHT_OP (#PCDATA)>
<!ELEMENT LE_OP (#PCDATA)>
<!ELEMENT GE_OP (#PCDATA)>
<!ELEMENT EQ_OP (#PCDATA)>
<!ELEMENT NE_OP (#PCDATA)>
<!ELEMENT AND_OP (#PCDATA)>
<!ELEMENT OR_OP (#PCDATA)>
<!ELEMENT MUL_ASSIGN (#PCDATA)>
<!ELEMENT DIV_ASSIGN (#PCDATA)>
<!ELEMENT MOD_ASSIGN (#PCDATA)>
<!ELEMENT ADD_ASSIGN (#PCDATA)>
<!ELEMENT SUB_ASSIGN (#PCDATA)>
<!ELEMENT LEFT_ASSIGN (#PCDATA)>
<!ELEMENT RIGHT_ASSIGN (#PCDATA)>
<!ELEMENT AND_ASSIGN (#PCDATA)>
<!ELEMENT XOR_ASSIGN (#PCDATA)>
<!ELEMENT OR_ASSIGN (#PCDATA)>
<!ELEMENT TYPE_NAME (#PCDATA)>
<!ELEMENT TYPEDEF (#PCDATA)>
<!ELEMENT EXTERN (#PCDATA)>
<!ELEMENT STATIC (#PCDATA)>
<!ELEMENT AUTO (#PCDATA)>
<!ELEMENT REGISTER (#PCDATA)>
<!ELEMENT CHAR (#PCDATA)>
<!ELEMENT SHORT (#PCDATA)>
<!ELEMENT INT (#PCDATA)>
<!ELEMENT LONG (#PCDATA)>
<!ELEMENT SIGNED (#PCDATA)>
<!ELEMENT UNSIGNED (#PCDATA)>
<!ELEMENT FLOAT (#PCDATA)>
<!ELEMENT DOUBLE (#PCDATA)>
<!ELEMENT CONST (#PCDATA)>
<!ELEMENT VOLATILE (#PCDATA)>
<!ELEMENT VOID (#PCDATA)>
<!ELEMENT STRUCT (#PCDATA)>
<!ELEMENT UNION (#PCDATA)>
<!ELEMENT ENUM (#PCDATA)>
<!ELEMENT ELIPSIS (#PCDATA)>
<!ELEMENT RANGE (#PCDATA)>
<!ELEMENT CASE (#PCDATA)>
<!ELEMENT DEFAULT (#PCDATA)>
<!ELEMENT IF (#PCDATA)>
<!ELEMENT ELSE (#PCDATA)>
<!ELEMENT SWITCH (#PCDATA)>
<!ELEMENT WHILE (#PCDATA)>
<!ELEMENT DO (#PCDATA)>
<!ELEMENT FOR (#PCDATA)>
<!ELEMENT GOTO (#PCDATA)>
<!ELEMENT CONTINUE (#PCDATA)>
<!ELEMENT BREAK (#PCDATA)>
<!ELEMENT RETURN (#PCDATA)>
<!ELEMENT PUNCT_COLON (#PCDATA)>
<!ELEMENT PUNCT_SEMICOLON (#PCDATA)>
<!ELEMENT PUNCT_COMMA (#PCDATA)>
<!ELEMENT PUNCT_DOT (#PCDATA)>
<!ELEMENT PUNCT_EQUAL (#PCDATA)>
<!ELEMENT PUNCT_AMBLE (#PCDATA)>
<!ELEMENT PUNCT_STAR (#PCDATA)>
<!ELEMENT PUNCT_PLUS (#PCDATA)>
<!ELEMENT PUNCT_MINUS (#PCDATA)>
<!ELEMENT PUNCT_TILDE (#PCDATA)>
<!ELEMENT PUNCT_EXCLAIM (#PCDATA)>
<!ELEMENT PUNCT_QUESTION (#PCDATA)>
<!ELEMENT PUNCT_OR (#PCDATA)>
<!ELEMENT PUNCT_DIV (#PCDATA)>
<!ELEMENT PUNCT_PERCENT (#PCDATA)>
<!ELEMENT PUNCT_LT (#PCDATA)>
<!ELEMENT PUNCT_GT (#PCDATA)>
<!ELEMENT PUNCT_CARET (#PCDATA)>
<!ELEMENT PUNCT_LPAR (#PCDATA)>
<!ELEMENT PUNCT_RPAR (#PCDATA)>
<!ELEMENT PUNCT_LBRACKET (#PCDATA)>
<!ELEMENT PUNCT_RBRACKET (#PCDATA)>
<!ELEMENT PUNCT_LBRACE (#PCDATA)>
<!ELEMENT PUNCT_RBRACE (#PCDATA)>