[antlr-interest] Objective-C tree grammars with 3.0.1

Basil Shkara bshkara at gmail.com
Mon Nov 12 04:13:37 PST 2007


Thanks Kay!

The newly packaged source worked great.

I do have another issue though.  :)

I've attempted to create a test rig to walk my AST based on Terence's  
Java one from his book.

However upon launching from Xcode, it outputs all my root nodes  
correctly but when it attempts to walk the tree it borks with the  
following:

2007-11-12 22:58:37.619 Expr_Ast[10066:10b] *** Terminating app due to  
uncaught exception 'NSInvalidArgumentException', reason: '*** - 
[NSCFArray replaceObjectAtIndex:withObject:]: attempt to insert nil'

For some reason it doesn't like [walker prog].  I should be able to  
invoke the tree walker with a starting rule.  It doesn't work however.

I'd love some advice regarding this if possible.

I've appended my main.m.

Thanks in advance!
Basil.

#import <Cocoa/Cocoa.h>
#import <ANTLR/ANTLR.h>
#import "ExprLexer.h"
#import "ExprParser.h"
#import "Eval.h"

int main() {
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

	NSString *string = @"a=3\nb=4\n2+a*b\n";
	NSLog(@"input is: %@", string);
	ANTLRStringStream *stream = [[ANTLRStringStream alloc]  
initWithStringNoCopy:string];
	ExprLexer *lexer = [[ExprLexer alloc] initWithCharStream:stream];

	ANTLRCommonTokenStream *tokenStream = [[ANTLRCommonTokenStream alloc]  
initWithTokenSource:lexer];
	ExprParser *parser = [[ExprParser alloc]  
initWithTokenStream:tokenStream];
	// start parsing from the prog grammar
	ExprParser_prog_return *r = [[ExprParser_prog_return alloc] init];
	r = [parser prog];

	// start walking the tree here
	ANTLRCommonTree *t = [[ANTLRCommonTree alloc] initWithTreeNode:[r  
tree]];
	// create a tree node stream from resulting tree
	ANTLRCommonTreeNodeStream *nodes = [[ANTLRCommonTreeNodeStream alloc]  
initWithTree:t];
	Eval *walker = [[Eval alloc] initWithTreeNodeStream:nodes];
	[walker prog];

	[lexer release];
	[stream release];
	[tokenStream release];
	[parser release];
	[r release];
	[t release];
	[nodes release];
	[walker release];

	[pool release];
	return 0;
}

On 12/11/2007, at 3:55 AM, Kay Röpke wrote:

> Hi Basil!
>
> On Nov 11, 2007, at 8:13 AM, Basil Shkara wrote:
>
>> I ran an example tree grammar and set the language option to ObjC  
>> and it generated fine so I guess that answers my previous question  
>> about whether ANTLR supports tree grammars for objective-c.
>>
>> However I still do not understand why my particular grammar is not  
>> able to be generated.  I am going through Terence's book  
>> (Definitive ANTLR reference) and converting the java examples to  
>> objective-c progressively.  So far I have been able to write and  
>> generate everything except for the tree grammar.
>>
>> The grammar I have been trying to generate is below.
>>
>> Any ideas?
>
>
> Turns out that I've broken the ASTLabelType option with a typo in  
> the code generation templates.
> Thanks for catching this!
>
> I've uploaded a fixed version to http://classdump.org/articles/2007/11/11/antlr-3-1-early-access-source
>
> Please note that the copy is straight from the (unreleased) depot  
> version and contains stuff that might not work (it also contains  
> changes to the Java source that might not be in the next release) so  
> proceed with care.
>
> In case you want to fix your existing copy, unpack the antlr3.jar  
> and change the file named ObjC.stg. After the replacement you can  
> repack the jar, or just adjust your classpath accordingly.  
> Alternatively, you can put the modified ObjC.stg into your classpath  
> before the jar. (Sounds complicated, but really isn't ;))
> You need to replace the string "ANTLRASTLabelType" to  
> "ASTLabelType". It's just one occurrence. After that change you  
> grammar goes trough fine, though it might not do what you intended  
> because the references to a and b won't work:
>
> expr returns [NSString *value]
> 		:	^('+' a=expr b=expr)	{$value = a+b;}
> 		|	^('-' a=expr b=expr)	{$value = a-b;}
> 		|	^('*' a=expr b=expr)	{$value = a*b;}
> 		|	ID
> 			{
>
> You need to use $a and $b and make sure that you first convert their  
> string values to integers or floats and then do the arithmetic.

Yep my mistake.  I think something like this will work:
		:	^('+' a=expr b=expr)	{$value = [NSString stringWithFormat:@"\%d",  
[a intValue] + [b intValue]];}
		|	^('-' a=expr b=expr)	{$value = [NSString stringWithFormat:@"\%d",  
[a intValue] - [b intValue]];}
		|	^('*' a=expr b=expr)	{$value = [NSString stringWithFormat:@"\%d",  
[a intValue] * [b intValue]];}

>
>
> HTH,
>
> -k
> -- 
> Kay Röpke
> http://classdump.org/
>
>
>
>
>
>



More information about the antlr-interest mailing list