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 1680 of file template.cpp.

Constructor & Destructor Documentation

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

Definition at line 1683 of file template.cpp.

1684  : m_parser(parser), m_line(line), m_tokenStream(0)
1685  {
1686  }
const TemplateParser * m_parser
Definition: template.cpp:2217
void line(double t, double *p, double &x, double &y, double &z)
const char * m_tokenStream
Definition: template.cpp:2220
virtual ExpressionParser::~ExpressionParser ( )
inlinevirtual

Definition at line 1687 of file template.cpp.

1688  {
1689  }

Member Function Documentation

bool ExpressionParser::getNextToken ( )
inlineprivate

Definition at line 2015 of file template.cpp.

2016  {
2017  const char *p = m_tokenStream;
2018  char s[2];
2019  s[1]=0;
2020  if (p==0 || *p=='\0') return FALSE;
2021  while (*p==' ') p++; // skip over spaces
2022  char c=*p;
2023  if (*p=='\0') // only spaces...
2024  {
2025  m_tokenStream = p;
2026  return FALSE;
2027  }
2028  const char *q = p;
2029  switch (c)
2030  {
2031  case '=':
2032  if (c=='=' && *(p+1)=='=') // equal
2033  {
2035  p+=2;
2036  }
2037  break;
2038  case '!':
2039  if (c=='!' && *(p+1)=='=') // not equal
2040  {
2042  p+=2;
2043  }
2044  break;
2045  case '<':
2046  if (c=='<' && *(p+1)=='=') // less or equal
2047  {
2049  p+=2;
2050  }
2051  else // less
2052  {
2054  p++;
2055  }
2056  break;
2057  case '>':
2058  if (c=='>' && *(p+1)=='=') // greater or equal
2059  {
2061  p+=2;
2062  }
2063  else // greater
2064  {
2066  p++;
2067  }
2068  break;
2069  case '(':
2071  p++;
2072  break;
2073  case ')':
2075  p++;
2076  break;
2077  case '|':
2079  p++;
2080  break;
2081  case '+':
2083  p++;
2084  break;
2085  case '-':
2087  p++;
2088  break;
2089  case '*':
2091  p++;
2092  break;
2093  case '/':
2095  p++;
2096  break;
2097  case '%':
2099  p++;
2100  break;
2101  case ':':
2103  p++;
2104  break;
2105  case ',':
2107  p++;
2108  break;
2109  case 'n':
2110  if (strncmp(p,"not ",4)==0)
2111  {
2113  p+=4;
2114  }
2115  break;
2116  case 'a':
2117  if (strncmp(p,"and ",4)==0)
2118  {
2120  p+=4;
2121  }
2122  break;
2123  case 'o':
2124  if (strncmp(p,"or ",3)==0)
2125  {
2127  p+=3;
2128  }
2129  break;
2130  default:
2131  break;
2132  }
2133  if (p!=q) // found an operator
2134  {
2136  }
2137  else // no token found yet
2138  {
2139  if (c>='0' && c<='9') // number?
2140  {
2142  const char *np = p;
2143  m_curToken.num = 0;
2144  while (*np>='0' && *np<='9')
2145  {
2146  m_curToken.num*=10;
2147  m_curToken.num+=*np-'0';
2148  np++;
2149  }
2150  p=np;
2151  }
2152  else if (c=='_' || (c>='a' && c<='z') || (c>='A' && c<='Z')) // identifier?
2153  {
2155  s[0]=c;
2156  m_curToken.id = s;
2157  p++;
2158  while ((c=*p) &&
2159  (c=='_' || c=='.' ||
2160  (c>='a' && c<='z') ||
2161  (c>='A' && c<='Z') ||
2162  (c>='0' && c<='9'))
2163  )
2164  {
2165  s[0]=c;
2166  m_curToken.id+=s;
2167  p++;
2168  }
2169  if (m_curToken.id=="True") // treat true literal as numerical 1
2170  {
2172  m_curToken.num = 1;
2173  }
2174  else if (m_curToken.id=="False") // treat false literal as numerical 0
2175  {
2177  m_curToken.num = 0;
2178  }
2179  }
2180  else if (c=='"' || c=='\'') // string literal
2181  {
2183  m_curToken.id.resize(0);
2184  p++;
2185  char tokenChar = c;
2186  char cp=0;
2187  while ((c=*p) && (c!=tokenChar || (c==tokenChar && cp=='\\')))
2188  {
2189  s[0]=c;
2190  if (c!='\\' || cp=='\\') // don't add escapes
2191  {
2192  m_curToken.id+=s;
2193  }
2194  cp=c;
2195  p++;
2196  }
2197  if (*p==tokenChar) p++;
2198  }
2199  }
2200  if (p==q) // still no valid token found -> error
2201  {
2203  char s[2];
2204  s[0]=c;
2205  s[1]=0;
2206  warn(m_parser->templateName(),m_line,"Found unknown token '%s' (%d) while parsing %s",s,c,m_tokenStream);
2207  m_curToken.id = s;
2208  p++;
2209  }
2210  //TRACE(("token type=%d op=%d num=%d id=%s\n",
2211  // m_curToken.type,m_curToken.op,m_curToken.num,m_curToken.id.data()));
2212 
2213  m_tokenStream = p;
2214  return TRUE;
2215  }
bool resize(uint newlen)
Definition: qcstring.h:225
const bool FALSE
Definition: qglobal.h:370
const TemplateParser * m_parser
Definition: template.cpp:2217
QCString templateName() const
Definition: template.cpp:1668
p
Definition: test.py:223
void warn(const char *file, int line, const char *fmt,...)
Definition: message.cpp:183
ExprToken m_curToken
Definition: template.cpp:2218
const char * m_tokenStream
Definition: template.cpp:2220
static QCString * s
Definition: config.cpp:1042
const bool TRUE
Definition: qglobal.h:371
ExprAst* ExpressionParser::parse ( const char *  expr)
inline

Definition at line 1691 of file template.cpp.

1692  {
1693  if (expr==0) return 0;
1694  m_tokenStream = expr;
1695  getNextToken();
1696  return parseExpression();
1697  }
ExprAst * parseExpression()
Definition: template.cpp:1719
const char * m_tokenStream
Definition: template.cpp:2220
ExprAst* ExpressionParser::parseAdditiveExpression ( )
inlineprivate

Definition at line 1813 of file template.cpp.

1814  {
1815  TRACE(("{parseAdditiveExpression(%s)\n",m_tokenStream));
1817  if (lhs)
1818  {
1821  {
1823  getNextToken();
1825  lhs = new ExprAstBinary(op,lhs,rhs);
1826  }
1827  }
1828  TRACE(("}parseAdditiveExpression(%s)\n",m_tokenStream));
1829  return lhs;
1830  }
Class representing a binary operator in the AST.
Definition: template.cpp:1529
Base class for all nodes in the abstract syntax tree of an expression.
Definition: template.cpp:1364
ExprAst * parseMultiplicativeExpression()
Definition: template.cpp:1832
ExprToken m_curToken
Definition: template.cpp:2218
const char * m_tokenStream
Definition: template.cpp:2220
#define TRACE(x)
Definition: template.cpp:43
ExprAst* ExpressionParser::parseAndExpression ( )
inlineprivate

Definition at line 1745 of file template.cpp.

1746  {
1747  TRACE(("{parseAndExpression(%s)\n",m_tokenStream));
1748  ExprAst *lhs = parseNotExpression();
1749  if (lhs)
1750  {
1753  {
1754  getNextToken();
1755  ExprAst *rhs = parseNotExpression();
1756  lhs = new ExprAstBinary(Operator::And,lhs,rhs);
1757  }
1758  }
1759  TRACE(("}parseAndExpression(%s)\n",m_tokenStream));
1760  return lhs;
1761  }
ExprAst * parseNotExpression()
Definition: template.cpp:1763
Class representing a binary operator in the AST.
Definition: template.cpp:1529
Base class for all nodes in the abstract syntax tree of an expression.
Definition: template.cpp:1364
ExprToken m_curToken
Definition: template.cpp:2218
const char * m_tokenStream
Definition: template.cpp:2220
#define TRACE(x)
Definition: template.cpp:43
ExprAst* ExpressionParser::parseCompareExpression ( )
inlineprivate

Definition at line 1787 of file template.cpp.

1788  {
1789  TRACE(("{parseCompareExpression(%s)\n",m_tokenStream));
1791  if (lhs)
1792  {
1795  (op==Operator::Less ||
1796  op==Operator::Greater ||
1797  op==Operator::Equal ||
1798  op==Operator::NotEqual ||
1799  op==Operator::LessEqual ||
1801  )
1802  )
1803  {
1804  getNextToken();
1805  ExprAst *rhs = parseNotExpression();
1806  lhs = new ExprAstBinary(op,lhs,rhs);
1807  }
1808  }
1809  TRACE(("}parseCompareExpression(%s)\n",m_tokenStream));
1810  return lhs;
1811  }
ExprAst * parseNotExpression()
Definition: template.cpp:1763
Class representing a binary operator in the AST.
Definition: template.cpp:1529
Base class for all nodes in the abstract syntax tree of an expression.
Definition: template.cpp:1364
ExprAst * parseAdditiveExpression()
Definition: template.cpp:1813
ExprToken m_curToken
Definition: template.cpp:2218
const char * m_tokenStream
Definition: template.cpp:2220
#define TRACE(x)
Definition: template.cpp:43
ExprAst* ExpressionParser::parseExpression ( )
inlineprivate

Definition at line 1719 of file template.cpp.

1720  {
1721  TRACE(("{parseExpression(%s)\n",m_tokenStream));
1723  TRACE(("}parseExpression(%s)\n",m_tokenStream));
1724  return result;
1725  }
static QCString result
ExprAst * parseOrExpression()
Definition: template.cpp:1727
Base class for all nodes in the abstract syntax tree of an expression.
Definition: template.cpp:1364
const char * m_tokenStream
Definition: template.cpp:2220
#define TRACE(x)
Definition: template.cpp:43
ExprAstFilter* ExpressionParser::parseFilter ( )
inlineprivate

Definition at line 1997 of file template.cpp.

1998  {
1999  TRACE(("{parseFilter(%s)\n",m_curToken.id.data()));
2000  QCString filterName = m_curToken.id;
2001  getNextToken();
2002  ExprAst *argExpr=0;
2005  {
2006  getNextToken();
2007  argExpr = parsePrimaryExpression();
2008  }
2009  ExprAstFilter *filter = new ExprAstFilter(filterName,argExpr);
2010  TRACE(("}parseFilter()\n"));
2011  return filter;
2012  }
Base class for all nodes in the abstract syntax tree of an expression.
Definition: template.cpp:1364
const char * data() const
Definition: qcstring.h:207
Class representing a filter in the AST.
Definition: template.cpp:1437
ExprToken m_curToken
Definition: template.cpp:2218
static unsigned filter(unsigned char *out, const unsigned char *in, unsigned w, unsigned h, const LodePNG_InfoColor *info)
Definition: lodepng.cpp:3576
ExprAst * parsePrimaryExpression()
Definition: template.cpp:1881
#define TRACE(x)
Definition: template.cpp:43
ExprAst* ExpressionParser::parseFilteredVariable ( )
inlineprivate

Definition at line 1978 of file template.cpp.

1979  {
1980  TRACE(("{parseFilteredVariable()\n"));
1982  if (expr)
1983  {
1986  {
1987  getNextToken();
1989  if (!filter) break;
1990  expr = new ExprAstFilterAppl(expr,filter);
1991  }
1992  }
1993  TRACE(("}parseFilteredVariable()\n"));
1994  return expr;
1995  }
ExprAstFilter * parseFilter()
Definition: template.cpp:1997
Class representing a filter applied to an expression in the AST.
Definition: template.cpp:1465
Base class for all nodes in the abstract syntax tree of an expression.
Definition: template.cpp:1364
Class representing a filter in the AST.
Definition: template.cpp:1437
ExprToken m_curToken
Definition: template.cpp:2218
#define TRACE(x)
Definition: template.cpp:43
ExprAst * parseIdentifierOptionalArgs()
Definition: template.cpp:1951
ExprAst* ExpressionParser::parseIdentifier ( )
inlineprivate

Definition at line 1933 of file template.cpp.

1934  {
1935  TRACE(("{parseIdentifier(%s)\n",m_curToken.id.data()));
1936  ExprAst *id = new ExprAstVariable(m_curToken.id);
1937  getNextToken();
1938  TRACE(("}parseIdentifier()\n"));
1939  return id;
1940  }
Base class for all nodes in the abstract syntax tree of an expression.
Definition: template.cpp:1364
const char * data() const
Definition: qcstring.h:207
Class representing a variable in the AST.
Definition: template.cpp:1384
ExprToken m_curToken
Definition: template.cpp:2218
#define TRACE(x)
Definition: template.cpp:43
ExprAst* ExpressionParser::parseIdentifierOptionalArgs ( )
inlineprivate

Definition at line 1951 of file template.cpp.

1952  {
1953  TRACE(("{parseIdentifierOptionalArgs(%s)\n",m_curToken.id.data()));
1954  ExprAst *expr = parseIdentifier();
1955  if (expr)
1956  {
1959  {
1960  getNextToken();
1961  ExprAst *argExpr = parsePrimaryExpression();
1963  args.append(argExpr);
1966  {
1967  getNextToken();
1968  argExpr = parsePrimaryExpression();
1969  args.append(argExpr);
1970  }
1971  expr = new ExprAstFunctionVariable(expr,args);
1972  }
1973  }
1974  TRACE(("}parseIdentifierOptionalArgs()\n"));
1975  return expr;
1976  }
void append(const type *d)
Definition: qlist.h:73
static QCString args
Definition: declinfo.cpp:674
ExprAst * parseIdentifier()
Definition: template.cpp:1933
Base class for all nodes in the abstract syntax tree of an expression.
Definition: template.cpp:1364
const char * data() const
Definition: qcstring.h:207
ExprToken m_curToken
Definition: template.cpp:2218
ExprAst * parsePrimaryExpression()
Definition: template.cpp:1881
#define TRACE(x)
Definition: template.cpp:43
ExprAst* ExpressionParser::parseLiteral ( )
inlineprivate

Definition at line 1942 of file template.cpp.

1943  {
1944  TRACE(("{parseLiteral(%s)\n",m_curToken.id.data()));
1945  ExprAst *expr = new ExprAstLiteral(m_curToken.id);
1946  getNextToken();
1947  TRACE(("}parseLiteral()\n"));
1948  return expr;
1949  }
Class representing a string literal in the AST.
Definition: template.cpp:1482
Base class for all nodes in the abstract syntax tree of an expression.
Definition: template.cpp:1364
const char * data() const
Definition: qcstring.h:207
ExprToken m_curToken
Definition: template.cpp:2218
#define TRACE(x)
Definition: template.cpp:43
ExprAst* ExpressionParser::parseMultiplicativeExpression ( )
inlineprivate

Definition at line 1832 of file template.cpp.

1833  {
1834  TRACE(("{parseMultiplicativeExpression(%s)\n",m_tokenStream));
1835  ExprAst *lhs = parseUnaryExpression();
1836  if (lhs)
1837  {
1840  {
1842  getNextToken();
1843  ExprAst *rhs = parseUnaryExpression();
1844  lhs = new ExprAstBinary(op,lhs,rhs);
1845  }
1846  }
1847  TRACE(("}parseMultiplicativeExpression(%s)\n",m_tokenStream));
1848  return lhs;
1849  }
Class representing a binary operator in the AST.
Definition: template.cpp:1529
Base class for all nodes in the abstract syntax tree of an expression.
Definition: template.cpp:1364
ExprAst * parseUnaryExpression()
Definition: template.cpp:1851
ExprToken m_curToken
Definition: template.cpp:2218
const char * m_tokenStream
Definition: template.cpp:2220
#define TRACE(x)
Definition: template.cpp:43
ExprAst* ExpressionParser::parseNotExpression ( )
inlineprivate

Definition at line 1763 of file template.cpp.

1764  {
1765  TRACE(("{parseNotExpression(%s)\n",m_tokenStream));
1766  ExprAst *result=0;
1769  {
1770  getNextToken();
1771  ExprAst *expr = parseCompareExpression();
1772  if (expr==0)
1773  {
1774  warn(m_parser->templateName(),m_line,"argument missing for not operator");
1775  return 0;
1776  }
1777  result = new ExprAstNegate(expr);
1778  }
1779  else
1780  {
1781  result = parseCompareExpression();
1782  }
1783  TRACE(("}parseNotExpression(%s)\n",m_tokenStream));
1784  return result;
1785  }
static QCString result
ExprAst * parseCompareExpression()
Definition: template.cpp:1787
const TemplateParser * m_parser
Definition: template.cpp:2217
Base class for all nodes in the abstract syntax tree of an expression.
Definition: template.cpp:1364
QCString templateName() const
Definition: template.cpp:1668
Class representing a negation (not) operator in the AST.
Definition: template.cpp:1494
void warn(const char *file, int line, const char *fmt,...)
Definition: message.cpp:183
ExprToken m_curToken
Definition: template.cpp:2218
const char * m_tokenStream
Definition: template.cpp:2220
#define TRACE(x)
Definition: template.cpp:43
ExprAst* ExpressionParser::parseNumber ( )
inlineprivate

Definition at line 1924 of file template.cpp.

1925  {
1926  TRACE(("{parseNumber(%d)\n",m_curToken.num));
1928  getNextToken();
1929  TRACE(("}parseNumber()\n"));
1930  return num;
1931  }
Class representing a number in the AST.
Definition: template.cpp:1372
Base class for all nodes in the abstract syntax tree of an expression.
Definition: template.cpp:1364
ExprToken m_curToken
Definition: template.cpp:2218
#define TRACE(x)
Definition: template.cpp:43
ExprAst* ExpressionParser::parseOrExpression ( )
inlineprivate

Definition at line 1727 of file template.cpp.

1728  {
1729  TRACE(("{parseOrExpression(%s)\n",m_tokenStream));
1730  ExprAst *lhs = parseAndExpression();
1731  if (lhs)
1732  {
1735  {
1736  getNextToken();
1737  ExprAst *rhs = parseAndExpression();
1738  lhs = new ExprAstBinary(Operator::Or,lhs,rhs);
1739  }
1740  }
1741  TRACE(("}parseOrExpression(%s)\n",m_tokenStream));
1742  return lhs;
1743  }
Class representing a binary operator in the AST.
Definition: template.cpp:1529
Base class for all nodes in the abstract syntax tree of an expression.
Definition: template.cpp:1364
ExprAst * parseAndExpression()
Definition: template.cpp:1745
ExprToken m_curToken
Definition: template.cpp:2218
const char * m_tokenStream
Definition: template.cpp:2220
#define TRACE(x)
Definition: template.cpp:43
ExprAst* ExpressionParser::parsePrimaryExpression ( )
inlineprivate

Definition at line 1881 of file template.cpp.

1882  {
1883  TRACE(("{parsePrimary(%s)\n",m_tokenStream));
1884  ExprAst *result=0;
1885  switch (m_curToken.type)
1886  {
1887  case ExprToken::Number:
1888  result = parseNumber();
1889  break;
1890  case ExprToken::Identifier:
1891  result = parseFilteredVariable();
1892  break;
1893  case ExprToken::Literal:
1894  result = parseLiteral();
1895  break;
1896  case ExprToken::Operator:
1898  {
1899  getNextToken(); // skip over opening bracket
1900  result = parseExpression();
1903  {
1904  warn(m_parser->templateName(),m_line,"missing closing parenthesis");
1905  }
1906  else
1907  {
1908  getNextToken(); // skip over closing bracket
1909  }
1910  }
1911  else
1912  {
1913  warn(m_parser->templateName(),m_line,"unexpected operator '%s' in expression",
1915  }
1916  break;
1917  default:
1918  warn(m_parser->templateName(),m_line,"unexpected token in expression");
1919  }
1920  TRACE(("}parsePrimary(%s)\n",m_tokenStream));
1921  return result;
1922  }
static const char * toString(Type op)
Definition: template.cpp:451
static QCString result
ExprAst * parseNumber()
Definition: template.cpp:1924
ExprAst * parseFilteredVariable()
Definition: template.cpp:1978
ExprAst * parseExpression()
Definition: template.cpp:1719
const TemplateParser * m_parser
Definition: template.cpp:2217
Base class for all nodes in the abstract syntax tree of an expression.
Definition: template.cpp:1364
QCString templateName() const
Definition: template.cpp:1668
void warn(const char *file, int line, const char *fmt,...)
Definition: message.cpp:183
ExprAst * parseLiteral()
Definition: template.cpp:1942
ExprToken m_curToken
Definition: template.cpp:2218
const char * m_tokenStream
Definition: template.cpp:2220
#define TRACE(x)
Definition: template.cpp:43
ExprAst* ExpressionParser::parseUnaryExpression ( )
inlineprivate

Definition at line 1851 of file template.cpp.

1852  {
1853  TRACE(("{parseUnaryExpression(%s)\n",m_tokenStream));
1854  ExprAst *result=0;
1856  {
1858  {
1859  getNextToken();
1860  result = parsePrimaryExpression();
1861  }
1862  else if (m_curToken.op==Operator::Minus)
1863  {
1864  getNextToken();
1866  result = new ExprAstUnary(m_curToken.op,rhs);
1867  }
1868  else
1869  {
1870  result = parsePrimaryExpression();
1871  }
1872  }
1873  else
1874  {
1875  result = parsePrimaryExpression();
1876  }
1877  TRACE(("}parseUnaryExpression(%s)\n",m_tokenStream));
1878  return result;
1879  }
static QCString result
Base class for all nodes in the abstract syntax tree of an expression.
Definition: template.cpp:1364
ExprToken m_curToken
Definition: template.cpp:2218
const char * m_tokenStream
Definition: template.cpp:2220
ExprAst * parsePrimaryExpression()
Definition: template.cpp:1881
#define TRACE(x)
Definition: template.cpp:43

Member Data Documentation

ExprToken ExpressionParser::m_curToken
private

Definition at line 2218 of file template.cpp.

int ExpressionParser::m_line
private

Definition at line 2219 of file template.cpp.

const TemplateParser* ExpressionParser::m_parser
private

Definition at line 2217 of file template.cpp.

const char* ExpressionParser::m_tokenStream
private

Definition at line 2220 of file template.cpp.


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