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 code.l:3989

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 1815 of file pyscanner.l.

1816{
1817 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1818
1819 auto doc = yyextra->current->doc;
1820 auto docLine = yyextra->current->docLine;
1821 auto docFile = yyextra->current->docFile;
1822 auto brief = yyextra->current->brief;
1823 auto briefLine = yyextra->current->briefLine;
1824 auto briefFile = yyextra->current->briefFile;
1825
1826 yyextra->previous = yyextra->current;
1827 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
1828 initEntry(yyscanner);
static void initEntry(yyscan_t yyscanner)
Definition pyscanner.l:1759
1829
1830 yyextra->current->doc = doc;
1831 yyextra->current->docLine = docLine;
1832 yyextra->current->docFile = docFile;
1833 yyextra->current->brief = brief;
1834 yyextra->current->briefLine = briefLine;
1835 yyextra->current->briefFile = briefFile;
1836}

References initEntry().

Referenced by addVariable().

◆ addFrom()

static void addFrom ( yyscan_t yyscanner,
bool all )
static

Definition at line 1953 of file pyscanner.l.

1954{
1955 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1956 QCString item=all ? yyextra->packageName : yyextra->packageName+"."+yytext;
1957 yyextra->current->name=removeRedundantWhiteSpace(substitute(item,".","::"));
1958 yyextra->current->fileName = yyextra->fileName;
1959 //printf("Adding using declaration: found:%s:%d name=%s\n",qPrint(yyextra->fileName),yyextra->yyLineNr,qPrint(yyextra->current->name));
1960 yyextra->current->section=all ? EntryType::makeUsingDir() : EntryType::makeUsingDecl();
1961 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
1962 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
1963}

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

◆ addToString()

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

Definition at line 2066 of file pyscanner.l.

2067{
2068 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2069 if (yyextra->copyString) (*yyextra->copyString) << s;
2070}

◆ addVariable()

static void addVariable ( yyscan_t yyscanner)
static

Definition at line 1878 of file pyscanner.l.

1879{
1880 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1881 setProtection(yyscanner);
1882 if (yyextra->current_root->section.isCompound()) // mark as class variable
1883 {
1884 yyextra->current->isStatic = TRUE;
1885 }
1886 addEntry(yyscanner);
static void setProtection(yyscan_t yyscanner)
Definition pyscanner.l:1838
static void addEntry(yyscan_t yyscanner)
Definition pyscanner.l:1815
#define TRUE
Definition qcstring.h:37
1887}

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

◆ computeIndent()

static int computeIndent ( const char * s)
inlinestatic

Definition at line 1904 of file pyscanner.l.

1905{
1906 int col=0;
1907 int tabSize=Config_getInt(TAB_SIZE);
1908 const char *p=s;
1909 char c;
1910 while ((c=*p++))
1911 {
1912 if (c==' ') col++;
1913 else if (c=='\t') col+=tabSize-(col%tabSize);
1914 else break;
1915 }
1916 return col;
#define Config_getInt(name)
Definition config.h:34
1917}

References Config_getInt.

◆ docVariable()

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

Definition at line 1854 of file pyscanner.l.

1855{
1856 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1857 yyextra->current->name = name;
1858 yyextra->current->section=EntryType::makeVariable();
1859 yyextra->current->fileName = yyextra->fileName;
1860 yyextra->current->startLine = yyextra->yyLineNr;
1861 yyextra->current->bodyLine = yyextra->yyLineNr;
1862 yyextra->current->type.clear();
1863 setProtection(yyscanner);
1864 yyextra->checkDupEntry = true;
1865}

References setProtection().

◆ endOfDef()

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

Definition at line 2053 of file pyscanner.l.

2054{
2055 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2056 //printf("endOfDef at=%d\n",yyextra->yyLineNr);
2057 if (yyextra->bodyEntry)
2058 {
2059 yyextra->bodyEntry->endBodyLine = yyextra->yyLineNr-correction;
2060 yyextra->bodyEntry = 0;
2061 }
2062 newEntry(yyscanner);
2063 //yyextra->insideConstructor = FALSE;
static void newEntry(yyscan_t yyscanner)
Definition pyscanner.l:1774
2064}

References newEntry().

◆ findPackageScope()

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

Definition at line 1946 of file pyscanner.l.

1947{
1948 if (fileName.isEmpty()) return fileName;
1949 FileInfo fi(fileName.str());
1950 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:537
static QCString findPackageScopeFromPath(yyscan_t yyscanner, const QCString &path)
Definition pyscanner.l:1919
1951}

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 1919 of file pyscanner.l.

1920{
1921 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1922 auto it = yyextra->packageNameCache.find(path.str());
1923 if (it!=yyextra->packageNameCache.end())
1924 {
1925 return QCString(it->second);
1926 }
1927 FileInfo pf(path.str()+"/__init__.py"); // found package initialization file
1928 if (pf.exists())
1929 {
1930 int i=path.findRev('/');
1931 if (i!=-1)
1932 {
1933 QCString scope = findPackageScopeFromPath(yyscanner,path.left(i));
1934 if (!scope.isEmpty())
1935 {
1936 scope+="::";
1937 }
1938 scope+=path.mid(i+1);
1939 yyextra->packageNameCache.emplace(path.str(),scope.str());
1940 return scope;
1941 }
1942 }
1943 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
1944}

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 1999 of file pyscanner.l.

2000{
2001 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2002 //printf("handleCommentBlock(doc=[%s] brief=%d yyextra->docBlockInBody=%d yyextra->docBlockJavaStyle=%d\n",
2003 // qPrint(doc),brief,yyextra->docBlockInBody,yyextra->docBlockJavaStyle);
2004
2005 // TODO: Fix me
2006 yyextra->docBlockInBody=FALSE;
#define FALSE
Definition qcstring.h:34
2007
2008 if (!yyextra->current->doc.isEmpty())
2009 {
2010 yyextra->current->doc=yyextra->current->doc.stripWhiteSpace()+"\n\n";
2011 }
2012 if (yyextra->docBlockInBody && yyextra->previous && !yyextra->previous->doc.isEmpty())
2013 {
2014 yyextra->previous->doc=yyextra->previous->doc.stripWhiteSpace()+"\n\n";
2015 }
2016
2017 int position = 0;
2018 bool needsEntry = false;
2019 int lineNr = brief ? yyextra->current->briefLine : yyextra->current->docLine;
2020 Markdown markdown(yyextra->fileName,lineNr);
2021 GuardedSectionStack guards;
2022 QCString strippedDoc = stripIndentation(doc);
2023 QCString processedDoc = Config_getBool(MARKDOWN_SUPPORT) ? markdown.process(strippedDoc,lineNr) : strippedDoc;
2024 while (yyextra->commentScanner.parseCommentBlock(
2025 yyextra->thisParser,
2026 (yyextra->docBlockInBody && yyextra->previous) ? yyextra->previous.get() : yyextra->current.get(),
2027 processedDoc, // text
2028 yyextra->fileName, // file
2029 lineNr,
2030 yyextra->docBlockInBody ? FALSE : brief,
2031 yyextra->docBlockJavaStyle, // javadoc style // or FALSE,
2032 yyextra->docBlockInBody,
2033 yyextra->protection,
2034 position,
2035 needsEntry,
2036 Config_getBool(MARKDOWN_SUPPORT),
2037 &guards
2038 )
2039 ) // need to start a new entry
2040 {
2041 if (needsEntry)
2042 {
2043 newEntry(yyscanner);
2044 }
2045 }
2046 if (needsEntry)
2047 {
2048 newEntry(yyscanner);
2049 }
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:6378
2050
2051}

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

◆ incLineNr()

static void incLineNr ( yyscan_t yyscanner)
static

Definition at line 1976 of file pyscanner.l.

1977{
1978 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1979 DBG_CTX((stderr,"yyextra->yyLineNr=%d\n",yyextra->yyLineNr));
1980 yyextra->yyLineNr++;
#define DBG_CTX(x)
Definition pyscanner.l:65
1981}

References DBG_CTX.

◆ initEntry()

static void initEntry ( yyscan_t yyscanner)
static

Definition at line 1759 of file pyscanner.l.

1760{
1761 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1762 //yyextra->current->python = TRUE;
1763 yyextra->current->protection = yyextra->protection ;
1764 yyextra->current->mtype = yyextra->mtype;
1765 yyextra->current->virt = yyextra->virt;
1766 yyextra->current->isStatic = yyextra->isStatic;
1767 yyextra->current->lang = SrcLangExt::Python;
1768 yyextra->current->type.clear();
1769 yyextra->current->name.clear();
1770 yyextra->commentScanner.initGroupInfo(yyextra->current.get());
1771 yyextra->isStatic = FALSE;
@ Python
Definition types.h:52
1772}

References FALSE, and Python.

◆ initParser()

static void initParser ( yyscan_t yyscanner)
static

Definition at line 1748 of file pyscanner.l.

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

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

◆ initSpecialBlock()

static void initSpecialBlock ( yyscan_t yyscanner)
static

Definition at line 2106 of file pyscanner.l.

2107{
2108 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2109 yyextra->docBlockContext = YY_START;
2110 yyextra->docBlockInBody = FALSE;
2111 yyextra->docBlockJavaStyle = TRUE;
2112 yyextra->docBrief = TRUE;
2113 yyextra->docBlock.clear();
2114 yyextra->commentIndent = yyextra->curIndent;
2115 startCommentBlock(yyscanner,FALSE);
static void startCommentBlock(yyscan_t yyscanner, bool brief)
Definition pyscanner.l:1984
2116}

References FALSE, startCommentBlock(), and TRUE.

◆ initTriDoubleQuoteBlock()

static void initTriDoubleQuoteBlock ( yyscan_t yyscanner)
static

Definition at line 2072 of file pyscanner.l.

2073{
2074 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2075 yyextra->docBlockContext = YY_START;
2076 yyextra->docBlockInBody = FALSE;
2077 yyextra->docBlockJavaStyle = TRUE;
2078 yyextra->docBlockSpecial = yytext[strlen(yytext) - 1]=='!' || !Config_getBool(PYTHON_DOCSTRING);
2079 yyextra->docBlock.clear();
2080 yyextra->commentIndent = yyextra->curIndent;
2081 yyextra->doubleQuote = TRUE;
2082 if (yyextra->docBlockSpecial)
2083 {
2084 yyextra->docBlock.fill(' ',yyextra->indent);
2085 }
2086 startCommentBlock(yyscanner,FALSE);
2087}

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

◆ initTriSingleQuoteBlock()

static void initTriSingleQuoteBlock ( yyscan_t yyscanner)
static

Definition at line 2089 of file pyscanner.l.

2090{
2091 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2092 yyextra->docBlockContext = YY_START;
2093 yyextra->docBlockInBody = FALSE;
2094 yyextra->docBlockJavaStyle = TRUE;
2095 yyextra->docBlockSpecial = yytext[strlen(yytext) - 1]=='!' || !Config_getBool(PYTHON_DOCSTRING);
2096 yyextra->docBlock.clear();
2097 yyextra->commentIndent = yyextra->curIndent;
2098 yyextra->doubleQuote = FALSE;
2099 if (yyextra->docBlockSpecial)
2100 {
2101 yyextra->docBlock.fill(' ',yyextra->indent);
2102 }
2103 startCommentBlock(yyscanner,FALSE);
2104}

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

◆ lineCount()

static void lineCount ( yyscan_t yyscanner)
static

Definition at line 1966 of file pyscanner.l.

1967{
1968 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1969 DBG_CTX((stderr,"yyextra->yyLineNr=%d\n",yyextra->yyLineNr));
1970 for (const char *p = yytext; *p; ++p)
1971 {
1972 yyextra->yyLineNr += (*p == '\n') ;
1973 }
1974}

References DBG_CTX.

◆ newEntry()

static void newEntry ( yyscan_t yyscanner)
static

Definition at line 1774 of file pyscanner.l.

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

References found, and initEntry().

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

◆ newFunction()

static void newFunction ( yyscan_t yyscanner)
static

Definition at line 1889 of file pyscanner.l.

1890{
1891 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1892 if (yyextra->current->name.startsWith("__") && yyextra->current->name.endsWith("__"))
1893 {
1894 // special method name, see
1895 // http://docs.python.org/ref/specialnames.html
1896 yyextra->current->protection=Protection::Public;
1897 }
1898 else
1899 {
1900 setProtection(yyscanner);
1901 }
1902}

References Public, and setProtection().

◆ newVariable()

static void newVariable ( yyscan_t yyscanner)
static

Definition at line 1867 of file pyscanner.l.

1868{
1869 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1870 setProtection(yyscanner);
1871 if (yyextra->current_root->section.isCompound()) // mark as class variable
1872 {
1873 yyextra->current->isStatic = TRUE;
1874 }
1875 newEntry(yyscanner);
1876}

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

◆ parseCompounds()

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

Definition at line 2152 of file pyscanner.l.

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

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 2207 of file pyscanner.l.

2208{
2209 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2210 initParser(yyscanner);
static void initParser(yyscan_t yyscanner)
Definition pyscanner.l:1748
2211
2212 if (fileBuf==nullptr || fileBuf[0]=='\0') return;
2213
2214 yyextra->inputString = fileBuf;
2215 yyextra->inputPosition = 0;
2216
2217 yyextra->protection = Protection::Public;
2218 yyextra->mtype = MethodTypes::Method;
2219 yyextra->isStatic = false;
2220 yyextra->virt = Specifier::Normal;
2221 yyextra->current_root = rt;
2222 yyextra->specialBlock = false;
2223
2224 yyextra->yyLineNr= 1 ;
2225 yyextra->fileName = fileName;
2226 yyextra->checkDupEntry = false;
2227 //setContext();
2228 msg("Parsing file {}...\n",yyextra->fileName);
#define msg(fmt,...)
Definition message.h:94
2229
2230 FileInfo fi(fileName.str());
2231 yyextra->moduleScope = findPackageScope(yyscanner,fileName);
2232 QCString baseName=fi.baseName();
2233 if (baseName!="__init__") // package initializer file is not a package itself
2234 {
2235 if (!yyextra->moduleScope.isEmpty())
2236 {
2237 yyextra->moduleScope+="::";
2238 }
2239 yyextra->moduleScope+=baseName;
2240 }
static QCString findPackageScope(yyscan_t yyscanner, const QCString &fileName)
Definition pyscanner.l:1946
2241
2242 // add namespaces for each scope
2243 QCString scope = yyextra->moduleScope;
2244 int startPos = 0;
2245 int pos = 0;
2246 do
2247 {
2248 pos = scope.find("::",startPos);
2249 startPos=pos+2;
2250 if (pos==-1) pos=(int)scope.length();
2251 yyextra->current = std::make_shared<Entry>();
2252 initEntry(yyscanner);
2253 yyextra->current->name = scope.left(pos);
2254 yyextra->current->section = EntryType::makeNamespace();
2255 yyextra->current->type = "namespace";
2256 yyextra->current->fileName = yyextra->fileName;
2257 yyextra->current->startLine = yyextra->yyLineNr;
2258 yyextra->current->bodyLine = yyextra->yyLineNr;
2259 yyextra->current_root = yyextra->current;
2260 rt->moveToSubEntryAndRefresh(yyextra->current);
2261 } 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
2262
2263 initParser(yyscanner);
2264
2265 yyextra->commentScanner.enterFile(yyextra->fileName,yyextra->yyLineNr);
2266
2267 yyextra->current->reset();
2268 initEntry(yyscanner);
2269 pyscannerYYrestart(nullptr,yyscanner);
2270 BEGIN( Search );
2271 pyscannerYYlex(yyscanner);
2272 yyextra->lexInit=TRUE;
2273
2274 yyextra->commentScanner.leaveFile(yyextra->fileName,yyextra->yyLineNr);
2275
2276 yyextra->programStr.clear();
2277 yyextra->current_root->program.str(std::string());
2278
2279 parseCompounds(yyscanner, yyextra->current_root);
2280}

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

◆ parsePrototype()

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

Definition at line 2284 of file pyscanner.l.

2285{
2286 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2287 //printf("**** parsePrototype(%s) begin\n",qPrint(text));
2288 if (text.isEmpty())
2289 {
2290 warn(yyextra->fileName,yyextra->yyLineNr,"Empty prototype found!");
2291 return;
2292 }
#define warn(file, line, fmt,...)
Definition message.h:97
2293
2294 yyextra->specialBlock = FALSE;
2295 yyextra->packageCommentAllowed = FALSE;
2296
2297 // save scanner state
2298 YY_BUFFER_STATE orgState = YY_CURRENT_BUFFER;
2299 yy_switch_to_buffer(yy_create_buffer(nullptr, YY_BUF_SIZE, yyscanner), yyscanner);
2300 const char *orgInputString = yyextra->inputString;
2301 int orgInputPosition = yyextra->inputPosition;
#define YY_BUF_SIZE
Definition commentcnv.l:19
2302
2303 // set new string
2304 yyextra->inputString = text.data();
2305 yyextra->inputPosition = 0;
2306 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
2307
2308 BEGIN( FunctionDec );
2309
2310 pyscannerYYlex(yyscanner);
2311 yyextra->lexInit=TRUE;
2312
2313 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
2314 if (yyextra->current->section.isMemberDoc() && yyextra->current->args.isEmpty())
2315 {
2316 yyextra->current->section = EntryType::makeVariableDoc();
2317 }
2318
2319 // restore original scanner state
2320
2321 yy_delete_buffer(YY_CURRENT_BUFFER, yyscanner);
2322 yy_switch_to_buffer(orgState, yyscanner);
2323
2324 yyextra->inputString = orgInputString;
2325 yyextra->inputPosition = orgInputPosition;
2326
2327 //printf("**** parsePrototype end\n");
2328}

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

◆ searchFoundClass()

static void searchFoundClass ( yyscan_t yyscanner)
static

Definition at line 2138 of file pyscanner.l.

2139{
2140 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2141 yyextra->current->section = EntryType::makeClass();
2142 yyextra->current->argList.clear();
2143 yyextra->current->type += "class" ;
2144 yyextra->current->fileName = yyextra->fileName;
2145 yyextra->current->startLine = yyextra->yyLineNr;
2146 yyextra->current->bodyLine = yyextra->yyLineNr;
2147 yyextra->packageCommentAllowed = FALSE;
2148}

References FALSE.

◆ searchFoundDef()

static void searchFoundDef ( yyscan_t yyscanner)
static

Definition at line 2118 of file pyscanner.l.

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

References FALSE, Method, Normal, and Python.

◆ setProtection()

static void setProtection ( yyscan_t yyscanner)
static

Definition at line 1838 of file pyscanner.l.

1839{
1840 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1841 if (!yyextra->current->name.isEmpty() && yyextra->current->name.at(0)=='_')
1842 {
1843 if (yyextra->current->name.at(1)=='_') // mark as private
1844 {
1845 yyextra->current->protection=Protection::Private;
1846 }
1847 else // mark as protected
1848 {
1849 yyextra->current->protection=Protection::Protected;
1850 }
1851 }
@ Private
Definition types.h:26
@ Protected
Definition types.h:26
1852}

References Private, and Protected.

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

◆ startCommentBlock()

static void startCommentBlock ( yyscan_t yyscanner,
bool brief )
static

Definition at line 1984 of file pyscanner.l.

1985{
1986 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1987 if (brief)
1988 {
1989 yyextra->current->briefFile = yyextra->fileName;
1990 yyextra->current->briefLine = yyextra->yyLineNr;
1991 }
1992 else
1993 {
1994 yyextra->current->docFile = yyextra->fileName;
1995 yyextra->current->docLine = yyextra->yyLineNr;
1996 }
1997}

◆ 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:1904
static void searchFoundDef(yyscan_t yyscanner)
Definition pyscanner.l:2118
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:2138
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:1878
@ 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:2072
414
415 {TRISINGLEQUOTE} { // start of a comment block
416 initTriSingleQuoteBlock(yyscanner);
417 BEGIN(TripleComment);
418 }
static void initTriSingleQuoteBlock(yyscan_t yyscanner)
Definition pyscanner.l:2089
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:2106
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:1976
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:1953
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:1854
const char * qPrint(const char *s)
Definition qcstring.h:672
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 <<EOF>> { incLineNr(yyscanner);
763 newEntry(yyscanner);
764 BEGIN(SearchMemVars);
765 }
766}
767
768<FunctionBody>{
769 \n{B}/{IDENTIFIER}[^{LETTER}{DIGIT}_] {
770 DBG_CTX((stderr,"indent %d<=%d\n",computeIndent(&yytext[1]),yyextra->indent));
771 if (computeIndent(&yytext[1])<=yyextra->indent)
772 {
773 unput_string(yytext,yyleng);
774 endOfDef(yyscanner);
775 //YY_CURRENT_BUFFER->yy_at_bol=TRUE;
776 BEGIN(Search);
777 }
778 else
779 {
780 incLineNr(yyscanner);
781 yyextra->current->program << yytext;
782 }
783 }
784 \n{B}/"##" {
785 if (computeIndent(&yytext[1])<=yyextra->indent)
786 {
787 unput_string(yytext,yyleng);
788 endOfDef(yyscanner);
789 //YY_CURRENT_BUFFER->yy_at_bol=TRUE;
790 BEGIN(Search);
791 }
792 else
793 {
794 incLineNr(yyscanner);
795 yyextra->current->program << yytext;
796 }
797 }
798 <<EOF>> {
799 endOfDef(yyscanner);
800 yyterminate();
801 }
802 ^{BB}/\n { // skip empty line
803 yyextra->current->program << yytext;
804 }
805 ^{BB} { // something at indent >0
806 yyextra->current->program << yytext;
807 yyextra->curIndent = computeIndent(yytext);
808 if (yyextra->curIndent<=yyextra->indent)
809 // jumped out of the function
810 {
811 endOfDef(yyscanner,1);
812 BEGIN(Search);
813 }
814 }
815 "'" { // start of a single quoted string
816 yyextra->current->program << yytext;
817 yyextra->stringContext=YY_START;
818 yyextra->specialBlock = FALSE;
819 yyextra->copyString=&yyextra->current->program;
820 BEGIN( SingleQuoteString );
821 }
822 "\"" { // start of a double quoted string
823 yyextra->current->program << yytext;
824 yyextra->stringContext=YY_START;
825 yyextra->specialBlock = FALSE;
826 yyextra->copyString=&yyextra->current->program;
827 BEGIN( DoubleQuoteString );
828 }
829 [^ \t\n#'".]+ { // non-special stuff
830 yyextra->current->program << yytext;
831 yyextra->specialBlock = FALSE;
832 }
833 ^{POUNDCOMMENT} { // normal comment
834 yyextra->current->program << yytext;
835 }
836 "#".* { // comment half way
837 yyextra->current->program << yytext;
838 }
839 {NEWLINE} {
840 incLineNr(yyscanner);
841 yyextra->current->program << yytext;
842 }
843 . { // any character
844 yyextra->current->program << *yytext;
845 yyextra->specialBlock = FALSE;
846 }
#define yyterminate()
const int DIGIT
RegularExpression Id.
const int LETTER
RegularExpression Id.
static void endOfDef(yyscan_t yyscanner, int correction=0)
Definition pyscanner.l:2053
#define unput_string(yytext, yyleng)
Definition pyscanner.l:70
847
848 {TRIDOUBLEQUOTE} { // start of a comment block
849 yyextra->current->program << yytext;
850 initTriDoubleQuoteBlock(yyscanner);
851 BEGIN(TripleComment);
852 }
853
854 {TRISINGLEQUOTE} { // start of a comment block
855 yyextra->current->program << yytext;
856 initTriSingleQuoteBlock(yyscanner);
857 BEGIN(TripleComment);
858 }
859
860}
861
862<FunctionDec>{
863 {IDENTIFIER} {
864 //found function name
865 yyextra->current->name = yytext;
866 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
867 newFunction(yyscanner);
868 }
869 {B}":"{B} { // function without arguments
870 yyextra->specialBlock = TRUE; // expecting a docstring
871 yyextra->bodyEntry = yyextra->current;
872 yyextra->current->bodyLine = yyextra->yyLineNr;
873 BEGIN(FunctionBody);
874 }
static void newFunction(yyscan_t yyscanner)
Definition pyscanner.l:1889
875
876 "->" {
877 yyextra->defVal.str(std::string());
878 yyextra->braceCount = 0;
879 BEGIN(FunctionTypeAnnotation);
880 }
881 {B}"(" {
882 yyextra->funcParamsEnd = FALSE;
883 yyextra->current->bodyLine = yyextra->yyLineNr;
884 BEGIN(FunctionParams);
885 }
886 ")" { // end of parameter list
887 if (yyextra->current->argList.empty())
888 {
889 yyextra->current->argList.setNoParameters(TRUE);
890 }
891 yyextra->current->args = argListToString(yyextra->current->argList);
892 yyextra->funcParamsEnd = TRUE;
893 }
QCString argListToString(const ArgumentList &al, bool useCanonicalType, bool showDefVals)
Definition util.cpp:1174
894}
895
896<FunctionParams>{
897 {BB} {
898 }
899
900 "," {
901 if (!yyextra->argType.isEmpty())
902 {
903 Argument a;
904 a.name = "";
905 a.type = yyextra->argType;
906 yyextra->current->argList.push_back(a);
907 yyextra->argType = "";
908 }
909 }
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
910
911 [\*]+ {
912 yyextra->argType = yytext;
913 }
914 {IDENTIFIER} { // Name of parameter
915 lineCount(yyscanner);
916 Argument a;
917 a.name = QCString(yytext).stripWhiteSpace();
918 a.type = yyextra->argType;
919 yyextra->current->argList.push_back(a);
920 yyextra->argType = "";
921 }
922 "=" { // default value
923 // TODO: this rule is too simple, need to be able to
924 // match things like =")" as well!
925 yyextra->defVal.str(std::string());
926 yyextra->braceCount = 0;
927 BEGIN(FunctionParamDefVal);
928 }
929 ")" {
930 if (!yyextra->argType.isEmpty())
931 {
932 Argument a;
933 a.name = "";
934 a.type = yyextra->argType;
935 yyextra->current->argList.push_back(a);
936 yyextra->argType = "";
937 }
938 unput(*yytext);
939 BEGIN(FunctionDec);
940 }
941 ":"{B} {
942 yyextra->defVal.str(std::string());
943 yyextra->braceCount = 0;
944 BEGIN(FunctionAnnotation);
945 }
946 {POUNDCOMMENT} { // a comment
947 }
948 {PARAMNONEMPTY} { // Default rule inside arguments.
949 }
950
951}
952
953<FunctionTypeAnnotation>{
954 "{" |
955 "[" |
956 "(" {
957 ++yyextra->braceCount;
958 yyextra->defVal << *yytext;
959 }
960 "}" |
961 "]" |
962 ")" {
963 --yyextra->braceCount;
964 yyextra->defVal << *yytext;
965 }
966 ":" {
967 if (yyextra->braceCount == 0)
968 {
969 yyextra->current->type = yyextra->defVal.str();
970 unput(*yytext);
971 BEGIN(FunctionDec);
972 }
973 else
974 yyextra->defVal << *yytext;
975 }
976 "'" {
977 yyextra->defVal << *yytext;
978 yyextra->copyString=&yyextra->defVal;
979 yyextra->stringContext=FunctionTypeAnnotation;
980 BEGIN(SingleQuoteString);
981 }
982 "\"" {
983 yyextra->defVal << *yytext;
984 yyextra->copyString=&yyextra->defVal;
985 yyextra->stringContext=FunctionTypeAnnotation;
986 BEGIN(DoubleQuoteString);
987 }
988 \n {
989 yyextra->defVal << *yytext;
990 incLineNr(yyscanner);
991 }
992 . {
993 yyextra->defVal << *yytext;
994 }
995}
996
997<FunctionAnnotation>{
998 "{" |
999 "[" |
1000 "(" {
1001 ++yyextra->braceCount;
1002 yyextra->defVal << *yytext;
1003 }
1004 "}" |
1005 "]" {
1006 --yyextra->braceCount;
1007 yyextra->defVal << *yytext;
1008 }
1009 ")" |
1010 "=" |
1011 "," {
1012 if (yyextra->braceCount == 0)
1013 {
1014 if (!yyextra->current->argList.empty())
1015 yyextra->current->argList.back().type += yyextra->defVal.str();
1016 if (*yytext != ',')
1017 unput(*yytext);
1018 BEGIN(FunctionParams);
1019 }
1020 else
1021 {
1022 if (*yytext == ')')
1023 --yyextra->braceCount;
1024 yyextra->defVal << *yytext;
1025 }
1026 }
1027 "'" {
1028 yyextra->defVal << *yytext;
1029 yyextra->copyString=&yyextra->defVal;
1030 yyextra->stringContext=FunctionAnnotation;
1031 BEGIN(SingleQuoteString);
1032 }
1033 "\"" {
1034 yyextra->defVal << *yytext;
1035 yyextra->copyString=&yyextra->defVal;
1036 yyextra->stringContext=FunctionAnnotation;
1037 BEGIN(DoubleQuoteString);
1038 }
1039 \n {
1040 yyextra->defVal << *yytext;
1041 incLineNr(yyscanner);
1042 }
1043 . {
1044 yyextra->defVal << *yytext;
1045 }
1046}
1047
1048<FunctionParamDefVal>{
1049 "{" |
1050 "[" |
1051 "(" { // internal opening brace, assumption is that we have correct code so braces do match
1052 ++yyextra->braceCount;
1053 yyextra->defVal << *yytext;
1054 }
1055 "}" |
1056 "]" {
1057 --yyextra->braceCount;
1058 yyextra->defVal << *yytext;
1059 }
1060 ")" |
1061 "," {
1062 if (yyextra->braceCount == 0)
1063 {
1064 if (!yyextra->current->argList.empty())
1065 yyextra->current->argList.back().defval=QCString(yyextra->defVal.str()).stripWhiteSpace();
1066 if (*yytext == ')')
1067 unput(*yytext);
1068 BEGIN(FunctionParams);
1069 }
1070 else
1071 {
1072 if (*yytext == ')')
1073 --yyextra->braceCount;
1074 yyextra->defVal << *yytext;
1075 }
1076 }
1077
1078 "'" {
1079 yyextra->defVal << *yytext;
1080 yyextra->copyString=&yyextra->defVal;
1081 yyextra->stringContext=FunctionParamDefVal;
1082 BEGIN( SingleQuoteString );
1083 }
1084 "\"" {
1085 yyextra->defVal << *yytext;
1086 yyextra->copyString=&yyextra->defVal;
1087 yyextra->stringContext=FunctionParamDefVal;
1088 BEGIN( DoubleQuoteString );
1089 }
1090 \n {
1091 yyextra->defVal << *yytext;
1092 incLineNr(yyscanner);
1093 }
1094 . {
1095 yyextra->defVal << *yytext;
1096 }
1097}
1098
1099
1100<ClassBody>{
1101 \n/{IDENTIFIER}{BB} { // new def at indent 0
1102 if (computeIndent(&yytext[1])<=yyextra->indent)
1103 {
1104 int i;
1105 for (i=(int)yyleng-1;i>=0;i--)
1106 {
1107 unput(yytext[i]);
1108 }
1109 endOfDef(yyscanner);
1110 //YY_CURRENT_BUFFER->yy_at_bol=TRUE;
1111 BEGIN(Search);
1112 }
1113 else
1114 {
1115 incLineNr(yyscanner);
1116 yyextra->current->program << yytext;
1117 }
1118 }
1119 \n/"##"[^#] { // start of a special comment at indent 0
1120 if (computeIndent(&yytext[1])<=yyextra->indent)
1121 {
1122 int i;
1123 for (i=(int)yyleng-1;i>=0;i--)
1124 {
1125 unput(yytext[i]);
1126 }
1127 endOfDef(yyscanner);
1128 //YY_CURRENT_BUFFER->yy_at_bol=TRUE;
1129 BEGIN(Search);
1130 }
1131 else
1132 {
1133 incLineNr(yyscanner);
1134 yyextra->current->program << yytext;
1135 }
1136 }
1137 ^{BB}/\n { // skip empty line
1138 yyextra->current->program << yytext;
1139 }
1140 <<EOF>> {
1141 endOfDef(yyscanner);
1142 yyterminate();
1143 }
1144 ^{BB} { // something at indent >0
1145 yyextra->curIndent=computeIndent(yytext);
1146 DBG_CTX((stderr,"yyextra->curIndent=%d yyextra->indent=%d\n",yyextra->curIndent,yyextra->indent));
1147 if (yyextra->curIndent<=yyextra->indent)
1148 // jumped out of the class/method
1149 {
1150 endOfDef(yyscanner,1);
1151 yyextra->indent=yyextra->curIndent;
1152 // make sure the next rule matches ^...
1153 //YY_CURRENT_BUFFER->yy_at_bol=TRUE;
1154 //yyextra->hideClassDocs = FALSE;
1155 BEGIN(Search);
1156 }
1157 else
1158 {
1159 yyextra->current->program << yytext;
1160 }
1161 }
1162 "'" { // start of a single quoted string
1163 yyextra->current->program << *yytext;
1164 yyextra->stringContext=YY_START;
1165 yyextra->specialBlock = FALSE;
1166 yyextra->copyString=&yyextra->current->program;
1167 BEGIN( SingleQuoteString );
1168 }
1169 "\"" { // start of a double quoted string
1170 yyextra->current->program << *yytext;
1171 yyextra->stringContext=YY_START;
1172 yyextra->specialBlock = FALSE;
1173 yyextra->copyString=&yyextra->current->program;
1174 BEGIN( DoubleQuoteString );
1175 }
1176 [^ \t\n#'"]+ { // non-special stuff
1177 yyextra->current->program << yytext;
1178 yyextra->specialBlock = FALSE;
1179 //yyextra->hideClassDocs = FALSE;
1180 }
1181 {NEWLINE} {
1182 yyextra->current->program << *yytext;
1183 incLineNr(yyscanner);
1184 }
1185 {POUNDCOMMENT} { // normal comment
1186 yyextra->current->program << yytext;
1187 }
1188 . { // any character
1189 yyextra->specialBlock = FALSE;
1190 yyextra->current->program << *yytext;
1191 }
1192 {TRIDOUBLEQUOTE} { // start of a comment block
1193 //if (!yyextra->hideClassDocs)
1194 yyextra->current->program << yytext;
1195 initTriDoubleQuoteBlock(yyscanner);
1196 BEGIN(TripleComment);
1197 }
1198
1199 {TRISINGLEQUOTE} { // start of a comment block
1200 //if (!yyextra->hideClassDocs)
1201 yyextra->current->program << yytext;
1202 initTriSingleQuoteBlock(yyscanner);
1203 BEGIN(TripleComment);
1204 }
1205}
1206
1207<ClassDec>{IDENTIFIER} {
1208 if (yyextra->current->type.isEmpty())
1209 {
1210 yyextra->current->type = "class";
1211 }
1212
1213 yyextra->current->section = EntryType::makeClass();
1214 yyextra->current->name = yytext;
1215 // we need to set the protectiion based on the "local" class name
1216 setProtection(yyscanner);
1217
1218 // prepend scope in case of nested classes
1219 if (yyextra->current_root->section.isScope())
1220 {
1221 //printf("*** Prepending scope %s to class %s\n",qPrint(yyextra->current_root->name),qPrint(yyextra->current->name));
1222 yyextra->current->name.prepend(yyextra->current_root->name+"::");
1223 }
1224
1225 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
1226 yyextra->current->fileName = yyextra->fileName;
1227 yyextra->docBlockContext = YY_START;
1228 yyextra->docBlockInBody = FALSE;
1229 yyextra->docBlockJavaStyle = FALSE;
1230 yyextra->docBlock.clear();
1231
1232 BEGIN(ClassInheritance);
1233 }
1234
1235<ClassInheritance>{
1236 ({BB}|[\‍(,\‍)]) { // syntactic sugar for the list
1237 }
1238
1239 ":" { // begin of the class definition
1240 yyextra->specialBlock = TRUE; // expecting a docstring
1241 yyextra->current->bodyLine = yyextra->yyLineNr;
1242 yyextra->current->program.str(std::string());
1243 BEGIN(ClassCaptureIndent);
1244 }
1245
1246 {SCOPE} {
1247 yyextra->current->extends.emplace_back(
1249 );
1250 //Has base class-do stuff
1251 }
1252 "'" { // start of a single quoted string
1253 yyextra->stringContext=YY_START;
1254 BEGIN( SingleQuoteStringIgnore );
1255 }
1256 "\"" { // start of a double quoted string
1257 yyextra->stringContext=YY_START;
1258 BEGIN( DoubleQuoteStringIgnore );
1259 }
1260}
1261
1262<SingleQuoteStringIgnore>{
1263 "'" { // end of a single quoted string
1264 BEGIN(yyextra->stringContext);
1265 }
1266 . { }
1267}
1268<DoubleQuoteStringIgnore>{
1269 "\"" { // end of a double quoted string
1270 BEGIN(yyextra->stringContext);
1271 }
1272 . { }
1273}
1274
1275<ClassCaptureIndent>{
1276 "\n"|({BB}"\n") {
1277 // Blankline - ignore, keep looking for indentation.
1278 lineCount(yyscanner);
1279 yyextra->current->program << yytext;
1280 }
1281
1282 {TRIDOUBLEQUOTE} { // start of a comment block
1283 initTriDoubleQuoteBlock(yyscanner);
1284 yyextra->current->program << yytext;
1285 BEGIN(TripleComment);
1286 }
1287 {TRISINGLEQUOTE} { // start of a comment block
1288 initTriSingleQuoteBlock(yyscanner);
1289 yyextra->current->program << yytext;
1290 BEGIN(TripleComment);
1291 }
1292 {STARTDOCSYMS}[#]* { // start of a special comment
1293 initSpecialBlock(yyscanner);
1294 BEGIN(SpecialComment);
1295 }
1296 {POUNDCOMMENT} { // ignore comment with just one #
1297 }
1298 ^{BB} {
1299 yyextra->current->program << yytext;
1300 //yyextra->current->startLine = yyextra->yyLineNr;
1301 yyextra->curIndent=computeIndent(yytext);
1302 yyextra->bodyEntry = yyextra->current;
1303 DBG_CTX((stderr,"setting indent %d\n",yyextra->curIndent));
1304 //printf("yyextra->current->program=[%s]\n",qPrint(yyextra->current->program));
1305 //yyextra->hideClassDocs = TRUE;
1306 BEGIN(ClassBody);
1307 }
1308
1309 ""/({NONEMPTY}|{EXPCHAR}) {
1310 // Just pushback an empty class, and
1311 // resume parsing the body.
1312 newEntry(yyscanner);
1313 yyextra->current->program << yytext;
1314
1315 // printf("Failed to find indent - skipping!");
1316 BEGIN( Search );
1317 }
1318}
1319
1320
1321<VariableDec>{
1322 ":"{B}{IDENTIFIER} { //typing
1323 yyextra->startInit = FALSE;
1324 yyextra->current->type = substitute(yytext,":","");
1325 }
1326 {STARTDOCSYMS}"<"/.* { // start of a special comment
1327 yyextra->curIndent=computeIndent(yytext);
1328 yyextra->packageCommentAllowed = FALSE;
1329 initSpecialBlock(yyscanner);
1330 yyextra->docBlockContext = VariableEnd;
1331 BEGIN(SpecialComment);
1332 }
1333 "#".* { // comment
1334 BEGIN( VariableEnd );
1335 }
1336 \n {
1337 unput('\n');
1338 BEGIN( VariableEnd );
1339 }
1340}
1341
1342<VariableAtom>{
1343 [\‍(\[\{] {
1344 yyextra->current->initializer << *yytext;
1345 if (yyextra->atomStart==*yytext)
1346 {
1347 yyextra->atomCount++;
1348 }
1349 }
1350 [\‍)\]\}] {
1351 yyextra->current->initializer << *yytext;
1352 if (yyextra->atomEnd==*yytext)
1353 {
1354 yyextra->atomCount--;
1355 }
1356 if (yyextra->atomCount==0)
1357 {
1358 yyextra->startInit = FALSE;
1359 BEGIN(yyextra->atomContext);
1360 }
1361 }
1362 {TRIDOUBLEQUOTE} { // start of a comment block
1363 yyextra->specialBlock = FALSE;
1364 yyextra->current->program << yytext;
1365 initTriDoubleQuoteBlock(yyscanner);
1366 BEGIN(TripleComment);
1367 }
1368
1369 {TRISINGLEQUOTE} { // start of a comment block
1370 yyextra->specialBlock = FALSE;
1371 yyextra->current->program << yytext;
1372 initTriSingleQuoteBlock(yyscanner);
1373 BEGIN(TripleComment);
1374 }
1375 "'" {
1376 yyextra->stringContext=YY_START;
1377 yyextra->current->initializer << "'";
1378 yyextra->copyString=&yyextra->current->initializer;
1379 BEGIN( SingleQuoteString );
1380 }
1381 "\"" {
1382 yyextra->stringContext=YY_START;
1383 yyextra->current->initializer << "\"";
1384 yyextra->copyString=&yyextra->current->initializer;
1385 BEGIN( DoubleQuoteString );
1386 }
1387 {IDENTIFIER} {
1388 yyextra->current->initializer << yytext;
1389 }
1390 . {
1391 yyextra->current->initializer << *yytext;
1392 }
1393 \n {
1394 yyextra->current->initializer << *yytext;
1395 incLineNr(yyscanner);
1396 }
1397
1398}
1399
1400<VariableEnd>{
1401 \n {
1402 incLineNr(yyscanner);
1403 if (!stripWhiteSpace(yyextra->current->initializer.str()).empty())
1404 {
1405 newVariable(yyscanner);
1406 }
1407 BEGIN(Search);
1408 }
1409 . {
1410 unput(*yytext);
1411 newVariable(yyscanner);
1412 BEGIN(Search);
1413 }
1414 <<EOF>> { yyterminate();
1415 }
static void newVariable(yyscan_t yyscanner)
Definition pyscanner.l:1867
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
1416}
1417
1418<TripleComment>{
1419 {ENDTRIDOUBLEQUOTE} |
1420 {ENDTRISINGLEQUOTE} {
1421 // printf("Expected module block %d special=%d\n",yyextra->expectModuleDocs,yyextra->specialBlock);
1422 if (yyextra->doubleQuote==(yytext[0]=='"'))
1423 {
1424 if (yyextra->specialBlock) // expecting a docstring
1425 {
1426 QCString actualDoc=yyextra->docBlock;
1427 if (!yyextra->docBlockSpecial) // legacy unformatted docstring
1428 {
1429 if (!actualDoc.isEmpty())
1430 {
1431 stripIndentationVerbatim(actualDoc,yyextra->commentIndent);
1432 actualDoc.prepend("@iverbatim\n");
1433 actualDoc.append("@endiverbatim ");
1434 }
1435 }
1436 //printf("-------> yyextra->current=%p yyextra->bodyEntry=%p\n",yyextra->current,yyextra->bodyEntry);
1437 handleCommentBlock(yyscanner, actualDoc, FALSE);
1438 }
1439 else if (yyextra->packageCommentAllowed) // expecting module docs
1440 {
1441 QCString actualDoc=yyextra->docBlock;
1442 if (!yyextra->docBlockSpecial) // legacy unformatted docstring
1443 {
1444 if (!actualDoc.isEmpty())
1445 {
1446 stripIndentationVerbatim(actualDoc,yyextra->commentIndent);
1447 actualDoc.prepend("@iverbatim\n");
1448 actualDoc.append("@endiverbatim ");
1449 }
1450 }
1451 if (yyextra->moduleScope.startsWith("__") && yyextra->moduleScope.endsWith("__"))
1452 {
1453 actualDoc.prepend("\\namespace \\"+yyextra->moduleScope+" ");
1454 }
1455 else
1456 {
1457 actualDoc.prepend("\\namespace "+yyextra->moduleScope+" ");
1458 }
1459 handleCommentBlock(yyscanner, actualDoc, FALSE);
1460 }
1461 if ((yyextra->docBlockContext==ClassBody /*&& !yyextra->hideClassDocs*/) ||
1462 yyextra->docBlockContext==FunctionBody)
1463 {
1464 yyextra->current->program << yyextra->docBlock;
1465 yyextra->current->program << yytext;
1466 }
1467 //if (yyextra->hideClassDocs)
1468 //{
1469 // yyextra->current->startLine = yyextra->yyLineNr;
1470 //}
1471 //yyextra->hideClassDocs=FALSE;
1472 BEGIN(yyextra->docBlockContext);
1473 }
1474 else
1475 {
1476 yyextra->docBlock += yytext;
1477 }
1478 yyextra->packageCommentAllowed = FALSE;
1479 }
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:1999
void stripIndentationVerbatim(QCString &doc, const int indentationLevel)
Definition util.cpp:6463
1480
1481
1482 ^{BB} { // leading whitespace, compensate for """! / '''!
1483 if (yyextra->docBlockSpecial && yyleng >= yyextra->curIndent)
1484 yyextra->docBlock += yytext + yyextra->curIndent;
1485 else
1486 yyextra->docBlock += yytext;
1487 }
1488 [^"'\n \t\\@]+ {
1489 yyextra->docBlock += yytext;
1490 }
1491 \n {
1492 incLineNr(yyscanner);
1493 yyextra->docBlock += yytext;
1494 }
1495 {CMD}"ifile"{B}+"\""[^\n\"]+"\"" {
1496 yyextra->fileName = &yytext[6];
1497 yyextra->fileName = yyextra->fileName.stripWhiteSpace();
1498 yyextra->fileName = yyextra->fileName.mid(1,yyextra->fileName.length()-2);
1499 yyextra->docBlock+=yytext;
1500 }
1501 {CMD}"ifile"{B}+{FILEMASK} {
1502 yyextra->fileName = &yytext[6];
1503 yyextra->fileName = yyextra->fileName.stripWhiteSpace();
1504 yyextra->docBlock+=yytext;
1505 }
1506 {CMD}"iline"{LINENR}/[\n\.] |
1507 {CMD}"iline"{LINENR}{B} {
1508 bool ok = false;
1509 int nr = QCString(&yytext[6]).toInt(&ok);
1510 if (!ok)
1511 {
1512 warn(yyextra->fileName,yyextra->yyLineNr,"Invalid line number '{}' for iline command",yytext);
1513 }
1514 else
1515 {
1516 yyextra->yyLineNr = nr;
1517 }
1518 yyextra->docBlock+=yytext;
1519 }
1520 ({CMD}{CMD}){ID}/[^a-z_A-Z0-9] { // escaped command
1521 yyextra->docBlock+=yytext;
1522 }
1523 \\. { // escaped char TO be extended
1524 yyextra->docBlock += yytext;
1525 }
1526 . {
1527 yyextra->docBlock += yytext;
1528 }
int toInt(bool *ok=nullptr, int base=10) const
Definition qcstring.cpp:249
1529}
1530
1531<SpecialComment>{
1532 ^{B}"#"("#")* { // skip leading hashes
1533 }
1534 \n/{B}"#" { // continuation of the comment on the next line
1535 yyextra->docBlock+='\n';
1536 yyextra->docBrief = FALSE;
1537 incLineNr(yyscanner);
1538 }
1539 {CMD}"ifile"{B}+"\""[^\n\"]+"\"" {
1540 yyextra->fileName = &yytext[6];
1541 yyextra->fileName = yyextra->fileName.stripWhiteSpace();
1542 yyextra->fileName = yyextra->fileName.mid(1,yyextra->fileName.length()-2);
1543 yyextra->docBlock+=yytext;
1544 }
1545 {CMD}"ifile"{B}+{FILEMASK} {
1546 yyextra->fileName = &yytext[6];
1547 yyextra->fileName = yyextra->fileName.stripWhiteSpace();
1548 yyextra->docBlock+=yytext;
1549 }
1550 {CMD}"iline"{LINENR}/[\n\.] |
1551 {CMD}"iline"{LINENR}{B} {
1552 bool ok = false;
1553 int nr = QCString(&yytext[6]).toInt(&ok);
1554 if (!ok)
1555 {
1556 warn(yyextra->fileName,yyextra->yyLineNr,"Invalid line number '{}' for iline command",yytext);
1557 }
1558 else
1559 {
1560 yyextra->yyLineNr = nr;
1561 }
1562 yyextra->docBlock+=yytext;
1563 }
1564 ({CMD}{CMD}){ID}/[^a-z_A-Z0-9] { // escaped command
1565 yyextra->docBlock+=yytext;
1566 }
1567 "\\ilinebr "{B}* {
1568 QCString indent;
1569 int extraSpaces = std::max(0,static_cast<int>(yyleng-9-yyextra->curIndent-2));
1570 indent.fill(' ',extraSpaces);
1571 //printf("extraSpaces=%d\n",extraSpaces);
1572 yyextra->docBlock += "\\ilinebr ";
1573 yyextra->docBlock += indent;
1574 }
1575 [^#\\@\n]+ { // any other stuff
1576 yyextra->docBlock+=yytext;
1577 }
1578 \n { // new line that ends the comment
1579 handleCommentBlock(yyscanner, yyextra->docBlock, yyextra->docBrief);
1580 if (yyextra->docBlockContext == VariableEnd)
1581 {
1582 unput(*yytext);
1583 }
1584 else
1585 {
1586 incLineNr(yyscanner);
1587 }
1588 BEGIN(yyextra->docBlockContext);
1589 }
1590 . { // anything we missed
1591 yyextra->docBlock+=*yytext;
1592 }
void fill(char c, int len=-1)
Fills a string with a predefined character.
Definition qcstring.h:180
1593}
1594
1595<SingleQuoteString>{
1596 \\{B}\n { // line continuation
1597 addToString(yyscanner,yytext);
1598 incLineNr(yyscanner);
1599 }
1600 \\. { // escaped char
1601 addToString(yyscanner,yytext);
1602 }
1603 "\"\"\"" { // triple double quotes
1604 addToString(yyscanner,yytext);
1605 }
1606 "'" { // end of the string
1607 addToString(yyscanner,yytext);
1608 BEGIN(yyextra->stringContext);
1609 }
1610 [^"'\n\\]+ { // normal chars
1611 addToString(yyscanner,yytext);
1612 }
1613 . { // normal char
1614 addToString(yyscanner,yytext);
1615 }
static void addToString(yyscan_t yyscanner, const char *s)
Definition pyscanner.l:2066
1616}
1617
1618<DoubleQuoteString>{
1619 \\{B}\n { // line continuation
1620 addToString(yyscanner,yytext);
1621 incLineNr(yyscanner);
1622 }
1623 \\. { // escaped char
1624 addToString(yyscanner,yytext);
1625 }
1626 "'''" { // triple single quotes
1627 addToString(yyscanner,yytext);
1628 }
1629 "\"" { // end of the string
1630 addToString(yyscanner,yytext);
1631 BEGIN(yyextra->stringContext);
1632 }
1633 [^"'\n\\]+ { // normal chars
1634 addToString(yyscanner,yytext);
1635 }
1636 . { // normal char
1637 addToString(yyscanner,yytext);
1638 }
1639}
1640
1641<TripleString>{
1642 {ENDTRIDOUBLEQUOTE} |
1643 {ENDTRISINGLEQUOTE} {
1644 *yyextra->copyString << yytext;
1645 if (yyextra->doubleQuote==(yytext[0]=='"'))
1646 {
1647 BEGIN(yyextra->stringContext);
1648 }
1649 }
1650
1651
1652 ({LONGSTRINGBLOCK}) {
1653 lineCount(yyscanner);
1654 *yyextra->copyString << yytext;
1655 }
1656 \n {
1657 incLineNr(yyscanner);
1658 *yyextra->copyString << yytext;
1659 }
1660 . {
1661 *yyextra->copyString << *yytext;
1662 }
1663}
1664
1665<Decorator>{
1666 {TRIDOUBLEQUOTE} { // start of a comment block
1667 yyextra->doubleQuote=TRUE;
1668 yyextra->decoratorCommentStr.str(std::string());
1669 yyextra->copyString=&yyextra->decoratorCommentStr;
1670 yyextra->stringContext=YY_START;
1671 BEGIN(TripleString);
1672 }
1673
1674 {TRISINGLEQUOTE} { // start of a comment block
1675 yyextra->doubleQuote=FALSE;
1676 yyextra->decoratorCommentStr.str(std::string());
1677 yyextra->copyString=&yyextra->decoratorCommentStr;
1678 yyextra->stringContext=YY_START;
1679 BEGIN(TripleString);
1680 }
1681 "'" {
1682 yyextra->stringContext=YY_START;
1683 yyextra->decoratorCommentStr.str(std::string());
1684 yyextra->copyString=&yyextra->decoratorCommentStr;
1685 BEGIN( SingleQuoteString );
1686 }
1687 "\"" {
1688 yyextra->stringContext=YY_START;
1689 yyextra->decoratorCommentStr.str(std::string());
1690 yyextra->copyString=&yyextra->decoratorCommentStr;
1691 BEGIN( DoubleQuoteString );
1692 }
1693 "(" {
1694 yyextra->decoratorRound++;
1695 }
1696 ")" {
1697 yyextra->decoratorRound--;
1698 if (!yyextra->decoratorRound) BEGIN( Search );
1699 }
1700 \n {
1701 incLineNr(yyscanner);
1702 }
1703 . { }
1704}
1705
1706 /* ------------ End rules -------------- */
1707
1708 /*
1709<*>({NONEMPTY}|{EXPCHAR}|{BB}) { // This should go one character at a time.
1710 // printf("[pyscanner] '%s' [ state %d ] [line %d] no match\n",
1711 // yytext, YY_START, yyextra->yyLineNr);
1712
1713 }
1714 */
1715
1716<*>{NEWLINE} {
1717 //printf("[pyscanner] %d NEWLINE [line %d] no match\n",
1718 // YY_START, yyextra->yyLineNr);
1719
1720 lineCount(yyscanner);
1721 }
1722
1723<*>"'" {
1724 //fprintf(stderr,"Quote: %d\n",YY_START);
1725 }
1726
1727<*>. {
1728 //printf("[pyscanner] '%s' [ state %d ] [line %d] no match\n",
1729 // yytext, YY_START, yyextra->yyLineNr);
1730
1731 }
1732
1733
1734%%

◆ yyread()

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

Definition at line 1738 of file pyscanner.l.

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