Benjamin Halsted // [bgh] todo, add something clever here.

25Feb/08Off

C++ and Spirit

So I've been busy doing taxes, getting over my cold, and refreshing my C++. As part of the C++ refreshing I was using Antlr and some STL libraries. While looking at the STL libs I also went to look at Boost, only to find Spirit, a C++ recursive descent parser. I haven't looked at it much, but I'm going to re-do the first couple examples using it, and compare them to the Antlr versions. It may be better suited for what I'm doing since Antlr 3 doesn't have a (working?) C++ output. I know already that if I switch, I'm going to miss AntlrWorks. ;-)

Filed under: Code No Comments
12Feb/08Off

Antl3 actions in C

I started working with rule actions in Antlr 3 + C (A3C). In section 3.2 of the book Terence adds an action to load a stored value from a recognized ID. I decided to keep it simple and just print out some information for that recognized ID. My action grammar:

atom returns [int value]

    :    INT
    |    ID
        {
        printf("Position: \%d\nToken Index: \%d\nText: \%s\n", $ID.pos, $ID.index, $ID.text->chars);
        }
    |    '(' expr ')'

As you can see, the rule for atom is looking for ID which is defined as ('a'..'z'|'A'..'Z')+. When it finds this alphabetic string it's going to print out the position of where it appeared on the line, its index and the value of the token (the matched text).

The action token ID.text is very similar to the Java equivalent, the difference being that it is a struct and to get to the characters you have to use the struct's chars variable. You can find the struct defined in antlr3string.h.

There are a couple of other properties that you can use off of the token variables. Other than .text, you can use: (this is mostly for my own reference). ;-)

  • type
  • line
  • pos
  • channel
  • index
  • tree

TTFN!
 

Filed under: Code No Comments
11Feb/08Off

Y! Q2/07 Hack Day

Today Yahoo! released the AS3 version of their maps API. They also released the hack that Jon and I worked on back in Q2. Check it out, and if you don't have Flash9 and refuse to upgrade, you can try spinning and flicking your iPhone to simulate it*. You almost get the same effect.

*You assume full responsibility for any damages done to your iPhone. 

Filed under: Code 2 Comments
11Feb/08Off

Antlr3 + generated C + OSX

I've been a fan of Antlr for a while now. I've used it to generate intrinsic classes for ActionScript2 so that our team could build an incremental compiler. I just bought the Antlr3 book (in PDF format) and have been going through the examples as I reach them.

As I went through the book I decided that I wanted to combine learning Antlr with my recent LLVM fascination. LLVM is in C/C++ so I decided to use the 'C' output language option in Antlr. I haven't found any documentation on line on how to use the C API, but through some trials I've ported the first example in the book to C.

The first big trial that I faced was that XCode defaults to C++ mode, which is fine for compiling C code as long as you use the right decorations. Some of the Antlr3C support lib uses 'or' which the preprocessor converts to '||'. I spent a day and found that you can disable this by using the '-fno-operator-names' compiler flag.

Most of the code is very similar to the Java version. The second problem I ran into is when you try to connect the dots between creating the lexer and the parser. In Java you just create a CommonTokenStream and pass the lexer into its constructor. In the C version you have to drill down the nested structs to find the token stream. It's not hard to find, it just takes way to long to drill down through the files.

extern "C" {
#import <antlr3.h>
#import "ExprLexer.h"
#import "ExprParser.h"
}

int main (int argc, char * const argv[]) {
    if(argc != 2) {
        printf("Which file do you want to parse?");
        return 0;
    }
   
    pANTLR3_INPUT_STREAM pInputStream = antlr3AsciiFileStreamNew((pANTLR3_UINT8)argv[1]);
   
    pExprLexer exprLex = ExprLexerNew(pInputStream);
   
    pANTLR3_COMMON_TOKEN_STREAM pTokenStream = antlr3CommonTokenStreamSourceNew(0, exprLex->pLexer->tokSource);
   
    pExprParser exprPar  = ExprParserNew(pTokenStream);
   
    exprPar->prog(exprPar);
   
    return 0;
}

Filed under: Code No Comments