My Project
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Classes | Public Member Functions | Private Member Functions | Private Attributes | List of all members
ExpressionParser Class Reference

Recursive decent parser for Django style template expressions. More...

Classes

class  ExprToken
 Class representing a token within an expression. More...
 

Public Member Functions

 ExpressionParser (const TemplateParser *parser, int line)
 
virtual ~ExpressionParser ()
 
ExprAstparse (const char *expr)
 

Private Member Functions

ExprAstparseExpression ()
 
ExprAstparseOrExpression ()
 
ExprAstparseAndExpression ()
 
ExprAstparseNotExpression ()
 
ExprAstparseCompareExpression ()
 
ExprAstparseAdditiveExpression ()
 
ExprAstparseMultiplicativeExpression ()
 
ExprAstparseUnaryExpression ()
 
ExprAstparsePrimaryExpression ()
 
ExprAstparseNumber ()
 
ExprAstparseIdentifier ()
 
ExprAstparseLiteral ()
 
ExprAstparseIdentifierOptionalArgs ()
 
ExprAstparseFilteredVariable ()
 
ExprAstFilterparseFilter ()
 
bool getNextToken ()
 

Private Attributes

const TemplateParserm_parser
 
ExprToken m_curToken
 
int m_line
 
const char * m_tokenStream
 

Detailed Description

Recursive decent parser for Django style template expressions.

Definition at line 1748 of file template.cpp.

Constructor & Destructor Documentation

ExpressionParser::ExpressionParser ( const TemplateParser parser,
int  line 
)
inline

Definition at line 1751 of file template.cpp.

: m_parser(parser), m_line(line), m_tokenStream(0)
{
}
virtual ExpressionParser::~ExpressionParser ( )
inlinevirtual

Definition at line 1755 of file template.cpp.

{
}

Member Function Documentation

bool ExpressionParser::getNextToken ( )
inlineprivate

Definition at line 2083 of file template.cpp.

References Operator::And, Operator::Colon, Operator::Comma, Operator::Divide, Operator::Equal, Operator::Filter, Operator::Greater, Operator::GreaterEqual, ExpressionParser::ExprToken::id, ExpressionParser::ExprToken::Identifier, Operator::LeftParen, Operator::Less, Operator::LessEqual, ExpressionParser::ExprToken::Literal, m_curToken, m_line, m_parser, m_tokenStream, Operator::Minus, Operator::Modulo, Operator::Multiply, Operator::Not, Operator::NotEqual, ExpressionParser::ExprToken::num, ExpressionParser::ExprToken::Number, ExpressionParser::ExprToken::op, ExpressionParser::ExprToken::Operator, Operator::Or, Operator::Plus, Operator::RightParen, TemplateParser::templateName(), ExpressionParser::ExprToken::type, ExpressionParser::ExprToken::Unknown, and warn().

Referenced by parse(), parseAdditiveExpression(), parseAndExpression(), parseCompareExpression(), parseFilter(), parseFilteredVariable(), parseIdentifier(), parseIdentifierOptionalArgs(), parseLiteral(), parseMultiplicativeExpression(), parseNotExpression(), parseNumber(), parseOrExpression(), parsePrimaryExpression(), and parseUnaryExpression().

{
const char *p = m_tokenStream;
char s[2];
s[1]=0;
if (p==0 || *p=='\0') return FALSE;
while (*p==' ') p++; // skip over spaces
char c=*p;
if (*p=='\0') // only spaces...
{
return FALSE;
}
const char *q = p;
switch (c)
{
case '=':
if (c=='=' && *(p+1)=='=') // equal
{
p+=2;
}
break;
case '!':
if (c=='!' && *(p+1)=='=') // not equal
{
p+=2;
}
break;
case '<':
if (c=='<' && *(p+1)=='=') // less or equal
{
p+=2;
}
else // less
{
p++;
}
break;
case '>':
if (c=='>' && *(p+1)=='=') // greater or equal
{
p+=2;
}
else // greater
{
p++;
}
break;
case '(':
p++;
break;
case ')':
p++;
break;
case '|':
p++;
break;
case '+':
p++;
break;
case '-':
p++;
break;
case '*':
p++;
break;
case '/':
p++;
break;
case '%':
p++;
break;
case ':':
p++;
break;
case ',':
p++;
break;
case 'n':
if (strncmp(p,"not ",4)==0)
{
p+=4;
}
break;
case 'a':
if (strncmp(p,"and ",4)==0)
{
p+=4;
}
break;
case 'o':
if (strncmp(p,"or ",3)==0)
{
p+=3;
}
break;
default:
break;
}
if (p!=q) // found an operator
{
}
else // no token found yet
{
if (c>='0' && c<='9') // number?
{
const char *np = p;
while (*np>='0' && *np<='9')
{
m_curToken.num+=*np-'0';
np++;
}
p=np;
}
else if (c=='_' || (c>='a' && c<='z') || (c>='A' && c<='Z')) // identifier?
{
s[0]=c;
p++;
while ((c=*p) &&
(c=='_' || c=='.' ||
(c>='a' && c<='z') ||
(c>='A' && c<='Z') ||
(c>='0' && c<='9'))
)
{
s[0]=c;
p++;
}
if (m_curToken.id=="True") // treat true literal as numerical 1
{
}
else if (m_curToken.id=="False") // treat false literal as numerical 0
{
}
}
else if (c=='"' || c=='\'') // string literal
{
m_curToken.id.resize(0);
p++;
char tokenChar = c;
char cp=0;
while ((c=*p) && (c!=tokenChar || (c==tokenChar && cp=='\\')))
{
s[0]=c;
if (c!='\\' || cp=='\\') // don't add escapes
{
}
cp=c;
p++;
}
if (*p==tokenChar) p++;
}
}
if (p==q) // still no valid token found -> error
{
char s[2];
s[0]=c;
s[1]=0;
warn(m_parser->templateName(),m_line,"Found unknown token '%s' (%d) while parsing %s",s,c,m_tokenStream);
p++;
}
//TRACE(("token type=%d op=%d num=%d id=%s\n",
// m_curToken.type,m_curToken.op,m_curToken.num,m_curToken.id.data()));
return TRUE;
}
ExprAst* ExpressionParser::parse ( const char *  expr)
inline
ExprAst* ExpressionParser::parseAdditiveExpression ( )
inlineprivate
ExprAst* ExpressionParser::parseAndExpression ( )
inlineprivate
ExprAst* ExpressionParser::parseCompareExpression ( )
inlineprivate
ExprAst* ExpressionParser::parseExpression ( )
inlineprivate

Definition at line 1787 of file template.cpp.

References m_tokenStream, parseOrExpression(), and TRACE.

Referenced by parse(), and parsePrimaryExpression().

{
TRACE(("{parseExpression(%s)\n",m_tokenStream));
TRACE(("}parseExpression(%s)\n",m_tokenStream));
return result;
}
ExprAstFilter* ExpressionParser::parseFilter ( )
inlineprivate
ExprAst* ExpressionParser::parseFilteredVariable ( )
inlineprivate

Definition at line 2046 of file template.cpp.

References Operator::Filter, filter(), getNextToken(), m_curToken, ExpressionParser::ExprToken::op, ExpressionParser::ExprToken::Operator, parseFilter(), parseIdentifierOptionalArgs(), TRACE, and ExpressionParser::ExprToken::type.

Referenced by parsePrimaryExpression().

{
TRACE(("{parseFilteredVariable()\n"));
if (expr)
{
{
if (!filter) break;
expr = new ExprAstFilterAppl(expr,filter);
}
}
TRACE(("}parseFilteredVariable()\n"));
return expr;
}
ExprAst* ExpressionParser::parseIdentifier ( )
inlineprivate

Definition at line 2001 of file template.cpp.

References getNextToken(), ExpressionParser::ExprToken::id, m_curToken, and TRACE.

Referenced by parseIdentifierOptionalArgs().

{
TRACE(("{parseIdentifier(%s)\n",m_curToken.id.data()));
TRACE(("}parseIdentifier()\n"));
return id;
}
ExprAst* ExpressionParser::parseIdentifierOptionalArgs ( )
inlineprivate

Definition at line 2019 of file template.cpp.

References Operator::Colon, Operator::Comma, getNextToken(), ExpressionParser::ExprToken::id, m_curToken, ExpressionParser::ExprToken::op, ExpressionParser::ExprToken::Operator, parseIdentifier(), parsePrimaryExpression(), TRACE, and ExpressionParser::ExprToken::type.

Referenced by parseFilteredVariable().

{
TRACE(("{parseIdentifierOptionalArgs(%s)\n",m_curToken.id.data()));
if (expr)
{
{
QList<ExprAst> args;
args.append(argExpr);
{
args.append(argExpr);
}
expr = new ExprAstFunctionVariable(expr,args);
}
}
TRACE(("}parseIdentifierOptionalArgs()\n"));
return expr;
}
ExprAst* ExpressionParser::parseLiteral ( )
inlineprivate

Definition at line 2010 of file template.cpp.

References getNextToken(), ExpressionParser::ExprToken::id, m_curToken, and TRACE.

Referenced by parsePrimaryExpression().

{
TRACE(("{parseLiteral(%s)\n",m_curToken.id.data()));
TRACE(("}parseLiteral()\n"));
return expr;
}
ExprAst* ExpressionParser::parseMultiplicativeExpression ( )
inlineprivate
ExprAst* ExpressionParser::parseNotExpression ( )
inlineprivate

Definition at line 1831 of file template.cpp.

References getNextToken(), m_curToken, m_line, m_parser, m_tokenStream, Operator::Not, ExpressionParser::ExprToken::op, ExpressionParser::ExprToken::Operator, parseCompareExpression(), TemplateParser::templateName(), TRACE, ExpressionParser::ExprToken::type, and warn().

Referenced by parseAndExpression(), and parseCompareExpression().

{
TRACE(("{parseNotExpression(%s)\n",m_tokenStream));
ExprAst *result=0;
{
if (expr==0)
{
warn(m_parser->templateName(),m_line,"argument missing for not operator");
return 0;
}
result = new ExprAstNegate(expr);
}
else
{
}
TRACE(("}parseNotExpression(%s)\n",m_tokenStream));
return result;
}
ExprAst* ExpressionParser::parseNumber ( )
inlineprivate

Definition at line 1992 of file template.cpp.

References getNextToken(), m_curToken, ExpressionParser::ExprToken::num, and TRACE.

Referenced by parsePrimaryExpression().

{
TRACE(("{parseNumber(%d)\n",m_curToken.num));
TRACE(("}parseNumber()\n"));
return num;
}
ExprAst* ExpressionParser::parseOrExpression ( )
inlineprivate
ExprAst* ExpressionParser::parsePrimaryExpression ( )
inlineprivate

Definition at line 1949 of file template.cpp.

References getNextToken(), ExpressionParser::ExprToken::Identifier, Operator::LeftParen, ExpressionParser::ExprToken::Literal, m_curToken, m_line, m_parser, m_tokenStream, ExpressionParser::ExprToken::Number, ExpressionParser::ExprToken::op, ExpressionParser::ExprToken::Operator, parseExpression(), parseFilteredVariable(), parseLiteral(), parseNumber(), Operator::RightParen, TemplateParser::templateName(), Operator::toString(), TRACE, ExpressionParser::ExprToken::type, and warn().

Referenced by parseFilter(), parseIdentifierOptionalArgs(), and parseUnaryExpression().

{
TRACE(("{parsePrimary(%s)\n",m_tokenStream));
ExprAst *result=0;
switch (m_curToken.type)
{
result = parseNumber();
break;
break;
result = parseLiteral();
break;
{
getNextToken(); // skip over opening bracket
result = parseExpression();
{
warn(m_parser->templateName(),m_line,"missing closing parenthesis");
}
else
{
getNextToken(); // skip over closing bracket
}
}
else
{
warn(m_parser->templateName(),m_line,"unexpected operator '%s' in expression",
}
break;
default:
warn(m_parser->templateName(),m_line,"unexpected token in expression");
}
TRACE(("}parsePrimary(%s)\n",m_tokenStream));
return result;
}
ExprAst* ExpressionParser::parseUnaryExpression ( )
inlineprivate

Member Data Documentation

ExprToken ExpressionParser::m_curToken
private
int ExpressionParser::m_line
private

Definition at line 2287 of file template.cpp.

Referenced by getNextToken(), parseNotExpression(), and parsePrimaryExpression().

const TemplateParser* ExpressionParser::m_parser
private

Definition at line 2285 of file template.cpp.

Referenced by getNextToken(), parseNotExpression(), and parsePrimaryExpression().

const char* ExpressionParser::m_tokenStream
private

The documentation for this class was generated from the following file: