1#import <Foundation/Foundation.h> 2#import <ANTLR/ANTLR.h> 3#import "SimpleCLexer.h" 4#import "SimpleCParser.h" 5#import "SimpleCWalker.h" 6#import "stdio.h" 7#include <unistd.h> 8 9int main(int argc, const char * argv[]) { 10 NSError *anError; 11 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 12 char *inp = "/Users/acondit/source/antlr/code/antlr3/runtime/ObjC/Framework/examples/simplecTreeParser/input"; 13 14/* 15 if (argc < 2) { 16 NSLog(@"provide the input file, please"); 17 return 1; 18 } 19 */ 20 21 // simply read in the input file in one gulp 22 NSString *string = [NSString stringWithContentsOfFile:[NSString stringWithCString:inp encoding:NSASCIIStringEncoding] encoding:NSASCIIStringEncoding error:&anError]; 23 NSLog(@"input is : %@", string); 24 25 // create a stream over the input, so the lexer can seek back and forth, but don't copy the string, 26 // as we make sure it will not go away. 27 // If the string would be coming from a volatile source, say a text field, we could opt to copy the string. 28 // That way we could do the parsing in a different thread, and still let the user edit the original string. 29 // But here we do it the simple way. 30 ANTLRStringStream *stream = [ANTLRStringStream newANTLRStringStream:string]; 31 32 // Actually create the lexer feeding of the character stream. 33 SimpleCLexer *lexer = [SimpleCLexer newSimpleCLexerWithCharStream:stream]; 34 35 // For fun, you could print all tokens the lexer recognized, but we can only do it once. After that 36 // we would need to reset the lexer, and lex again. 37// id<Token> currentToken; 38// while ((currentToken = [lexer nextToken]) && [currentToken type] != TokenTypeEOF) { 39// NSLog(@"%@", currentToken); 40// } 41// [lexer reset]; 42 43 // Since the parser needs to scan back and forth over the tokens, we put them into a stream, too. 44 CommonTokenStream *tokenStream = [CommonTokenStream newCommonTokenStreamWithTokenSource:lexer]; 45 46 // Construct a parser and feed it the token stream. 47 SimpleCParser *parser = [[SimpleCParser alloc] initWithTokenStream:tokenStream]; 48 49 // We start the parsing process by calling a parser rule. In theory you can call any parser rule here, 50 // but it obviously has to match the input token stream. Otherwise parsing would fail. 51 // Also watch out for internal dependencies in your grammar (e.g. you use a symbol table that's only 52 // initialized when you call a specific parser rule). 53 // This is a simple example, so we just call the top-most rule 'program'. 54 // Since we want to parse the AST the parser builds, we just ask the returned object for that. 55 CommonTree *program_tree = [[parser program] getTree]; 56 57 NSLog(@"Reached end of first parse\n"); 58 // Print the matched tree as a Lisp-style string 59 NSLog(@"tree: %@", [program_tree treeDescription]); 60 61 // Create a new tree node stream that's feeding off of the root node (thus seeing the whole tree) 62 CommonTreeNodeStream *treeStream = [CommonTreeNodeStream newCommonTreeNodeStream:program_tree]; 63 // tell the TreeNodeStream where the tokens originally came from, so we can retrieve arbitrary tokens and their text. 64 [treeStream setTokenStream:tokenStream]; 65 66 // Create the treeparser instance, passing it the stream of nodes 67 SimpleCWalker *walker = [[SimpleCWalker alloc] initWithStream:treeStream]; 68 // As with parsers, you can invoke any treeparser rule here. 69 [walker program]; 70 71 // Whew, done. Release everything that we are responsible for. 72 [lexer release]; 73 [stream release]; 74 [tokenStream release]; 75 [parser release]; 76 [treeStream release]; 77 [walker release]; 78 79 [pool release]; 80 81 // use this for ObjectAlloc on Tiger 82 //while(1) sleep(5); 83 return 0; 84}