libs-gsweb/GSWeb.framework/GSWTemplateParserANTLR.m
Manuel Guesdon db19cd7d25 * GSWeb.framework/GSWTemplateParserANTLR.h:
o removed GSWPageDef* includes
* GSWeb.framework/GSWTemplateParserANTLR.m:
  o renamed defintions* to declarations*
  o replaced GSWPageDefElement by GSWDeclaration


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gsweb/trunk@18907 72102866-910b-0410-8b05-ffd578937521
2004-03-25 08:36:00 +00:00

487 lines
21 KiB
Objective-C

/** GSWTemplateParserANTLR.m - <title>GSWeb: Class GSWTemplateParserANTLR</title>
Copyright (C) 1999-2004 Free Software Foundation, Inc.
Written by: Manuel Guesdon <mguesdon@orange-concept.com>
Date: Mar 1999
$Revision$
$Date$
$Id$
This file is part of the GNUstep Web Library.
<license>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
</license>
**/
#include "config.h"
RCS_ID("$Id$")
#include "GSWeb.h"
#include "GSWTemplateParserANTLR.h"
//====================================================================
@implementation GSWTemplateParserANTLR
-(void)dealloc
{
DESTROY(_tagsNames);
DESTROY(_tagsAttrs);
[super dealloc];
};
-(NSArray*)templateElements
{
NSArray* elements=nil;
id<NSObject,ANTLRAST> htmlAST=nil;
NSAutoreleasePool* arpParse=nil;
ANTLRTextInputStreamString* htmlStream=nil;
GSWHTMLLexer* htmlLexer=nil;
ANTLRTokenBuffer* htmlTokenBuffer=nil;
GSWHTMLParser* htmlParser=nil;
LOGObjectFnStart();
NSDebugMLLog(@"low",@"template named:%@ frameworkName:%@ pageDefString=%@",
_templateName,
_frameworkName,
_declarationsString);
//TODO remove
/*
[ANTLRCharBuffer setTraceFlag_LA:YES];
[ANTLRCharScanner setTraceFlag_LA:YES];
[ANTLRLLkParser setTraceFlag_LA:YES];
[ANTLRTokenBuffer setTraceFlag_LA:YES];
*/
htmlStream=[[ANTLRTextInputStreamString newWithString:_string]
autorelease];
htmlLexer=[[[GSWHTMLLexer alloc]initWithTextStream:htmlStream]
autorelease];
htmlTokenBuffer=[ANTLRTokenBuffer tokenBufferWithTokenizer:htmlLexer];
htmlParser=[[[GSWHTMLParser alloc] initWithTokenBuffer:htmlTokenBuffer]
autorelease];
NSDebugMLLog(@"low",@"template named:%@ HTMLString=%@",
_templateName,
_string);
arpParse=[NSAutoreleasePool new];
NS_DURING
{
[htmlParser document];
if ([htmlParser isError])
{
LOGError(@"Parser Errors : %@",[htmlParser errors]);
ExceptionRaise(@"GSWTemplateParser",
@"GSWTemlateParser: Errors in HTML parsing template named %@: %@\nAST:\n%@",
_templateName,
[htmlParser errors],
[htmlParser AST]);
};
htmlAST=[htmlParser AST];
NSDebugMLLog0(@"low",@"HTML Parse OK!");
}
NS_HANDLER
{
LOGError(@"template named:%@ HTML Parse failed!",_templateName);
localException=ExceptionByAddingUserInfoObjectFrameInfo(localException,@"In [htmlParser document]... template named:%@ HTML Parse failed!",_templateName);
RETAIN(localException);
DESTROY(arpParse);
AUTORELEASE(localException);
[localException raise];
}
NS_ENDHANDLER;
[htmlAST retain];
DESTROY(arpParse);
arpParse=[NSAutoreleasePool new];
[htmlAST autorelease];
if (htmlAST)
{
_tagsNames=[[NSMutableDictionary dictionary] retain];
_tagsAttrs=[[NSMutableDictionary dictionary] retain];
NS_DURING
{
elements=[self createElementsStartingWithAST:&htmlAST
stopOnTagNamed:nil];
NSDebugMLLog(@"low",@"template named:%@ _template=%@",
_templateName,
elements);
}
NS_HANDLER
{
LOGSeriousError(@"template named:%@ createElements failed!",
_templateName);
localException=ExceptionByAddingUserInfoObjectFrameInfo0(localException,
@"In createElementsStartingWithAST...");
RETAIN(localException);
DESTROY(arpParse);
AUTORELEASE(localException);
[localException raise];
}
NS_ENDHANDLER;
};
[elements retain];
DESTROY(arpParse);
[elements autorelease];
NSDebugMLLog0(@"low",@"Display Template\n");
NSDebugMLLog(@"low",@"template named:%@ elements=%@",
_templateName,
elements);
LOGClassFnStop();
return elements;
};
//--------------------------------------------------------------------
-(BOOL)parseTag:(ANTLRDefAST)anAST
{
BOOL htmlAttrParseOK=YES;
NSString* tagName=[_tagsNames objectForKey:[NSNumber numberWithUnsignedLong:(unsigned long)anAST]]; //TODO bad hack
LOGClassFnStart();
if (!tagName
&& ([anAST tokenType]==GSWHTMLTokenType_OPENTAG
|| [anAST tokenType]==GSWHTMLTokenType_CLOSETAG))
{
NSAutoreleasePool* arpParse=nil;
ANTLRTextInputStreamString* _tagStream=[[[ANTLRTextInputStreamString alloc]
initWithString:[anAST text]]
autorelease];
GSWHTMLAttrLexer* htmlAttrLexer=[[[GSWHTMLAttrLexer alloc]
initWithTextStream:_tagStream]
autorelease];
ANTLRTokenBuffer* htmlAttrTokenBuffer=[ANTLRTokenBuffer tokenBufferWithTokenizer:htmlAttrLexer];
GSWHTMLAttrParser* _tagParser=[[[GSWHTMLAttrParser alloc] initWithTokenBuffer:htmlAttrTokenBuffer]
autorelease];
NSString* tagName=nil;
NSDictionary* tagAttrs=nil;
NSDebugMLLog(@"low",@"PARSE:[%@]",[anAST text]);
NSDebugMLLog(@"low",@"stream:[%@]",_tagStream);
htmlAttrParseOK=NO;
arpParse=[NSAutoreleasePool new];
NS_DURING
{
[_tagParser tag];
if ([_tagParser isError])
{
LOGError(@"Parser Errors : %@",[_tagParser errors]);
ExceptionRaise(@"GSWTemplateParser",
@"GSWTemlateParser: Errors in HTML Tag parsing: %@",
[_tagParser errors]);
};
tagName=[_tagParser tagName];
tagAttrs=[_tagParser attributes];
NSDebugMLLog(@"low",@"tagName=%@ tagAttrs=%@",
tagName,
tagAttrs);
htmlAttrParseOK=YES;
}
NS_HANDLER
{
htmlAttrParseOK=NO;
LOGError(@"PARSE PB:[%@]",[anAST text]);//TODO
localException=ExceptionByAddingUserInfoObjectFrameInfo0(localException,
@"In [_tagParser tag]...");
RETAIN(localException);
DESTROY(arpParse);
AUTORELEASE(localException);
[localException raise];
}
NS_ENDHANDLER;
DESTROY(arpParse);
NSDebugMLLog(@"low",@"END PARSE:[%@]",[anAST text]);
if (htmlAttrParseOK && tagName)
{
NSDebugMLLog(@"low",@"tagName:[%@]",tagName);
if ([tagName hasPrefix:@"\""] && [tagName hasSuffix:@"\""])
tagName=[[tagName stringByDeletingPrefix:@"\""]stringByDeletingSuffix:@"\""];
NSDebugMLLog(@"low",@"Add tagName:[%@]",
tagName);
[_tagsNames setObject:tagName
forKey:[NSNumber numberWithUnsignedLong:(unsigned long)anAST]]; //TODO bad hack
NSDebugMLLog(@"low",@"Verify tagName=%@",
[_tagsNames objectForKey:[NSNumber numberWithUnsignedLong:(unsigned long)anAST]]); //TODO bad hack
NSDebugMLLog(@"low",@"Add tagsAttrs:[%@]",
tagAttrs);
if (tagAttrs)
{
[_tagsAttrs setObject:tagAttrs
forKey:[NSNumber numberWithUnsignedLong:(unsigned long)anAST]]; //TODO bad hack
NSDebugMLLog(@"low",@"Verify tagAttrs=%@",
[_tagsAttrs objectForKey:[NSNumber numberWithUnsignedLong:(unsigned long)anAST]]); //TODO bad hack
};
};
};
LOGClassFnStop();
return htmlAttrParseOK;
};
//--------------------------------------------------------------------
-(NSString*)getTagNameFor:(ANTLRDefAST)anAST
{
NSString* tagName=[_tagsNames objectForKey:
[NSNumber numberWithUnsignedLong:(unsigned long)anAST]]; //TODO bad hack
LOGClassFnStart();
NSDebugMLLog(@"low",@"[%@]",[anAST text]);
if (!tagName)
{
BOOL htmlAttrParseOK=[self parseTag:anAST];
if (htmlAttrParseOK)
tagName=[_tagsNames objectForKey:
[NSNumber numberWithUnsignedLong:(unsigned long)anAST]]; //TODO bad hack
};
NSDebugMLLog(@"low",@"tagName:[%@]",tagName);
LOGClassFnStop();
return tagName;
};
//--------------------------------------------------------------------
-(NSDictionary*)getTagAttrsFor:(ANTLRDefAST)anAST
{
NSDictionary* tagAttrs=[_tagsAttrs objectForKey:
[NSNumber numberWithUnsignedLong:(unsigned long)anAST]]; //TODO bad hack
LOGClassFnStart();
NSDebugMLLog(@"low",@"[%@]",[anAST text]);
if (!tagAttrs)
{
BOOL htmlAttrParseOK=[self parseTag:anAST];
if (htmlAttrParseOK)
tagAttrs=[_tagsAttrs objectForKey:
[NSNumber numberWithUnsignedLong:(unsigned long)anAST]]; //TODO bad hack
};
NSDebugMLLog(@"low",@"tagAttrs:[%@]",tagAttrs);
LOGClassFnStop();
return tagAttrs;
};
//--------------------------------------------------------------------
-(NSArray*)createElementsStartingWithAST:(ANTLRDefAST*)anAST
stopOnTagNamed:(NSString*)stopTagName
{
NSMutableArray* elements=[NSMutableArray array];
ANTLRDefAST currentAST=*anAST;
BOOL end=NO;
BOOL inHTMLBareString=NO;
NSMutableString* htmlBareString=nil;
LOGClassFnStart();
NSDebugMLLog(@"low",@"stopTagName:[%@]",stopTagName);
while(currentAST && !end)
{
GSWElement* element=nil;
NSString* tagName=nil;
NSDictionary* tagAttrs=nil;
BOOL stopBareString=NO;
NSDebugMLLog(@"low",@"[currentAST: text=[%@] Type=%d",
[currentAST text],
[currentAST tokenType]);
NSDebugMLLog(@"low",@"end=%s inHTMLBareString=%s stopBareString=%s",
end ? "YES" : "NO",
inHTMLBareString ? "YES" : "NO",
stopBareString ? "YES" : "NO");
if ([currentAST tokenType]==GSWHTMLTokenType_OPENTAG
|| [currentAST tokenType]==GSWHTMLTokenType_CLOSETAG)
{
tagName=[self getTagNameFor:currentAST];
NSDebugMLLog(@"low",@"Result tagName:[%@]",tagName);
if (!tagName)
{
LOGError0(@"");//TODO
}
else
{
NSDebugMLLog(@"low",@"[currentAST tokenType]=%d",(int)[currentAST tokenType]);
if ([currentAST tokenType]==GSWHTMLTokenType_OPENTAG)
{
NSDebugMLLog0(@"low",@"Found Open Tag");
tagAttrs=[self getTagAttrsFor:currentAST];
NSDebugMLLog(@"low",@"tagAttrs=%@",tagAttrs);
if ([tagName caseInsensitiveCompare:GSWTag_Name[GSWNAMES_INDEX]]==NSOrderedSame
|| [tagName caseInsensitiveCompare:GSWTag_Name[WONAMES_INDEX]]==NSOrderedSame)
{
NSDebugMLLog0(@"low",@"Found GSWeb Tag");
NSDebugMLLog(@"low",@"tagAttrs=%@",
tagAttrs);
if (inHTMLBareString)
{
NSDebugMLLog0(@"low",@"==>Stop BareString");
stopBareString=YES;
}
else
{
ANTLRDefAST nextAST=[currentAST nextSibling];
NSString* name=[tagAttrs objectForKey:@"name"];
NSDebugMLLog0(@"low",@"Process GSWeb Tag");
NSDebugMLLog(@"low",@"GSWeb Tag: name:[%@]",
name);
if (!name)
{
LOGError(@"No name for Element:%@",
[currentAST text]);//TODO
ExceptionRaise(@"GSWTemplateParser",
@"GSWTemlateParser: no name for GNUstepWeb tag in template named %@",
_templateName);
}
else
{
GSWDeclaration* declaration=[_declarations objectForKey:name];
NSDebugMLLog(@"low",@"declaration:[%@]",
declaration);
NSDebugMLLog(@"low",@"GSWeb Tag declaration:[%@]",
declaration);
if (declaration)
{
NSDictionary* _associations=[declaration associations];
NSString* className=nil;
className=[declaration type];
NSDebugMLLog(@"low",@"GSWeb Tag className:[%@]",
className);
if (className)
{
NSArray* children=nil;
children=[self createElementsStartingWithAST:&nextAST
stopOnTagNamed:tagName];
NSDebugMLLog(@"low",@"CREATE Element of Class:%@",className);
NSDebugMLLog(@"low",@"children:%@",children);
NSDebugMLLog(@"low",@"associations:%@",_associations);
{
NSEnumerator* _tagAttrsEnum = [tagAttrs keyEnumerator];
id _tagAttrKey=nil;
id _tagAttrValue=nil;
NSMutableDictionary* _addedAssoc=nil;
while ((_tagAttrKey = [_tagAttrsEnum nextObject]))
{
if (![_tagAttrKey isEqualToString:@"name"]
&& ![_associations objectForKey:_tagAttrKey])
{
if (!_addedAssoc)
_addedAssoc=(NSMutableDictionary*)[NSMutableDictionary dictionary];
_tagAttrValue=[tagAttrs objectForKey:_tagAttrKey];
[_addedAssoc setObject:[GSWAssociation associationWithValue:_tagAttrValue]
forKey:_tagAttrKey];
};
};
if (_addedAssoc)
{
_associations=[_associations dictionaryByAddingEntriesFromDictionary:_addedAssoc];
};
};
element=[GSWApp dynamicElementWithName:className
associations:_associations
template:[[[GSWHTMLStaticGroup alloc]initWithContentElements:children]autorelease]
languages:_languages];
if (element)
[element setDeclarationName:[declaration name]];
else
{
ExceptionRaise(@"GSWTemplateParser",
@"GSWTemplateParser: Creation failed for element named:%@ className:%@ in template named %@",
[declaration name],
className,
_templateName);
};
}
else
{
ExceptionRaise(@"GSWTemplateParser",
@"GSWTemplateParser: No class name in page definition for tag named:%@ declaration=%@ in template named %@",
name,
declaration,
_templateName);
};
}
else
{
ExceptionRaise(@"GSWTemplateParser",
@"No element definition for tag named:%@ in template named %@",
name,
_templateName);
};
};
currentAST=nextAST;
};
};
}
else
{
if (stopTagName
&& [tagName caseInsensitiveCompare:stopTagName]==NSOrderedSame)
{
NSDebugMLLog(@"low",@"stopTagName found: %@",stopTagName);
end=YES;
stopBareString=YES;
currentAST=[currentAST nextSibling];
};
};
};
}
else if ([currentAST tokenType]==GSWHTMLTokenType_COMMENT)
{
stopBareString=YES;
element=[GSWHTMLComment elementWithString:[currentAST text]];
currentAST=[currentAST nextSibling];
}
NSDebugMLLog(@"low",@"end=%s inHTMLBareString=%s stopBareString=%s",
end ? "YES" : "NO",
inHTMLBareString ? "YES" : "NO",
stopBareString ? "YES" : "NO");
if (!element && !end && !stopBareString)
{
NSDebugMLLog0(@"low",@"!element && !end && !stopBareString");
if (!inHTMLBareString)
{
NSDebugMLLog0(@"low",@"!inHTMLBareString ==> inHTMLBareString=YES");
inHTMLBareString=YES;
htmlBareString=[[NSMutableString new] autorelease];
};
NSDebugMLLog(@"low",@"inHTMLBareString: adding [%@]",[currentAST text]);
if ([currentAST tokenType]==GSWHTMLTokenType_OPENTAG)
[htmlBareString appendFormat:@"<%@>",[currentAST text]];
else if ([currentAST tokenType]==GSWHTMLTokenType_CLOSETAG)
[htmlBareString appendFormat:@"</%@>",[currentAST text]];
else
[htmlBareString appendString:[currentAST text]];
NSDebugMLLog(@"low",@"htmlBareString: ==> [%@]",htmlBareString);
currentAST=[currentAST nextSibling];
};
if (inHTMLBareString && (stopBareString || !currentAST))
{
NSDebugMLLog0(@"low",@"inHTMLBareString && stopBareString");
NSDebugMLLog(@"low",@"CREATE GSWHTMLBareString:\n%@",htmlBareString);
element=[GSWHTMLBareString elementWithString:htmlBareString];
NSDebugMLLog(@"low",@"element:%@",element);
htmlBareString=nil;
inHTMLBareString=NO;
};
if (element)
{
NSDebugMLLog(@"low",@"element to add: element=[%@]",element);
[elements addObject:element];
element=nil;
};
NSDebugMLLog(@"low",@"element:%@",element);
NSDebugMLLog(@"low",@"inHTMLBareString:%d",(int)inHTMLBareString);
NSDebugMLLog(@"low",@"htmlBareString:%@",htmlBareString);
};
*anAST=currentAST;
NSDebugMLLog(@"low",@"elements]:%@",elements);
LOGClassFnStop();
return elements;
};
@end