Doxygen
Loading...
Searching...
No Matches
pyscanner.l File Reference
#include <stdint.h>
#include <algorithm>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <ctype.h>
#include <string.h>
#include "pyscanner.h"
#include "entry.h"
#include "message.h"
#include "config.h"
#include "doxygen.h"
#include "util.h"
#include "defargs.h"
#include "language.h"
#include "commentscan.h"
#include "arguments.h"
#include "markdown.h"
#include "fileinfo.h"
#include "debug.h"
#include "stringutil.h"
#include "doxygen_lex.h"
#include "pyscanner.l.h"
+ Include dependency graph for pyscanner.l:

Go to the source code of this file.

Classes

struct  pyscannerYY_state
 
struct  PythonOutlineParser::Private
 

Macros

#define YY_TYPEDEF_YY_SCANNER_T
 
#define DBG_CTX(x)
 
#define YY_NO_INPUT   1
 
#define YY_NO_UNISTD_H   1
 
#define unput_string(yytext, yyleng)
 
#define YY_INPUT(buf, result, max_size)
 

Typedefs

typedef yyguts_t * yyscan_t
 

Functions

static const char * stateToString (int state)
 
static int computeIndent (const char *s)
 
static void initParser (yyscan_t yyscanner)
 
static void initEntry (yyscan_t yyscanner)
 
static void newEntry (yyscan_t yyscanner)
 
static void addEntry (yyscan_t yyscanner)
 
static void docVariable (yyscan_t yyscanner, const char *s)
 
static void newVariable (yyscan_t yyscanner)
 
static void addVariable (yyscan_t yyscanner)
 
static void newFunction (yyscan_t yyscanner)
 
static QCString findPackageScopeFromPath (yyscan_t yyscanner, const QCString &path)
 
static void addFrom (yyscan_t yyscanner, bool all)
 
static void lineCount (yyscan_t yyscanner)
 
static void incLineNr (yyscan_t yyscanner)
 
static void startCommentBlock (yyscan_t yyscanner, bool brief)
 
static void handleCommentBlock (yyscan_t yyscanner, const QCString &doc, bool brief)
 
static void endOfDef (yyscan_t yyscanner, int correction=0)
 
static void addToString (yyscan_t yyscanner, const char *s)
 
static void initTriDoubleQuoteBlock (yyscan_t yyscanner)
 
static void initTriSingleQuoteBlock (yyscan_t yyscanner)
 
static void initSpecialBlock (yyscan_t yyscanner)
 
static void searchFoundDef (yyscan_t yyscanner)
 
static void searchFoundClass (yyscan_t yyscanner)
 
static QCString findPackageScope (yyscan_t yyscanner, const QCString &fileName)
 
static void setProtection (yyscan_t yyscanner)
 
static int yyread (yyscan_t yyscanner, char *buf, int max_size)
 
static const char * getLexerFILE ()
 
int yylex (yyscan_t yyscanner)
 
static void parseCompounds (yyscan_t yyscanner, std::shared_ptr< Entry > rt)
 
static void parseMain (yyscan_t yyscanner, const QCString &fileName, const char *fileBuf, const std::shared_ptr< Entry > &rt)
 
static void parsePrototype (yyscan_t yyscanner, const QCString &text)
 

Macro Definition Documentation

◆ DBG_CTX

#define DBG_CTX ( x)
Value:
do { } while(0)

Definition at line 65 of file pyscanner.l.

◆ unput_string

#define unput_string ( yytext,
yyleng )
Value:
do { for (int i=(int)yyleng-1;i>=0;i--) unput(yytext[i]); } while(0)

Definition at line 70 of file pyscanner.l.

◆ YY_INPUT

#define YY_INPUT ( buf,
result,
max_size )
Value:
result=yyread(yyscanner,buf,max_size);
static int yyread(yyscan_t yyscanner, char *buf, int max_size)
Definition pyscanner.l:1734

Definition at line 160 of file pyscanner.l.

◆ YY_NO_INPUT

#define YY_NO_INPUT   1

Definition at line 67 of file pyscanner.l.

◆ YY_NO_UNISTD_H

#define YY_NO_UNISTD_H   1

Definition at line 68 of file pyscanner.l.

◆ YY_TYPEDEF_YY_SCANNER_T

#define YY_TYPEDEF_YY_SCANNER_T

Definition at line 29 of file pyscanner.l.

Typedef Documentation

◆ yyscan_t

typedef yyguts_t* yyscan_t

Definition at line 31 of file pyscanner.l.

Function Documentation

◆ addEntry()

static void addEntry ( yyscan_t yyscanner)
static

Definition at line 1808 of file pyscanner.l.

1809{
1810 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1811
1812 auto doc = yyextra->current->doc;
1813 auto docLine = yyextra->current->docLine;
1814 auto docFile = yyextra->current->docFile;
1815 auto brief = yyextra->current->brief;
1816 auto briefLine = yyextra->current->briefLine;
1817 auto briefFile = yyextra->current->briefFile;
1818
1819 yyextra->previous = yyextra->current;
1820 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
1821 initEntry(yyscanner);
static void initEntry(yyscan_t yyscanner)
Definition pyscanner.l:1755
1822
1823 yyextra->current->doc = doc;
1824 yyextra->current->docLine = docLine;
1825 yyextra->current->docFile = docFile;
1826 yyextra->current->brief = brief;
1827 yyextra->current->briefLine = briefLine;
1828 yyextra->current->briefFile = briefFile;
1829}

References initEntry().

Referenced by addVariable().

◆ addFrom()

static void addFrom ( yyscan_t yyscanner,
bool all )
static

Definition at line 1946 of file pyscanner.l.

1947{
1948 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1949 QCString item=all ? yyextra->packageName : yyextra->packageName+"."+yytext;
1950 yyextra->current->name=removeRedundantWhiteSpace(substitute(item,".","::"));
1951 yyextra->current->fileName = yyextra->fileName;
1952 //printf("Adding using declaration: found:%s:%d name=%s\n",qPrint(yyextra->fileName),yyextra->yyLineNr,qPrint(yyextra->current->name));
1953 yyextra->current->section=all ? EntryType::makeUsingDir() : EntryType::makeUsingDecl();
1954 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
1955 initEntry(yyscanner);
Wrapper class for the Entry type.
Definition types.h:631
This is an alternative implementation of QCString.
Definition qcstring.h:101
static void initEntry(yyscan_t yyscanner)
QCString substitute(const QCString &s, const QCString &src, const QCString &dst)
substitute all occurrences of src in s by dst
Definition qcstring.cpp:477
QCString removeRedundantWhiteSpace(const QCString &s)
Definition util.cpp:578
1956}

References initEntry(), removeRedundantWhiteSpace(), and substitute().

◆ addToString()

static void addToString ( yyscan_t yyscanner,
const char * s )
inlinestatic

Definition at line 2059 of file pyscanner.l.

2060{
2061 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2062 if (yyextra->copyString) (*yyextra->copyString) << s;
2063}

◆ addVariable()

static void addVariable ( yyscan_t yyscanner)
static

Definition at line 1871 of file pyscanner.l.

1872{
1873 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1874 setProtection(yyscanner);
1875 if (yyextra->current_root->section.isCompound()) // mark as class variable
1876 {
1877 yyextra->current->isStatic = TRUE;
1878 }
1879 addEntry(yyscanner);
static void setProtection(yyscan_t yyscanner)
Definition pyscanner.l:1831
static void addEntry(yyscan_t yyscanner)
Definition pyscanner.l:1808
#define TRUE
Definition qcstring.h:37
1880}

References addEntry(), setProtection(), and TRUE.

◆ computeIndent()

static int computeIndent ( const char * s)
inlinestatic

Definition at line 1897 of file pyscanner.l.

1898{
1899 int col=0;
1900 int tabSize=Config_getInt(TAB_SIZE);
1901 const char *p=s;
1902 char c;
1903 while ((c=*p++))
1904 {
1905 if (c==' ') col++;
1906 else if (c=='\t') col+=tabSize-(col%tabSize);
1907 else break;
1908 }
1909 return col;
#define Config_getInt(name)
Definition config.h:34
1910}

References Config_getInt.

◆ docVariable()

static void docVariable ( yyscan_t yyscanner,
const char * s )
static

Definition at line 1847 of file pyscanner.l.

1848{
1849 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1850 yyextra->current->name = name;
1851 yyextra->current->section=EntryType::makeVariable();
1852 yyextra->current->fileName = yyextra->fileName;
1853 yyextra->current->startLine = yyextra->yyLineNr;
1854 yyextra->current->bodyLine = yyextra->yyLineNr;
1855 yyextra->current->type.clear();
1856 setProtection(yyscanner);
1857 yyextra->checkDupEntry = true;
1858}

References setProtection().

◆ endOfDef()

static void endOfDef ( yyscan_t yyscanner,
int correction = 0 )
static

Definition at line 2046 of file pyscanner.l.

2047{
2048 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2049 //printf("endOfDef at=%d\n",yyextra->yyLineNr);
2050 if (yyextra->bodyEntry)
2051 {
2052 yyextra->bodyEntry->endBodyLine = yyextra->yyLineNr-correction;
2053 yyextra->bodyEntry = 0;
2054 }
2055 newEntry(yyscanner);
2056 //yyextra->insideConstructor = FALSE;
static void newEntry(yyscan_t yyscanner)
Definition pyscanner.l:1768
2057}

References newEntry().

◆ findPackageScope()

static QCString findPackageScope ( yyscan_t yyscanner,
const QCString & fileName )
static

Definition at line 1939 of file pyscanner.l.

1940{
1941 if (fileName.isEmpty()) return fileName;
1942 FileInfo fi(fileName.str());
1943 return findPackageScopeFromPath(yyscanner,fi.dirPath(true).c_str());
Minimal replacement for QFileInfo.
Definition fileinfo.h:23
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:150
const std::string & str() const
Definition qcstring.h:526
static QCString findPackageScopeFromPath(yyscan_t yyscanner, const QCString &path)
Definition pyscanner.l:1912
1944}

References FileInfo::dirPath(), findPackageScopeFromPath(), QCString::isEmpty(), and QCString::str().

Referenced by parseMain().

◆ findPackageScopeFromPath()

static QCString findPackageScopeFromPath ( yyscan_t yyscanner,
const QCString & path )
static

Definition at line 1912 of file pyscanner.l.

1913{
1914 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1915 auto it = yyextra->packageNameCache.find(path.str());
1916 if (it!=yyextra->packageNameCache.end())
1917 {
1918 return QCString(it->second);
1919 }
1920 FileInfo pf(path.str()+"/__init__.py"); // found package initialization file
1921 if (pf.exists())
1922 {
1923 int i=path.findRev('/');
1924 if (i!=-1)
1925 {
1926 QCString scope = findPackageScopeFromPath(yyscanner,path.left(i));
1927 if (!scope.isEmpty())
1928 {
1929 scope+="::";
1930 }
1931 scope+=path.mid(i+1);
1932 yyextra->packageNameCache.emplace(path.str(),scope.str());
1933 return scope;
1934 }
1935 }
1936 return "";
QCString mid(size_t index, size_t len=static_cast< size_t >(-1)) const
Definition qcstring.h:226
int findRev(char c, int index=-1, bool cs=TRUE) const
Definition qcstring.cpp:91
QCString left(size_t len) const
Definition qcstring.h:214
1937}

References FileInfo::exists(), QCString::find(), findPackageScopeFromPath(), QCString::findRev(), QCString::isEmpty(), QCString::left(), QCString::mid(), and QCString::str().

Referenced by findPackageScope(), and findPackageScopeFromPath().

◆ getLexerFILE()

static const char * getLexerFILE ( )
inlinestatic

Definition at line 163 of file pyscanner.l.

163{return __FILE__;}

◆ handleCommentBlock()

static void handleCommentBlock ( yyscan_t yyscanner,
const QCString & doc,
bool brief )
static

Definition at line 1992 of file pyscanner.l.

1993{
1994 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1995 //printf("handleCommentBlock(doc=[%s] brief=%d yyextra->docBlockInBody=%d yyextra->docBlockJavaStyle=%d\n",
1996 // qPrint(doc),brief,yyextra->docBlockInBody,yyextra->docBlockJavaStyle);
1997
1998 // TODO: Fix me
1999 yyextra->docBlockInBody=FALSE;
#define FALSE
Definition qcstring.h:34
2000
2001 if (!yyextra->current->doc.isEmpty())
2002 {
2003 yyextra->current->doc=yyextra->current->doc.stripWhiteSpace()+"\n\n";
2004 }
2005 if (yyextra->docBlockInBody && yyextra->previous && !yyextra->previous->doc.isEmpty())
2006 {
2007 yyextra->previous->doc=yyextra->previous->doc.stripWhiteSpace()+"\n\n";
2008 }
2009
2010 int position = 0;
2011 bool needsEntry = false;
2012 int lineNr = brief ? yyextra->current->briefLine : yyextra->current->docLine;
2013 Markdown markdown(yyextra->fileName,lineNr);
2014 GuardedSectionStack guards;
2015 QCString strippedDoc = stripIndentation(doc);
2016 QCString processedDoc = Config_getBool(MARKDOWN_SUPPORT) ? markdown.process(strippedDoc,lineNr) : strippedDoc;
2017 while (yyextra->commentScanner.parseCommentBlock(
2018 yyextra->thisParser,
2019 (yyextra->docBlockInBody && yyextra->previous) ? yyextra->previous.get() : yyextra->current.get(),
2020 processedDoc, // text
2021 yyextra->fileName, // file
2022 lineNr,
2023 yyextra->docBlockInBody ? FALSE : brief,
2024 yyextra->docBlockJavaStyle, // javadoc style // or FALSE,
2025 yyextra->docBlockInBody,
2026 yyextra->protection,
2027 position,
2028 needsEntry,
2029 Config_getBool(MARKDOWN_SUPPORT),
2030 &guards
2031 )
2032 ) // need to start a new entry
2033 {
2034 if (needsEntry)
2035 {
2036 newEntry(yyscanner);
2037 }
2038 }
2039 if (needsEntry)
2040 {
2041 newEntry(yyscanner);
2042 }
Helper class to process markdown formatted text.
Definition markdown.h:32
std::stack< GuardedSection > GuardedSectionStack
Definition commentscan.h:48
#define Config_getBool(name)
Definition config.h:33
QCString stripIndentation(const QCString &s)
Definition util.cpp:6281
2043
2044}

References Config_getBool, FALSE, newEntry(), Markdown::process(), and stripIndentation().

◆ incLineNr()

static void incLineNr ( yyscan_t yyscanner)
static

Definition at line 1969 of file pyscanner.l.

1970{
1971 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1972 DBG_CTX((stderr,"yyextra->yyLineNr=%d\n",yyextra->yyLineNr));
1973 yyextra->yyLineNr++;
#define DBG_CTX(x)
Definition pyscanner.l:65
1974}

References DBG_CTX.

◆ initEntry()

static void initEntry ( yyscan_t yyscanner)
static

Definition at line 1755 of file pyscanner.l.

1756{
1757 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1758 //yyextra->current->python = TRUE;
1759 yyextra->current->protection = yyextra->protection ;
1760 yyextra->current->mtype = yyextra->mtype;
1761 yyextra->current->virt = yyextra->virt;
1762 yyextra->current->isStatic = yyextra->isStatic;
1763 yyextra->current->lang = SrcLangExt::Python;
1764 yyextra->commentScanner.initGroupInfo(yyextra->current.get());
1765 yyextra->isStatic = FALSE;
@ Python
Definition types.h:52
1766}

References FALSE, and Python.

◆ initParser()

static void initParser ( yyscan_t yyscanner)
static

Definition at line 1744 of file pyscanner.l.

1745{
1746 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1747 yyextra->protection = Protection::Public;
1748 yyextra->mtype = MethodTypes::Method;
1749 yyextra->isStatic = FALSE;
1750 yyextra->virt = Specifier::Normal;
1751 yyextra->previous = 0;
1752 yyextra->packageCommentAllowed = TRUE;
@ Public
Definition types.h:26
@ Normal
Definition types.h:29
1753}

References FALSE, Method, Normal, Public, and TRUE.

◆ initSpecialBlock()

static void initSpecialBlock ( yyscan_t yyscanner)
static

Definition at line 2099 of file pyscanner.l.

2100{
2101 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2102 yyextra->docBlockContext = YY_START;
2103 yyextra->docBlockInBody = FALSE;
2104 yyextra->docBlockJavaStyle = TRUE;
2105 yyextra->docBrief = TRUE;
2106 yyextra->docBlock.clear();
2107 yyextra->commentIndent = yyextra->curIndent;
2108 startCommentBlock(yyscanner,FALSE);
static void startCommentBlock(yyscan_t yyscanner, bool brief)
Definition pyscanner.l:1977
2109}

References FALSE, startCommentBlock(), and TRUE.

◆ initTriDoubleQuoteBlock()

static void initTriDoubleQuoteBlock ( yyscan_t yyscanner)
static

Definition at line 2065 of file pyscanner.l.

2066{
2067 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2068 yyextra->docBlockContext = YY_START;
2069 yyextra->docBlockInBody = FALSE;
2070 yyextra->docBlockJavaStyle = TRUE;
2071 yyextra->docBlockSpecial = yytext[strlen(yytext) - 1]=='!' || !Config_getBool(PYTHON_DOCSTRING);
2072 yyextra->docBlock.clear();
2073 yyextra->commentIndent = yyextra->curIndent;
2074 yyextra->doubleQuote = TRUE;
2075 if (yyextra->docBlockSpecial)
2076 {
2077 yyextra->docBlock.fill(' ',yyextra->indent);
2078 }
2079 startCommentBlock(yyscanner,FALSE);
2080}

References Config_getBool, FALSE, startCommentBlock(), and TRUE.

◆ initTriSingleQuoteBlock()

static void initTriSingleQuoteBlock ( yyscan_t yyscanner)
static

Definition at line 2082 of file pyscanner.l.

2083{
2084 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2085 yyextra->docBlockContext = YY_START;
2086 yyextra->docBlockInBody = FALSE;
2087 yyextra->docBlockJavaStyle = TRUE;
2088 yyextra->docBlockSpecial = yytext[strlen(yytext) - 1]=='!' || !Config_getBool(PYTHON_DOCSTRING);
2089 yyextra->docBlock.clear();
2090 yyextra->commentIndent = yyextra->curIndent;
2091 yyextra->doubleQuote = FALSE;
2092 if (yyextra->docBlockSpecial)
2093 {
2094 yyextra->docBlock.fill(' ',yyextra->indent);
2095 }
2096 startCommentBlock(yyscanner,FALSE);
2097}

References Config_getBool, FALSE, startCommentBlock(), and TRUE.

◆ lineCount()

static void lineCount ( yyscan_t yyscanner)
static

Definition at line 1959 of file pyscanner.l.

1960{
1961 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1962 DBG_CTX((stderr,"yyextra->yyLineNr=%d\n",yyextra->yyLineNr));
1963 for (const char *p = yytext; *p; ++p)
1964 {
1965 yyextra->yyLineNr += (*p == '\n') ;
1966 }
1967}

References DBG_CTX.

◆ newEntry()

static void newEntry ( yyscan_t yyscanner)
static

Definition at line 1768 of file pyscanner.l.

1769{
1770 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1771 bool found = false;
1772 if (yyextra->checkDupEntry)
1773 {
1774 for (auto &v : yyextra->current_root->children())
1775 {
1776 //printf("candidate %s section=%s!\n",qPrint(v->name),v->section.to_string().c_str());
1777 if (v->name==yyextra->current->name && v->section==yyextra->current->section) // name is already added, don't add it again
1778 {
1779 if (v->doc.isEmpty() && !yyextra->current->doc.isEmpty())
1780 {
1781 v->doc = yyextra->current->doc;
1782 v->docLine = yyextra->current->docLine;
1783 v->docFile = yyextra->current->docFile;
1784 }
1785 if (v->brief.isEmpty() && !yyextra->current->brief.isEmpty())
1786 {
1787 v->brief = yyextra->current->brief;
1788 v->briefLine = yyextra->current->briefLine;
1789 v->briefFile = yyextra->current->briefFile;
1790 }
1791 if (v->type.isEmpty() && !yyextra->current->type.isEmpty())
1792 {
1793 v->type = yyextra->current->type;
1794 }
1795 found=true;
1796 }
1797 }
1798 yyextra->checkDupEntry=false;
1799 }
1800 if (!found)
1801 {
1802 yyextra->previous = yyextra->current;
1803 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
1804 }
1805 initEntry(yyscanner);
bool found
Definition util.cpp:984
1806}

References found, and initEntry().

Referenced by endOfDef(), handleCommentBlock(), handleCommentBlock(), handleParametersCommentBlocks(), and newVariable().

◆ newFunction()

static void newFunction ( yyscan_t yyscanner)
static

Definition at line 1882 of file pyscanner.l.

1883{
1884 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1885 if (yyextra->current->name.startsWith("__") && yyextra->current->name.endsWith("__"))
1886 {
1887 // special method name, see
1888 // http://docs.python.org/ref/specialnames.html
1889 yyextra->current->protection=Protection::Public;
1890 }
1891 else
1892 {
1893 setProtection(yyscanner);
1894 }
1895}

References Public, and setProtection().

◆ newVariable()

static void newVariable ( yyscan_t yyscanner)
static

Definition at line 1860 of file pyscanner.l.

1861{
1862 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1863 setProtection(yyscanner);
1864 if (yyextra->current_root->section.isCompound()) // mark as class variable
1865 {
1866 yyextra->current->isStatic = TRUE;
1867 }
1868 newEntry(yyscanner);
1869}

References newEntry(), setProtection(), and TRUE.

◆ parseCompounds()

static void parseCompounds ( yyscan_t yyscanner,
std::shared_ptr< Entry > rt )
static

Definition at line 2145 of file pyscanner.l.

2146{
2147 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2148 //printf("parseCompounds(%s)\n",qPrint(rt->name));
2149 for (size_t i=0; i<rt->children().size(); ++i)
2150 {
2151 std::shared_ptr<Entry> ce = rt->children()[i];
2152 if (!ce->program.empty())
2153 {
2154 //fprintf(stderr,"parseCompounds: -- %s (line %d) ---------\n%s\n---------------\n",
2155 // qPrint(ce->name), ce->bodyLine, qPrint(ce->program));
2156 // init scanner state
2157 yyextra->programStr = ce->program.str();
2158 yyextra->inputString = yyextra->programStr.data();
2159 yyextra->inputPosition = 0;
2160 pyscannerYYrestart( nullptr, yyscanner );
2161 if (ce->section.isCompound())
2162 {
2163 yyextra->specialBlock = false;
2164 yyextra->current_root = ce;
2165 BEGIN( Search );
2166 }
2167 else if (ce->parent())
2168 {
2169 yyextra->current_root = rt;
2170 //printf("Searching for member variables in %s parent=%s\n",
2171 // qPrint(ce->name),qPrint(ce->parent->name));
2172 BEGIN( SearchMemVars );
2173 }
2174 yyextra->fileName = ce->fileName;
2175 yyextra->yyLineNr = ce->bodyLine ;
2176 yyextra->current = std::make_shared<Entry>();
2177 initEntry(yyscanner);
2178
2179 QCString name = ce->name;
2180 yyextra->commentScanner.enterCompound(yyextra->fileName,yyextra->yyLineNr,name);
2181
2182 pyscannerYYlex(yyscanner) ;
2183 yyextra->lexInit=TRUE;
2184
2185 yyextra->programStr.clear();
2186 ce->program.str(std::string());
2187
2188 yyextra->commentScanner.leaveCompound(yyextra->fileName,yyextra->yyLineNr,name);
2189
2190 }
2191 parseCompounds(yyscanner,ce);
2192 }
static void parseCompounds(yyscan_t yyscanner, std::shared_ptr< Entry > rt)
Definition pyscanner.l:2145
2193}

References initEntry(), parseCompounds(), Search, and TRUE.

Referenced by parseCompounds(), parseCompounds(), parseMain(), and parseMain().

◆ parseMain()

static void parseMain ( yyscan_t yyscanner,
const QCString & fileName,
const char * fileBuf,
const std::shared_ptr< Entry > & rt )
static

Definition at line 2198 of file pyscanner.l.

2199{
2200 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2201 initParser(yyscanner);
static void initParser(yyscan_t yyscanner)
Definition pyscanner.l:1744
2202
2203 if (fileBuf==nullptr || fileBuf[0]=='\0') return;
2204
2205 yyextra->inputString = fileBuf;
2206 yyextra->inputPosition = 0;
2207
2208 yyextra->protection = Protection::Public;
2209 yyextra->mtype = MethodTypes::Method;
2210 yyextra->isStatic = false;
2211 yyextra->virt = Specifier::Normal;
2212 yyextra->current_root = rt;
2213 yyextra->specialBlock = false;
2214
2215 yyextra->yyLineNr= 1 ;
2216 yyextra->fileName = fileName;
2217 //setContext();
2218 msg("Parsing file %s...\n",qPrint(yyextra->fileName));
void msg(const char *fmt,...)
Definition message.cpp:98
const char * qPrint(const char *s)
Definition qcstring.h:661
2219
2220 FileInfo fi(fileName.str());
2221 yyextra->moduleScope = findPackageScope(yyscanner,fileName);
2222 QCString baseName=fi.baseName();
2223 if (baseName!="__init__") // package initializer file is not a package itself
2224 {
2225 if (!yyextra->moduleScope.isEmpty())
2226 {
2227 yyextra->moduleScope+="::";
2228 }
2229 yyextra->moduleScope+=baseName;
2230 }
static QCString findPackageScope(yyscan_t yyscanner, const QCString &fileName)
Definition pyscanner.l:1939
2231
2232 // add namespaces for each scope
2233 QCString scope = yyextra->moduleScope;
2234 int startPos = 0;
2235 int pos = 0;
2236 do
2237 {
2238 pos = scope.find("::",startPos);
2239 startPos=pos+2;
2240 if (pos==-1) pos=(int)scope.length();
2241 yyextra->current = std::make_shared<Entry>();
2242 initEntry(yyscanner);
2243 yyextra->current->name = scope.left(pos);
2244 yyextra->current->section = EntryType::makeNamespace();
2245 yyextra->current->type = "namespace";
2246 yyextra->current->fileName = yyextra->fileName;
2247 yyextra->current->startLine = yyextra->yyLineNr;
2248 yyextra->current->bodyLine = yyextra->yyLineNr;
2249 yyextra->current_root = yyextra->current;
2250 rt->moveToSubEntryAndRefresh(yyextra->current);
2251 } while (pos<(int)scope.length());
int find(char c, int index=0, bool cs=TRUE) const
Definition qcstring.cpp:43
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition qcstring.h:153
2252
2253 initParser(yyscanner);
2254
2255 yyextra->commentScanner.enterFile(yyextra->fileName,yyextra->yyLineNr);
2256
2257 yyextra->current->reset();
2258 initEntry(yyscanner);
2259 pyscannerYYrestart(nullptr,yyscanner);
2260 BEGIN( Search );
2261 pyscannerYYlex(yyscanner);
2262 yyextra->lexInit=TRUE;
2263
2264 yyextra->commentScanner.leaveFile(yyextra->fileName,yyextra->yyLineNr);
2265
2266 yyextra->programStr.clear();
2267 yyextra->current_root->program.str(std::string());
2268
2269 parseCompounds(yyscanner, yyextra->current_root);
2270}

References FileInfo::baseName(), QCString::find(), findPackageScope(), initEntry(), initParser(), QCString::left(), QCString::length(), Method, msg(), Normal, parseCompounds(), Public, qPrint(), Search, QCString::str(), and TRUE.

◆ parsePrototype()

static void parsePrototype ( yyscan_t yyscanner,
const QCString & text )
static

Definition at line 2274 of file pyscanner.l.

2275{
2276 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2277 //printf("**** parsePrototype(%s) begin\n",qPrint(text));
2278 if (text.isEmpty())
2279 {
2280 warn(yyextra->fileName,yyextra->yyLineNr,"Empty prototype found!");
2281 return;
2282 }
#define warn(file, line, fmt,...)
Definition message.h:59
2283
2284 yyextra->specialBlock = FALSE;
2285 yyextra->packageCommentAllowed = FALSE;
2286
2287 // save scanner state
2288 YY_BUFFER_STATE orgState = YY_CURRENT_BUFFER;
2289 yy_switch_to_buffer(yy_create_buffer(nullptr, YY_BUF_SIZE, yyscanner), yyscanner);
2290 const char *orgInputString = yyextra->inputString;
2291 int orgInputPosition = yyextra->inputPosition;
#define YY_BUF_SIZE
Definition commentcnv.l:19
2292
2293 // set new string
2294 yyextra->inputString = text.data();
2295 yyextra->inputPosition = 0;
2296 pyscannerYYrestart( nullptr, yyscanner );
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
Definition qcstring.h:159
2297
2298 BEGIN( FunctionDec );
2299
2300 pyscannerYYlex(yyscanner);
2301 yyextra->lexInit=TRUE;
2302
2303 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
2304 if (yyextra->current->section.isMemberDoc() && yyextra->current->args.isEmpty())
2305 {
2306 yyextra->current->section = EntryType::makeVariableDoc();
2307 }
2308
2309 // restore original scanner state
2310
2311 yy_delete_buffer(YY_CURRENT_BUFFER, yyscanner);
2312 yy_switch_to_buffer(orgState, yyscanner);
2313
2314 yyextra->inputString = orgInputString;
2315 yyextra->inputPosition = orgInputPosition;
2316
2317 //printf("**** parsePrototype end\n");
2318}

References QCString::data(), FALSE, QCString::isEmpty(), TRUE, warn, and YY_BUF_SIZE.

◆ searchFoundClass()

static void searchFoundClass ( yyscan_t yyscanner)
static

Definition at line 2131 of file pyscanner.l.

2132{
2133 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2134 yyextra->current->section = EntryType::makeClass();
2135 yyextra->current->argList.clear();
2136 yyextra->current->type += "class" ;
2137 yyextra->current->fileName = yyextra->fileName;
2138 yyextra->current->startLine = yyextra->yyLineNr;
2139 yyextra->current->bodyLine = yyextra->yyLineNr;
2140 yyextra->packageCommentAllowed = FALSE;
2141}

References FALSE.

◆ searchFoundDef()

static void searchFoundDef ( yyscan_t yyscanner)
static

Definition at line 2111 of file pyscanner.l.

2112{
2113 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2114 yyextra->current->fileName = yyextra->fileName;
2115 yyextra->current->startLine = yyextra->yyLineNr;
2116 yyextra->current->bodyLine = yyextra->yyLineNr;
2117 yyextra->current->section = EntryType::makeFunction();
2118 yyextra->current->lang = SrcLangExt::Python;
2119 yyextra->current->virt = Specifier::Normal;
2120 yyextra->current->isStatic = yyextra->isStatic;
2121 yyextra->current->mtype = yyextra->mtype = MethodTypes::Method;
2122 yyextra->current->type.clear();
2123 yyextra->current->name.clear();
2124 yyextra->current->args.clear();
2125 yyextra->current->argList.clear();
2126 yyextra->packageCommentAllowed = FALSE;
2127 yyextra->isStatic=FALSE;
2128 //printf("searchFoundDef at=%d\n",yyextra->yyLineNr);
2129}

References FALSE, Method, Normal, and Python.

◆ setProtection()

static void setProtection ( yyscan_t yyscanner)
static

Definition at line 1831 of file pyscanner.l.

1832{
1833 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1834 if (!yyextra->current->name.isEmpty() && yyextra->current->name.at(0)=='_')
1835 {
1836 if (yyextra->current->name.at(1)=='_') // mark as private
1837 {
1838 yyextra->current->protection=Protection::Private;
1839 }
1840 else // mark as protected
1841 {
1842 yyextra->current->protection=Protection::Protected;
1843 }
1844 }
@ Private
Definition types.h:26
@ Protected
Definition types.h:26
1845}

References Private, and Protected.

Referenced by addVariable(), docVariable(), newFunction(), and newVariable().

◆ startCommentBlock()

static void startCommentBlock ( yyscan_t yyscanner,
bool brief )
static

Definition at line 1977 of file pyscanner.l.

1978{
1979 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1980 if (brief)
1981 {
1982 yyextra->current->briefFile = yyextra->fileName;
1983 yyextra->current->briefLine = yyextra->yyLineNr;
1984 }
1985 else
1986 {
1987 yyextra->current->docFile = yyextra->fileName;
1988 yyextra->current->docLine = yyextra->yyLineNr;
1989 }
1990}

◆ stateToString()

static const char * stateToString ( int state)
static

◆ yylex()

int yylex ( yyscan_t yyscanner)

Definition at line 272 of file pyscanner.l.

276 {
277
278 ^{B}"def"{BB} { // start of a function/method definition with indent
279 DBG_CTX((stderr,"Found def at %d\n",yyextra->yyLineNr));
280 yyextra->indent=computeIndent(yytext);
281 searchFoundDef(yyscanner);
282 BEGIN( FunctionDec );
283 }
284 ^{B}"async"{BB}"def"{BB} { // start of an async function/method definition with indent
285 DBG_CTX((stderr,"Found async def at %d\n",yyextra->yyLineNr));
286 yyextra->indent=computeIndent(yytext);
287 searchFoundDef(yyscanner);
288 BEGIN( FunctionDec );
289 }
290 "def"{BB} { // start of a function/method definition
291 searchFoundDef(yyscanner);
292 BEGIN( FunctionDec );
293 }
294 "async"{BB}"def"{BB} { // start of a function/method definition
295 searchFoundDef(yyscanner);
296 BEGIN( FunctionDec );
297 }
static int computeIndent(const char *s)
Definition pyscanner.l:1897
static void searchFoundDef(yyscan_t yyscanner)
Definition pyscanner.l:2111
298
299 ^{B}"class"{BB} { // start of a class definition with indent
300 DBG_CTX((stderr,"Found class at %d\n",yyextra->yyLineNr));
301 yyextra->indent=computeIndent(yytext);
302 searchFoundClass(yyscanner);
303 BEGIN( ClassDec ) ;
304 }
305 "class"{BB} { // start of a class definition
306 searchFoundClass(yyscanner);
307 BEGIN( ClassDec ) ;
308 }
309 ^{B}"from"{BB} |
310 "from"{BB} { // start of an from import
311 yyextra->packageCommentAllowed = FALSE;
312 BEGIN( FromMod );
313 }
static void searchFoundClass(yyscan_t yyscanner)
Definition pyscanner.l:2131
314
315 ^{B}"import"{BB} |
316 "import"{BB} { // start of an import statement
317 yyextra->packageCommentAllowed = FALSE;
318 BEGIN( Import );
319 }
320 ^{B}{IDENTIFIER}/{B}"="{B}"property" { // property
321 yyextra->current->section = EntryType::makeVariable();
322 yyextra->current->mtype = MethodTypes::Property;
323 yyextra->current->name = QCString(yytext).stripWhiteSpace();
324 yyextra->current->fileName = yyextra->fileName;
325 yyextra->current->startLine = yyextra->yyLineNr;
326 yyextra->current->bodyLine = yyextra->yyLineNr;
327 yyextra->packageCommentAllowed = FALSE;
328 BEGIN(VariableDec);
329 }
330 ^{B}{IDENTIFIER}/{B}"="[^=] { // variable
331 if (yyextra->searchCount>0) REJECT;
332 yyextra->indent=computeIndent(yytext);
333 yyextra->current->section = EntryType::makeVariable();
334 yyextra->current->name = QCString(yytext).stripWhiteSpace();
335 yyextra->current->fileName = yyextra->fileName;
336 yyextra->current->startLine = yyextra->yyLineNr;
337 yyextra->current->bodyLine = yyextra->yyLineNr;
338 yyextra->packageCommentAllowed = FALSE;
339 BEGIN(VariableDec);
340 }
341 ^{B}{IDENTIFIER}/{B}":" { // variable
342 if (yyextra->searchCount>0) REJECT;
343 QCString id = QCString(yytext).stripWhiteSpace();
344 if (id =="try" || id == "else" || id == "except" || id == "finally") REJECT;
345 yyextra->indent=computeIndent(yytext);
346 yyextra->current->section = EntryType::makeVariable();
347 yyextra->current->name = id;
348 yyextra->current->fileName = yyextra->fileName;
349 yyextra->current->startLine = yyextra->yyLineNr;
350 yyextra->current->bodyLine = yyextra->yyLineNr;
351 yyextra->packageCommentAllowed = FALSE;
352 BEGIN(VariableDec);
353 }
354 {B}{IDENTIFIER}/({B},{B}{IDENTIFIER})*{B}")"*{B}"="[^=] { // list of variables, we cannot place the default value
355 // so we will skip it later on in a general rule
356 // Also note ")" this is to catch also (a,b). the "("
357 // is caught in the rule: [(], the ")" will be handled in [)]
358 if (yyextra->searchCount>1) REJECT;
359 yyextra->indent=computeIndent(yytext);
360 yyextra->current->section = EntryType::makeVariable();
361 yyextra->current->name = QCString(yytext).stripWhiteSpace();
362 yyextra->current->fileName = yyextra->fileName;
363 yyextra->current->startLine = yyextra->yyLineNr;
364 yyextra->current->bodyLine = yyextra->yyLineNr;
365 yyextra->packageCommentAllowed = FALSE;
366 addVariable(yyscanner);
367 }
368 "'" { // start of a single quoted string
369 yyextra->stringContext=YY_START;
370 yyextra->copyString=nullptr;
371 yyextra->packageCommentAllowed = FALSE;
372 BEGIN( SingleQuoteString );
373 }
374 "\"" { // start of a double quoted string
375 yyextra->stringContext=YY_START;
376 yyextra->copyString=nullptr;
377 yyextra->packageCommentAllowed = FALSE;
378 BEGIN( DoubleQuoteString );
379 }
380 "@staticmethod" {
381 yyextra->isStatic=TRUE;
382 }
383 "@"{SCOPE}"(" { // decorator
384 lineCount(yyscanner);
385 yyextra->decoratorRound = 1;
386 yyextra->copyString=nullptr;
387 BEGIN( Decorator );
388 }
389 "@"{SCOPE} { // decorator
390 lineCount(yyscanner);
391 }
392 {SCRIPTCOMMENT} { // Unix type script comment
393 if (yyextra->yyLineNr != 1) REJECT;
394 }
395 {POUNDCOMMENT} { // normal comment
396 // issue 9672
397 //yyextra->packageCommentAllowed = FALSE;
398 }
399 {IDENTIFIER} { // some other identifier
400 yyextra->packageCommentAllowed = FALSE;
401 }
402 ^{BB} {
403 yyextra->curIndent=computeIndent(yytext);
404 }
QCString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition qcstring.h:245
#define lineCount(s, len)
static void addVariable(yyscan_t yyscanner)
Definition pyscanner.l:1871
@ Property
Definition types.h:32
405
406 {NEWLINE}+ { // new line
407 lineCount(yyscanner);
408 }
409
410 {TRIDOUBLEQUOTE} { // start of a comment block
411 initTriDoubleQuoteBlock(yyscanner);
412 BEGIN(TripleComment);
413 }
static void initTriDoubleQuoteBlock(yyscan_t yyscanner)
Definition pyscanner.l:2065
414
415 {TRISINGLEQUOTE} { // start of a comment block
416 initTriSingleQuoteBlock(yyscanner);
417 BEGIN(TripleComment);
418 }
static void initTriSingleQuoteBlock(yyscan_t yyscanner)
Definition pyscanner.l:2082
419
420 {B}{STARTDOCSYMS}/[^#] { // start of a special comment
421 yyextra->curIndent=computeIndent(yytext);
422 yyextra->packageCommentAllowed = FALSE;
423 initSpecialBlock(yyscanner);
424 BEGIN(SpecialComment);
425 }
426 [(] { // we have to do something with (
427 yyextra->searchCount++;
428 }
429 [)] { // we have to do something with )
430 if (yyextra->searchCount>0)
431 {
432 yyextra->searchCount--;
433 }
434 }
435 "=" {
436 yyextra->current->doc.clear();
437 yyextra->current->brief.clear();
438 }
439 {IDENTIFIER} {
440 }
441 [^\n] { // any other character...
442 // This is the major default
443 // that should catch everything
444 // else in Body.
445 }
static void initSpecialBlock(yyscan_t yyscanner)
Definition pyscanner.l:2099
446}
447
448<FromMod>{
449 "." { // python3 style imports
450 }
451 {IDENTIFIER}({B}"."{B}{IDENTIFIER})* { // from package import
452 yyextra->packageName=yytext;
453 }
454 "import"{B} {
455 BEGIN(FromModItem);
456 }
457 \n {
458 incLineNr(yyscanner);
459 BEGIN(Search);
460 }
461 {B} {
462 }
463 . {
464 unput(*yytext);
465 BEGIN(Search);
466 }
static void incLineNr(yyscan_t yyscanner)
Definition pyscanner.l:1969
467}
468
469<FromModItem>{
470 "*" { // import all
471 addFrom(yyscanner,TRUE);
472 BEGIN(Search);
473 }
474 {IDENTIFIER}/{B}","{B} {
475 addFrom(yyscanner,FALSE);
476 }
477 {IDENTIFIER}/{B}")" {
478 addFrom(yyscanner,FALSE);
479 }
480 {IDENTIFIER} {
481 addFrom(yyscanner,FALSE);
482 if (!yyextra->importTuple)
483 {
484 BEGIN(Search);
485 }
486 }
487 \n {
488 incLineNr(yyscanner);
489 if (!yyextra->importTuple)
490 {
491 BEGIN(Search);
492 }
493 }
494 {B} {
495 }
496 "(" {
497 yyextra->importTuple=TRUE;
498 }
499 ")" {
500 yyextra->importTuple=FALSE;
501 BEGIN(Search);
502 }
503 "," {
504 }
505 "\\"{B}\n { // line continuation
506 incLineNr(yyscanner);
507 }
508 . {
509 unput(*yytext);
510 BEGIN(Search);
511 }
static void addFrom(yyscan_t yyscanner, bool all)
Definition pyscanner.l:1946
512}
513
514<Import>{
515 {IDENTIFIER}({B}"."{B}{IDENTIFIER})* {
516 yyextra->current->name=removeRedundantWhiteSpace(substitute(yytext,".","::"));
517 yyextra->current->fileName = yyextra->fileName;
518 //printf("Adding using declaration: found:%s:%d name=%s\n",qPrint(yyextra->fileName),yyextra->yyLineNr,qPrint(yyextra->current->name));
519 yyextra->current->section=EntryType::makeUsingDecl();
520 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
521 initEntry(yyscanner);
522 BEGIN(Search);
523 }
524 \n {
525 incLineNr(yyscanner);
526 BEGIN(Search);
527 }
528 {B} {
529 }
530 . {
531 unput(*yytext);
532 BEGIN(Search);
533 }
534}
535
536<SearchMemVars>{
537 ("cls"|"self")"."{IDENTIFIER}/{B}[,)] {
538 const char *s = strchr(yytext,'.'); s++;
539 DBG_CTX((stderr,"Found instance method variable %s in %s at %d\n",s,qPrint(yyextra->current_root->name.data(),yyextra->yyLineNr)));
540 docVariable(yyscanner,s);
541 addEntry(yyscanner);
542 }
543 ("cls"|"self")"."{IDENTIFIER}/{B}"=" {
544 const char *s = strchr(yytext,'.'); s++;
545 DBG_CTX((stderr,"Found instance method variable %s in %s at %d\n",s,qPrint(yyextra->current_root->name.data(),yyextra->yyLineNr)));
546 docVariable(yyscanner,s);
547 BEGIN( SearchSkipValue );
548 }
549 ("cls"|"self")"."{IDENTIFIER}/{B}":" { // type hint
550 const char *s = strchr(yytext,'.'); s++;
551 DBG_CTX((stderr,"Found instance method variable %s in %s at %d\n",s,qPrint(yyextra->current_root->name.data(),yyextra->yyLineNr)));
552 docVariable(yyscanner,s);
553 BEGIN(TypeHint);
554 }
555 {TRIDOUBLEQUOTE} { // start of a comment block
556 initTriDoubleQuoteBlock(yyscanner);
557 BEGIN(TripleComment);
558 }
static void docVariable(yyscan_t yyscanner, const char *s)
Definition pyscanner.l:1847
559
560 {TRISINGLEQUOTE} { // start of a comment block
561 initTriSingleQuoteBlock(yyscanner);
562 BEGIN(TripleComment);
563 }
564
565 {STARTDOCSYMS}/[^#] { // start of a special comment
566 initSpecialBlock(yyscanner);
567 BEGIN(SpecialComment);
568 }
569 {POUNDCOMMENT} { // #
570 }
571 "'" { // start of a single quoted string
572 yyextra->stringContext=YY_START;
573 yyextra->copyString=nullptr;
574 BEGIN( SingleQuoteString );
575 }
576 "\"" { // start of a double quoted string
577 yyextra->stringContext=YY_START;
578 yyextra->copyString=nullptr;
579 BEGIN( DoubleQuoteString );
580 }
581 \n { incLineNr(yyscanner); }
582 "=" {
583 yyextra->current->doc.clear();
584 yyextra->current->brief.clear();
585 unput(*yytext);
586 BEGIN( SearchSkipValue );
587 }
588 {IDENTIFIER} // identifiers
589 [^'"\.#a-z_A-Z=\n]+ // other uninteresting stuff
590 . // anything else
591}
592
593<TypeHint>{
594 ":" { // skip over start of type hint
595 yyextra->braceCount=0;
596 }
597 "("|"["|"{" {
598 yyextra->current->type+=*yytext;
599 yyextra->braceCount++;
600 }
601 ")"|"]"|"}" {
602 yyextra->current->type+=*yytext;
603 yyextra->braceCount--;
604 }
605 "'" { // start of a single quoted string
606 yyextra->stringContext=YY_START;
607 yyextra->copyString=nullptr;
608 BEGIN( SingleQuoteString );
609 }
610 "\"" { // start of a double quoted string
611 yyextra->stringContext=YY_START;
612 yyextra->copyString=nullptr;
613 BEGIN( DoubleQuoteString );
614 }
615 "=" {
616 if (yyextra->braceCount==0)
617 { // end of the type hint
618 yyextra->current->type = yyextra->current->type.stripWhiteSpace();
619 unput(*yytext);
620 BEGIN(SearchSkipValue);
621 }
622 else
623 {
624 yyextra->current->type+=*yytext;
625 }
626 }
627 \n { // end of the type hint
628 yyextra->current->type = yyextra->current->type.stripWhiteSpace();
629 incLineNr(yyscanner);
630 newEntry(yyscanner);
631 BEGIN(SearchMemVars);
632 }
633 "\\\n" {
634 yyextra->current->type+=' ';
635 incLineNr(yyscanner);
636 }
637 . {
638 yyextra->current->type+=*yytext;
639 }
640}
641
642<SearchSkipValue,VariableDec>{
643 "=" { // the assignment operator
644 //printf("====== VariableDec at line %d\n",yyextra->yyLineNr);
645 yyextra->startInit = TRUE;
646 yyextra->current->initializer.str(yytext);
647 yyextra->current->initializer << " ";
648 }
649 {B} { // spaces
650 yyextra->current->initializer << yytext;
651 }
652
653 {INTNUMBER} { // integer value
654 if (yyextra->current->type.isEmpty()) yyextra->current->type = "int";
655 yyextra->current->initializer << yytext;
656 }
657 {FLOATNUMBER} { // floating point value
658 if (yyextra->current->type.isEmpty()) yyextra->current->type = "float";
659 yyextra->current->initializer << yytext;
660 }
661 {BOOL} { // boolean value
662 if (yyextra->current->type.isEmpty()) yyextra->current->type = "bool";
663 yyextra->current->initializer << yytext;
664 }
665 {STRINGPREFIX}?"'" { // string
666 if (yyextra->current->type.isEmpty()) yyextra->current->type = "str";
667 yyextra->current->initializer << yytext;
668 yyextra->copyString=&yyextra->current->initializer;
669 yyextra->stringContext=YY_START;
670 BEGIN( SingleQuoteString );
671 }
672 {STRINGPREFIX}?"\"" { // string
673 if (yyextra->current->type.isEmpty()) yyextra->current->type = "str";
674 yyextra->current->initializer << yytext;
675 yyextra->copyString=&yyextra->current->initializer;
676 yyextra->stringContext=YY_START;
677 BEGIN( DoubleQuoteString );
678 }
679 {TRIDOUBLEQUOTE} { // start of a comment block
680 if (yyextra->current->type.isEmpty()) yyextra->current->type = "str";
681 yyextra->current->initializer << yytext;
682 yyextra->doubleQuote=TRUE;
683 yyextra->copyString=&yyextra->current->initializer;
684 yyextra->stringContext=YY_START;
685 BEGIN(TripleString);
686 }
687
688 {TRISINGLEQUOTE} { // start of a comment block
689 if (yyextra->current->type.isEmpty()) yyextra->current->type = "str";
690 yyextra->current->initializer << yytext;
691 yyextra->doubleQuote=FALSE;
692 yyextra->copyString=&yyextra->current->initializer;
693 yyextra->stringContext=YY_START;
694 BEGIN(TripleString);
695 }
696 "(" { // tuple, only when direct after =
697 if (yyextra->current->mtype!=MethodTypes::Property && yyextra->startInit)
698 {
699 yyextra->current->type = "tuple";
700 }
701 yyextra->current->initializer << *yytext;
702 yyextra->atomStart='(';
703 yyextra->atomEnd=')';
704 yyextra->atomCount=1;
705 yyextra->atomContext=YY_START;
706 BEGIN( VariableAtom );
707 }
708 "[" { // list
709 if (yyextra->startInit) yyextra->current->type = "list";
710 yyextra->current->initializer << *yytext;
711 yyextra->atomStart='[';
712 yyextra->atomEnd=']';
713 yyextra->atomCount=1;
714 yyextra->atomContext=YY_START;
715 BEGIN( VariableAtom );
716 }
717 "{" { // dictionary
718 if (yyextra->startInit) yyextra->current->type = "dict";
719 yyextra->current->initializer << *yytext;
720 yyextra->atomStart='{';
721 yyextra->atomEnd='}';
722 yyextra->atomCount=1;
723 yyextra->atomContext=YY_START;
724 BEGIN( VariableAtom );
725 }
726 "\\\n" {
727 yyextra->current->initializer << yytext;
728 incLineNr(yyscanner);
729 }
730 {IDENTIFIER} {
731 // do something based on the type of the IDENTIFIER
732 if (yyextra->current->type.isEmpty())
733 {
734 for (const auto &child : yyextra->current_root->children())
735 {
736 if (child->name == QCString(yytext))
737 {
738 yyextra->current->type = child->type;
739 break;
740 }
741 }
742 }
743 yyextra->startInit = FALSE;
744 yyextra->current->initializer << yytext;
745 }
746 . {
747 yyextra->startInit = FALSE;
748 yyextra->current->initializer << *yytext;
749 }
750}
751<SearchSkipValue>{
752 {STARTDOCSYMS}/[^#] { // start of a special comment
753 initSpecialBlock(yyscanner);
754 BEGIN(SpecialComment);
755 }
756 {POUNDCOMMENT} { // #
757 }
758 \n { incLineNr(yyscanner);
759 newEntry(yyscanner);
760 BEGIN(SearchMemVars);
761 }
762}
763
764<FunctionBody>{
765 \n{B}/{IDENTIFIER}[^{LETTER}{DIGIT}_] {
766 DBG_CTX((stderr,"indent %d<=%d\n",computeIndent(&yytext[1]),yyextra->indent));
767 if (computeIndent(&yytext[1])<=yyextra->indent)
768 {
769 unput_string(yytext,yyleng);
770 endOfDef(yyscanner);
771 //YY_CURRENT_BUFFER->yy_at_bol=TRUE;
772 BEGIN(Search);
773 }
774 else
775 {
776 incLineNr(yyscanner);
777 yyextra->current->program << yytext;
778 }
779 }
780 \n{B}/"##" {
781 if (computeIndent(&yytext[1])<=yyextra->indent)
782 {
783 unput_string(yytext,yyleng);
784 endOfDef(yyscanner);
785 //YY_CURRENT_BUFFER->yy_at_bol=TRUE;
786 BEGIN(Search);
787 }
788 else
789 {
790 incLineNr(yyscanner);
791 yyextra->current->program << yytext;
792 }
793 }
794 <<EOF>> {
795 endOfDef(yyscanner);
796 yyterminate();
797 }
798 ^{BB}/\n { // skip empty line
799 yyextra->current->program << yytext;
800 }
801 ^{BB} { // something at indent >0
802 yyextra->current->program << yytext;
803 yyextra->curIndent = computeIndent(yytext);
804 if (yyextra->curIndent<=yyextra->indent)
805 // jumped out of the function
806 {
807 endOfDef(yyscanner,1);
808 BEGIN(Search);
809 }
810 }
811 "'" { // start of a single quoted string
812 yyextra->current->program << yytext;
813 yyextra->stringContext=YY_START;
814 yyextra->specialBlock = FALSE;
815 yyextra->copyString=&yyextra->current->program;
816 BEGIN( SingleQuoteString );
817 }
818 "\"" { // start of a double quoted string
819 yyextra->current->program << yytext;
820 yyextra->stringContext=YY_START;
821 yyextra->specialBlock = FALSE;
822 yyextra->copyString=&yyextra->current->program;
823 BEGIN( DoubleQuoteString );
824 }
825 [^ \t\n#'".]+ { // non-special stuff
826 yyextra->current->program << yytext;
827 yyextra->specialBlock = FALSE;
828 }
829 ^{POUNDCOMMENT} { // normal comment
830 yyextra->current->program << yytext;
831 }
832 "#".* { // comment half way
833 yyextra->current->program << yytext;
834 }
835 {NEWLINE} {
836 incLineNr(yyscanner);
837 yyextra->current->program << yytext;
838 }
839 . { // any character
840 yyextra->current->program << *yytext;
841 yyextra->specialBlock = FALSE;
842 }
#define yyterminate()
const int DIGIT
RegularExpression Id.
const int LETTER
RegularExpression Id.
static void endOfDef(yyscan_t yyscanner, int correction=0)
Definition pyscanner.l:2046
#define unput_string(yytext, yyleng)
Definition pyscanner.l:70
843
844 {TRIDOUBLEQUOTE} { // start of a comment block
845 yyextra->current->program << yytext;
846 initTriDoubleQuoteBlock(yyscanner);
847 BEGIN(TripleComment);
848 }
849
850 {TRISINGLEQUOTE} { // start of a comment block
851 yyextra->current->program << yytext;
852 initTriSingleQuoteBlock(yyscanner);
853 BEGIN(TripleComment);
854 }
855
856}
857
858<FunctionDec>{
859 {IDENTIFIER} {
860 //found function name
861 yyextra->current->name = yytext;
862 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
863 newFunction(yyscanner);
864 }
865 {B}":"{B} { // function without arguments
866 yyextra->specialBlock = TRUE; // expecting a docstring
867 yyextra->bodyEntry = yyextra->current;
868 yyextra->current->bodyLine = yyextra->yyLineNr;
869 BEGIN(FunctionBody);
870 }
static void newFunction(yyscan_t yyscanner)
Definition pyscanner.l:1882
871
872 "->" {
873 yyextra->defVal.str(std::string());
874 yyextra->braceCount = 0;
875 BEGIN(FunctionTypeAnnotation);
876 }
877 {B}"(" {
878 yyextra->funcParamsEnd = FALSE;
879 yyextra->current->bodyLine = yyextra->yyLineNr;
880 BEGIN(FunctionParams);
881 }
882 ")" { // end of parameter list
883 if (yyextra->current->argList.empty())
884 {
885 yyextra->current->argList.setNoParameters(TRUE);
886 }
887 yyextra->current->args = argListToString(yyextra->current->argList);
888 yyextra->funcParamsEnd = TRUE;
889 }
QCString argListToString(const ArgumentList &al, bool useCanonicalType, bool showDefVals)
Definition util.cpp:1174
890}
891
892<FunctionParams>{
893 {BB} {
894 }
895
896 "," {
897 if (!yyextra->argType.isEmpty())
898 {
899 Argument a;
900 a.name = "";
901 a.type = yyextra->argType;
902 yyextra->current->argList.push_back(a);
903 yyextra->argType = "";
904 }
905 }
This class contains the information about the argument of a function or template.
Definition arguments.h:27
QCString type
Definition arguments.h:37
QCString name
Definition arguments.h:39
906
907 [\*]+ {
908 yyextra->argType = yytext;
909 }
910 {IDENTIFIER} { // Name of parameter
911 lineCount(yyscanner);
912 Argument a;
913 a.name = QCString(yytext).stripWhiteSpace();
914 a.type = yyextra->argType;
915 yyextra->current->argList.push_back(a);
916 yyextra->argType = "";
917 }
918 "=" { // default value
919 // TODO: this rule is too simple, need to be able to
920 // match things like =")" as well!
921 yyextra->defVal.str(std::string());
922 yyextra->braceCount = 0;
923 BEGIN(FunctionParamDefVal);
924 }
925 ")" {
926 if (!yyextra->argType.isEmpty())
927 {
928 Argument a;
929 a.name = "";
930 a.type = yyextra->argType;
931 yyextra->current->argList.push_back(a);
932 yyextra->argType = "";
933 }
934 unput(*yytext);
935 BEGIN(FunctionDec);
936 }
937 ":"{B} {
938 yyextra->defVal.str(std::string());
939 yyextra->braceCount = 0;
940 BEGIN(FunctionAnnotation);
941 }
942 {POUNDCOMMENT} { // a comment
943 }
944 {PARAMNONEMPTY} { // Default rule inside arguments.
945 }
946
947}
948
949<FunctionTypeAnnotation>{
950 "{" |
951 "[" |
952 "(" {
953 ++yyextra->braceCount;
954 yyextra->defVal << *yytext;
955 }
956 "}" |
957 "]" |
958 ")" {
959 --yyextra->braceCount;
960 yyextra->defVal << *yytext;
961 }
962 ":" {
963 if (yyextra->braceCount == 0)
964 {
965 yyextra->current->type = yyextra->defVal.str();
966 unput(*yytext);
967 BEGIN(FunctionDec);
968 }
969 else
970 yyextra->defVal << *yytext;
971 }
972 "'" {
973 yyextra->defVal << *yytext;
974 yyextra->copyString=&yyextra->defVal;
975 yyextra->stringContext=FunctionTypeAnnotation;
976 BEGIN(SingleQuoteString);
977 }
978 "\"" {
979 yyextra->defVal << *yytext;
980 yyextra->copyString=&yyextra->defVal;
981 yyextra->stringContext=FunctionTypeAnnotation;
982 BEGIN(DoubleQuoteString);
983 }
984 \n {
985 yyextra->defVal << *yytext;
986 incLineNr(yyscanner);
987 }
988 . {
989 yyextra->defVal << *yytext;
990 }
991}
992
993<FunctionAnnotation>{
994 "{" |
995 "[" |
996 "(" {
997 ++yyextra->braceCount;
998 yyextra->defVal << *yytext;
999 }
1000 "}" |
1001 "]" {
1002 --yyextra->braceCount;
1003 yyextra->defVal << *yytext;
1004 }
1005 ")" |
1006 "=" |
1007 "," {
1008 if (yyextra->braceCount == 0)
1009 {
1010 if (!yyextra->current->argList.empty())
1011 yyextra->current->argList.back().type += yyextra->defVal.str();
1012 if (*yytext != ',')
1013 unput(*yytext);
1014 BEGIN(FunctionParams);
1015 }
1016 else
1017 {
1018 if (*yytext == ')')
1019 --yyextra->braceCount;
1020 yyextra->defVal << *yytext;
1021 }
1022 }
1023 "'" {
1024 yyextra->defVal << *yytext;
1025 yyextra->copyString=&yyextra->defVal;
1026 yyextra->stringContext=FunctionAnnotation;
1027 BEGIN(SingleQuoteString);
1028 }
1029 "\"" {
1030 yyextra->defVal << *yytext;
1031 yyextra->copyString=&yyextra->defVal;
1032 yyextra->stringContext=FunctionAnnotation;
1033 BEGIN(DoubleQuoteString);
1034 }
1035 \n {
1036 yyextra->defVal << *yytext;
1037 incLineNr(yyscanner);
1038 }
1039 . {
1040 yyextra->defVal << *yytext;
1041 }
1042}
1043
1044<FunctionParamDefVal>{
1045 "{" |
1046 "[" |
1047 "(" { // internal opening brace, assumption is that we have correct code so braces do match
1048 ++yyextra->braceCount;
1049 yyextra->defVal << *yytext;
1050 }
1051 "}" |
1052 "]" {
1053 --yyextra->braceCount;
1054 yyextra->defVal << *yytext;
1055 }
1056 ")" |
1057 "," {
1058 if (yyextra->braceCount == 0)
1059 {
1060 if (!yyextra->current->argList.empty())
1061 yyextra->current->argList.back().defval=QCString(yyextra->defVal.str()).stripWhiteSpace();
1062 if (*yytext == ')')
1063 unput(*yytext);
1064 BEGIN(FunctionParams);
1065 }
1066 else
1067 {
1068 if (*yytext == ')')
1069 --yyextra->braceCount;
1070 yyextra->defVal << *yytext;
1071 }
1072 }
1073
1074 "'" {
1075 yyextra->defVal << *yytext;
1076 yyextra->copyString=&yyextra->defVal;
1077 yyextra->stringContext=FunctionParamDefVal;
1078 BEGIN( SingleQuoteString );
1079 }
1080 "\"" {
1081 yyextra->defVal << *yytext;
1082 yyextra->copyString=&yyextra->defVal;
1083 yyextra->stringContext=FunctionParamDefVal;
1084 BEGIN( DoubleQuoteString );
1085 }
1086 \n {
1087 yyextra->defVal << *yytext;
1088 incLineNr(yyscanner);
1089 }
1090 . {
1091 yyextra->defVal << *yytext;
1092 }
1093}
1094
1095
1096<ClassBody>{
1097 \n/{IDENTIFIER}{BB} { // new def at indent 0
1098 if (computeIndent(&yytext[1])<=yyextra->indent)
1099 {
1100 int i;
1101 for (i=(int)yyleng-1;i>=0;i--)
1102 {
1103 unput(yytext[i]);
1104 }
1105 endOfDef(yyscanner);
1106 //YY_CURRENT_BUFFER->yy_at_bol=TRUE;
1107 BEGIN(Search);
1108 }
1109 else
1110 {
1111 incLineNr(yyscanner);
1112 yyextra->current->program << yytext;
1113 }
1114 }
1115 \n/"##"[^#] { // start of a special comment at indent 0
1116 if (computeIndent(&yytext[1])<=yyextra->indent)
1117 {
1118 int i;
1119 for (i=(int)yyleng-1;i>=0;i--)
1120 {
1121 unput(yytext[i]);
1122 }
1123 endOfDef(yyscanner);
1124 //YY_CURRENT_BUFFER->yy_at_bol=TRUE;
1125 BEGIN(Search);
1126 }
1127 else
1128 {
1129 incLineNr(yyscanner);
1130 yyextra->current->program << yytext;
1131 }
1132 }
1133 ^{BB}/\n { // skip empty line
1134 yyextra->current->program << yytext;
1135 }
1136 <<EOF>> {
1137 endOfDef(yyscanner);
1138 yyterminate();
1139 }
1140 ^{BB} { // something at indent >0
1141 yyextra->curIndent=computeIndent(yytext);
1142 DBG_CTX((stderr,"yyextra->curIndent=%d yyextra->indent=%d\n",yyextra->curIndent,yyextra->indent));
1143 if (yyextra->curIndent<=yyextra->indent)
1144 // jumped out of the class/method
1145 {
1146 endOfDef(yyscanner,1);
1147 yyextra->indent=yyextra->curIndent;
1148 // make sure the next rule matches ^...
1149 //YY_CURRENT_BUFFER->yy_at_bol=TRUE;
1150 //yyextra->hideClassDocs = FALSE;
1151 BEGIN(Search);
1152 }
1153 else
1154 {
1155 yyextra->current->program << yytext;
1156 }
1157 }
1158 "'" { // start of a single quoted string
1159 yyextra->current->program << *yytext;
1160 yyextra->stringContext=YY_START;
1161 yyextra->specialBlock = FALSE;
1162 yyextra->copyString=&yyextra->current->program;
1163 BEGIN( SingleQuoteString );
1164 }
1165 "\"" { // start of a double quoted string
1166 yyextra->current->program << *yytext;
1167 yyextra->stringContext=YY_START;
1168 yyextra->specialBlock = FALSE;
1169 yyextra->copyString=&yyextra->current->program;
1170 BEGIN( DoubleQuoteString );
1171 }
1172 [^ \t\n#'"]+ { // non-special stuff
1173 yyextra->current->program << yytext;
1174 yyextra->specialBlock = FALSE;
1175 //yyextra->hideClassDocs = FALSE;
1176 }
1177 {NEWLINE} {
1178 yyextra->current->program << *yytext;
1179 incLineNr(yyscanner);
1180 }
1181 {POUNDCOMMENT} { // normal comment
1182 yyextra->current->program << yytext;
1183 }
1184 . { // any character
1185 yyextra->specialBlock = FALSE;
1186 yyextra->current->program << *yytext;
1187 }
1188 {TRIDOUBLEQUOTE} { // start of a comment block
1189 //if (!yyextra->hideClassDocs)
1190 yyextra->current->program << yytext;
1191 initTriDoubleQuoteBlock(yyscanner);
1192 BEGIN(TripleComment);
1193 }
1194
1195 {TRISINGLEQUOTE} { // start of a comment block
1196 //if (!yyextra->hideClassDocs)
1197 yyextra->current->program << yytext;
1198 initTriSingleQuoteBlock(yyscanner);
1199 BEGIN(TripleComment);
1200 }
1201}
1202
1203<ClassDec>{IDENTIFIER} {
1204 if (yyextra->current->type.isEmpty())
1205 {
1206 yyextra->current->type = "class";
1207 }
1208
1209 yyextra->current->section = EntryType::makeClass();
1210 yyextra->current->name = yytext;
1211 // we need to set the protectiion based on the "local" class name
1212 setProtection(yyscanner);
1213
1214 // prepend scope in case of nested classes
1215 if (yyextra->current_root->section.isScope())
1216 {
1217 //printf("*** Prepending scope %s to class %s\n",qPrint(yyextra->current_root->name),qPrint(yyextra->current->name));
1218 yyextra->current->name.prepend(yyextra->current_root->name+"::");
1219 }
1220
1221 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
1222 yyextra->current->fileName = yyextra->fileName;
1223 yyextra->docBlockContext = YY_START;
1224 yyextra->docBlockInBody = FALSE;
1225 yyextra->docBlockJavaStyle = FALSE;
1226 yyextra->docBlock.clear();
1227
1228 BEGIN(ClassInheritance);
1229 }
1230
1231<ClassInheritance>{
1232 ({BB}|[\‍(,\‍)]) { // syntactic sugar for the list
1233 }
1234
1235 ":" { // begin of the class definition
1236 yyextra->specialBlock = TRUE; // expecting a docstring
1237 yyextra->current->bodyLine = yyextra->yyLineNr;
1238 yyextra->current->program.str(std::string());
1239 BEGIN(ClassCaptureIndent);
1240 }
1241
1242 {SCOPE} {
1243 yyextra->current->extends.emplace_back(
1245 );
1246 //Has base class-do stuff
1247 }
1248 "'" { // start of a single quoted string
1249 yyextra->stringContext=YY_START;
1250 BEGIN( SingleQuoteStringIgnore );
1251 }
1252 "\"" { // start of a double quoted string
1253 yyextra->stringContext=YY_START;
1254 BEGIN( DoubleQuoteStringIgnore );
1255 }
1256}
1257
1258<SingleQuoteStringIgnore>{
1259 "'" { // end of a single quoted string
1260 BEGIN(yyextra->stringContext);
1261 }
1262 . { }
1263}
1264<DoubleQuoteStringIgnore>{
1265 "\"" { // end of a double quoted string
1266 BEGIN(yyextra->stringContext);
1267 }
1268 . { }
1269}
1270
1271<ClassCaptureIndent>{
1272 "\n"|({BB}"\n") {
1273 // Blankline - ignore, keep looking for indentation.
1274 lineCount(yyscanner);
1275 yyextra->current->program << yytext;
1276 }
1277
1278 {TRIDOUBLEQUOTE} { // start of a comment block
1279 initTriDoubleQuoteBlock(yyscanner);
1280 yyextra->current->program << yytext;
1281 BEGIN(TripleComment);
1282 }
1283 {TRISINGLEQUOTE} { // start of a comment block
1284 initTriSingleQuoteBlock(yyscanner);
1285 yyextra->current->program << yytext;
1286 BEGIN(TripleComment);
1287 }
1288 {STARTDOCSYMS}[#]* { // start of a special comment
1289 initSpecialBlock(yyscanner);
1290 BEGIN(SpecialComment);
1291 }
1292 {POUNDCOMMENT} { // ignore comment with just one #
1293 }
1294 ^{BB} {
1295 yyextra->current->program << yytext;
1296 //yyextra->current->startLine = yyextra->yyLineNr;
1297 yyextra->curIndent=computeIndent(yytext);
1298 yyextra->bodyEntry = yyextra->current;
1299 DBG_CTX((stderr,"setting indent %d\n",yyextra->curIndent));
1300 //printf("yyextra->current->program=[%s]\n",qPrint(yyextra->current->program));
1301 //yyextra->hideClassDocs = TRUE;
1302 BEGIN(ClassBody);
1303 }
1304
1305 ""/({NONEMPTY}|{EXPCHAR}) {
1306 // Just pushback an empty class, and
1307 // resume parsing the body.
1308 newEntry(yyscanner);
1309 yyextra->current->program << yytext;
1310
1311 // printf("Failed to find indent - skipping!");
1312 BEGIN( Search );
1313 }
1314}
1315
1316
1317<VariableDec>{
1318 ":"{B}{IDENTIFIER} { //typing
1319 yyextra->startInit = FALSE;
1320 yyextra->current->type = substitute(yytext,":","");
1321 }
1322 {STARTDOCSYMS}"<"/.* { // start of a special comment
1323 yyextra->curIndent=computeIndent(yytext);
1324 yyextra->packageCommentAllowed = FALSE;
1325 initSpecialBlock(yyscanner);
1326 yyextra->docBlockContext = VariableEnd;
1327 BEGIN(SpecialComment);
1328 }
1329 "#".* { // comment
1330 BEGIN( VariableEnd );
1331 }
1332 \n {
1333 unput('\n');
1334 BEGIN( VariableEnd );
1335 }
1336}
1337
1338<VariableAtom>{
1339 [\‍(\[\{] {
1340 yyextra->current->initializer << *yytext;
1341 if (yyextra->atomStart==*yytext)
1342 {
1343 yyextra->atomCount++;
1344 }
1345 }
1346 [\‍)\]\}] {
1347 yyextra->current->initializer << *yytext;
1348 if (yyextra->atomEnd==*yytext)
1349 {
1350 yyextra->atomCount--;
1351 }
1352 if (yyextra->atomCount==0)
1353 {
1354 yyextra->startInit = FALSE;
1355 BEGIN(yyextra->atomContext);
1356 }
1357 }
1358 {TRIDOUBLEQUOTE} { // start of a comment block
1359 yyextra->specialBlock = FALSE;
1360 yyextra->current->program << yytext;
1361 initTriDoubleQuoteBlock(yyscanner);
1362 BEGIN(TripleComment);
1363 }
1364
1365 {TRISINGLEQUOTE} { // start of a comment block
1366 yyextra->specialBlock = FALSE;
1367 yyextra->current->program << yytext;
1368 initTriSingleQuoteBlock(yyscanner);
1369 BEGIN(TripleComment);
1370 }
1371 "'" {
1372 yyextra->stringContext=YY_START;
1373 yyextra->current->initializer << "'";
1374 yyextra->copyString=&yyextra->current->initializer;
1375 BEGIN( SingleQuoteString );
1376 }
1377 "\"" {
1378 yyextra->stringContext=YY_START;
1379 yyextra->current->initializer << "\"";
1380 yyextra->copyString=&yyextra->current->initializer;
1381 BEGIN( DoubleQuoteString );
1382 }
1383 {IDENTIFIER} {
1384 yyextra->current->initializer << yytext;
1385 }
1386 . {
1387 yyextra->current->initializer << *yytext;
1388 }
1389 \n {
1390 yyextra->current->initializer << *yytext;
1391 incLineNr(yyscanner);
1392 }
1393
1394}
1395
1396<VariableEnd>{
1397 \n {
1398 incLineNr(yyscanner);
1399 if (!stripWhiteSpace(yyextra->current->initializer.str()).empty())
1400 {
1401 newVariable(yyscanner);
1402 }
1403 BEGIN(Search);
1404 }
1405 . {
1406 unput(*yytext);
1407 newVariable(yyscanner);
1408 BEGIN(Search);
1409 }
1410 <<EOF>> { yyterminate();
1411 }
static void newVariable(yyscan_t yyscanner)
Definition pyscanner.l:1860
std::string_view stripWhiteSpace(std::string_view s)
Given a string view s, returns a new, narrower view on that string, skipping over any leading or trai...
Definition stringutil.h:72
1412}
1413
1414<TripleComment>{
1415 {ENDTRIDOUBLEQUOTE} |
1416 {ENDTRISINGLEQUOTE} {
1417 // printf("Expected module block %d special=%d\n",yyextra->expectModuleDocs,yyextra->specialBlock);
1418 if (yyextra->doubleQuote==(yytext[0]=='"'))
1419 {
1420 if (yyextra->specialBlock) // expecting a docstring
1421 {
1422 QCString actualDoc=yyextra->docBlock;
1423 if (!yyextra->docBlockSpecial) // legacy unformatted docstring
1424 {
1425 if (!actualDoc.isEmpty())
1426 {
1427 stripIndentationVerbatim(actualDoc,yyextra->commentIndent);
1428 actualDoc.prepend("@iverbatim\n");
1429 actualDoc.append("@endiverbatim ");
1430 }
1431 }
1432 //printf("-------> yyextra->current=%p yyextra->bodyEntry=%p\n",yyextra->current,yyextra->bodyEntry);
1433 handleCommentBlock(yyscanner, actualDoc, FALSE);
1434 }
1435 else if (yyextra->packageCommentAllowed) // expecting module docs
1436 {
1437 QCString actualDoc=yyextra->docBlock;
1438 if (!yyextra->docBlockSpecial) // legacy unformatted docstring
1439 {
1440 if (!actualDoc.isEmpty())
1441 {
1442 stripIndentationVerbatim(actualDoc,yyextra->commentIndent);
1443 actualDoc.prepend("@iverbatim\n");
1444 actualDoc.append("@endiverbatim ");
1445 }
1446 }
1447 if (yyextra->moduleScope.startsWith("__") && yyextra->moduleScope.endsWith("__"))
1448 {
1449 actualDoc.prepend("\\namespace \\"+yyextra->moduleScope+" ");
1450 }
1451 else
1452 {
1453 actualDoc.prepend("\\namespace "+yyextra->moduleScope+" ");
1454 }
1455 handleCommentBlock(yyscanner, actualDoc, FALSE);
1456 }
1457 if ((yyextra->docBlockContext==ClassBody /*&& !yyextra->hideClassDocs*/) ||
1458 yyextra->docBlockContext==FunctionBody)
1459 {
1460 yyextra->current->program << yyextra->docBlock;
1461 yyextra->current->program << yytext;
1462 }
1463 //if (yyextra->hideClassDocs)
1464 //{
1465 // yyextra->current->startLine = yyextra->yyLineNr;
1466 //}
1467 //yyextra->hideClassDocs=FALSE;
1468 BEGIN(yyextra->docBlockContext);
1469 }
1470 else
1471 {
1472 yyextra->docBlock += yytext;
1473 }
1474 yyextra->packageCommentAllowed = FALSE;
1475 }
QCString & prepend(const char *s)
Definition qcstring.h:407
QCString & append(char c)
Definition qcstring.h:381
static void handleCommentBlock(yyscan_t yyscanner, const QCString &doc, bool brief)
Definition pyscanner.l:1992
void stripIndentationVerbatim(QCString &doc, const int indentationLevel)
Definition util.cpp:6366
1476
1477
1478 ^{BB} { // leading whitespace, compensate for """! / '''!
1479 if (yyextra->docBlockSpecial && yyleng >= yyextra->curIndent)
1480 yyextra->docBlock += yytext + yyextra->curIndent;
1481 else
1482 yyextra->docBlock += yytext;
1483 }
1484 [^"'\n \t\\@]+ {
1485 yyextra->docBlock += yytext;
1486 }
1487 \n {
1488 incLineNr(yyscanner);
1489 yyextra->docBlock += yytext;
1490 }
1491 {CMD}"ifile"{B}+"\""[^\n\"]+"\"" {
1492 yyextra->fileName = &yytext[6];
1493 yyextra->fileName = yyextra->fileName.stripWhiteSpace();
1494 yyextra->fileName = yyextra->fileName.mid(1,yyextra->fileName.length()-2);
1495 yyextra->docBlock+=yytext;
1496 }
1497 {CMD}"ifile"{B}+{FILEMASK} {
1498 yyextra->fileName = &yytext[6];
1499 yyextra->fileName = yyextra->fileName.stripWhiteSpace();
1500 yyextra->docBlock+=yytext;
1501 }
1502 {CMD}"iline"{LINENR}/[\n\.] |
1503 {CMD}"iline"{LINENR}{B} {
1504 bool ok = false;
1505 int nr = QCString(&yytext[6]).toInt(&ok);
1506 if (!ok)
1507 {
1508 warn(yyextra->fileName,yyextra->yyLineNr,"Invalid line number '%s' for iline command",yytext);
1509 }
1510 else
1511 {
1512 yyextra->yyLineNr = nr;
1513 }
1514 yyextra->docBlock+=yytext;
1515 }
1516 ({CMD}{CMD}){ID}/[^a-z_A-Z0-9] { // escaped command
1517 yyextra->docBlock+=yytext;
1518 }
1519 \\. { // escaped char TO be extended
1520 yyextra->docBlock += yytext;
1521 }
1522 . {
1523 yyextra->docBlock += yytext;
1524 }
int toInt(bool *ok=nullptr, int base=10) const
Definition qcstring.cpp:249
1525}
1526
1527<SpecialComment>{
1528 ^{B}"#"("#")* { // skip leading hashes
1529 }
1530 \n/{B}"#" { // continuation of the comment on the next line
1531 yyextra->docBlock+='\n';
1532 yyextra->docBrief = FALSE;
1533 incLineNr(yyscanner);
1534 }
1535 {CMD}"ifile"{B}+"\""[^\n\"]+"\"" {
1536 yyextra->fileName = &yytext[6];
1537 yyextra->fileName = yyextra->fileName.stripWhiteSpace();
1538 yyextra->fileName = yyextra->fileName.mid(1,yyextra->fileName.length()-2);
1539 yyextra->docBlock+=yytext;
1540 }
1541 {CMD}"ifile"{B}+{FILEMASK} {
1542 yyextra->fileName = &yytext[6];
1543 yyextra->fileName = yyextra->fileName.stripWhiteSpace();
1544 yyextra->docBlock+=yytext;
1545 }
1546 {CMD}"iline"{LINENR}/[\n\.] |
1547 {CMD}"iline"{LINENR}{B} {
1548 bool ok = false;
1549 int nr = QCString(&yytext[6]).toInt(&ok);
1550 if (!ok)
1551 {
1552 warn(yyextra->fileName,yyextra->yyLineNr,"Invalid line number '%s' for iline command",yytext);
1553 }
1554 else
1555 {
1556 yyextra->yyLineNr = nr;
1557 }
1558 yyextra->docBlock+=yytext;
1559 }
1560 ({CMD}{CMD}){ID}/[^a-z_A-Z0-9] { // escaped command
1561 yyextra->docBlock+=yytext;
1562 }
1563 "\\ilinebr "{B}* {
1564 QCString indent;
1565 int extraSpaces = std::max(0,static_cast<int>(yyleng-9-yyextra->curIndent-2));
1566 indent.fill(' ',extraSpaces);
1567 //printf("extraSpaces=%d\n",extraSpaces);
1568 yyextra->docBlock += "\\ilinebr ";
1569 yyextra->docBlock += indent;
1570 }
1571 [^#\\@\n]+ { // any other stuff
1572 yyextra->docBlock+=yytext;
1573 }
1574 \n { // new line that ends the comment
1575 handleCommentBlock(yyscanner, yyextra->docBlock, yyextra->docBrief);
1576 if (yyextra->docBlockContext == VariableEnd)
1577 {
1578 unput(*yytext);
1579 }
1580 else
1581 {
1582 incLineNr(yyscanner);
1583 }
1584 BEGIN(yyextra->docBlockContext);
1585 }
1586 . { // anything we missed
1587 yyextra->docBlock+=*yytext;
1588 }
void fill(char c, int len=-1)
Fills a string with a predefined character.
Definition qcstring.h:180
1589}
1590
1591<SingleQuoteString>{
1592 \\{B}\n { // line continuation
1593 addToString(yyscanner,yytext);
1594 incLineNr(yyscanner);
1595 }
1596 \\. { // escaped char
1597 addToString(yyscanner,yytext);
1598 }
1599 "\"\"\"" { // triple double quotes
1600 addToString(yyscanner,yytext);
1601 }
1602 "'" { // end of the string
1603 addToString(yyscanner,yytext);
1604 BEGIN(yyextra->stringContext);
1605 }
1606 [^"'\n\\]+ { // normal chars
1607 addToString(yyscanner,yytext);
1608 }
1609 . { // normal char
1610 addToString(yyscanner,yytext);
1611 }
static void addToString(yyscan_t yyscanner, const char *s)
Definition pyscanner.l:2059
1612}
1613
1614<DoubleQuoteString>{
1615 \\{B}\n { // line continuation
1616 addToString(yyscanner,yytext);
1617 incLineNr(yyscanner);
1618 }
1619 \\. { // escaped char
1620 addToString(yyscanner,yytext);
1621 }
1622 "'''" { // triple single quotes
1623 addToString(yyscanner,yytext);
1624 }
1625 "\"" { // end of the string
1626 addToString(yyscanner,yytext);
1627 BEGIN(yyextra->stringContext);
1628 }
1629 [^"'\n\\]+ { // normal chars
1630 addToString(yyscanner,yytext);
1631 }
1632 . { // normal char
1633 addToString(yyscanner,yytext);
1634 }
1635}
1636
1637<TripleString>{
1638 {ENDTRIDOUBLEQUOTE} |
1639 {ENDTRISINGLEQUOTE} {
1640 *yyextra->copyString << yytext;
1641 if (yyextra->doubleQuote==(yytext[0]=='"'))
1642 {
1643 BEGIN(yyextra->stringContext);
1644 }
1645 }
1646
1647
1648 ({LONGSTRINGBLOCK}) {
1649 lineCount(yyscanner);
1650 *yyextra->copyString << yytext;
1651 }
1652 \n {
1653 incLineNr(yyscanner);
1654 *yyextra->copyString << yytext;
1655 }
1656 . {
1657 *yyextra->copyString << *yytext;
1658 }
1659}
1660
1661<Decorator>{
1662 {TRIDOUBLEQUOTE} { // start of a comment block
1663 yyextra->doubleQuote=TRUE;
1664 yyextra->decoratorCommentStr.str(std::string());
1665 yyextra->copyString=&yyextra->decoratorCommentStr;
1666 yyextra->stringContext=YY_START;
1667 BEGIN(TripleString);
1668 }
1669
1670 {TRISINGLEQUOTE} { // start of a comment block
1671 yyextra->doubleQuote=FALSE;
1672 yyextra->decoratorCommentStr.str(std::string());
1673 yyextra->copyString=&yyextra->decoratorCommentStr;
1674 yyextra->stringContext=YY_START;
1675 BEGIN(TripleString);
1676 }
1677 "'" {
1678 yyextra->stringContext=YY_START;
1679 yyextra->decoratorCommentStr.str(std::string());
1680 yyextra->copyString=&yyextra->decoratorCommentStr;
1681 BEGIN( SingleQuoteString );
1682 }
1683 "\"" {
1684 yyextra->stringContext=YY_START;
1685 yyextra->decoratorCommentStr.str(std::string());
1686 yyextra->copyString=&yyextra->decoratorCommentStr;
1687 BEGIN( DoubleQuoteString );
1688 }
1689 "(" {
1690 yyextra->decoratorRound++;
1691 }
1692 ")" {
1693 yyextra->decoratorRound--;
1694 if (!yyextra->decoratorRound) BEGIN( Search );
1695 }
1696 \n {
1697 incLineNr(yyscanner);
1698 }
1699 . { }
1700}
1701
1702 /* ------------ End rules -------------- */
1703
1704 /*
1705<*>({NONEMPTY}|{EXPCHAR}|{BB}) { // This should go one character at a time.
1706 // printf("[pyscanner] '%s' [ state %d ] [line %d] no match\n",
1707 // yytext, YY_START, yyextra->yyLineNr);
1708
1709 }
1710 */
1711
1712<*>{NEWLINE} {
1713 //printf("[pyscanner] %d NEWLINE [line %d] no match\n",
1714 // YY_START, yyextra->yyLineNr);
1715
1716 lineCount(yyscanner);
1717 }
1718
1719<*>"'" {
1720 //fprintf(stderr,"Quote: %d\n",YY_START);
1721 }
1722
1723<*>. {
1724 //printf("[pyscanner] '%s' [ state %d ] [line %d] no match\n",
1725 // yytext, YY_START, yyextra->yyLineNr);
1726
1727 }
1728
1729
1730%%

◆ yyread()

static int yyread ( yyscan_t yyscanner,
char * buf,
int max_size )
static

Definition at line 1734 of file pyscanner.l.

1735{
1736 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1737 int c=0;
1738 const char *p = yyextra->inputString + yyextra->inputPosition;
1739 while ( c < max_size && *p ) { *buf++ = *p++; c++; }
1740 yyextra->inputPosition+=c;
1741 return c;
1742}