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 newTypeAlias (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 void searchFoundTypeAlias (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:3982

Definition at line 166 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()

void addEntry ( yyscan_t yyscanner)
static

Definition at line 1915 of file pyscanner.l.

1916{
1917 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1918
1919 auto doc = yyextra->current->doc;
1920 auto docLine = yyextra->current->docLine;
1921 auto docFile = yyextra->current->docFile;
1922 auto brief = yyextra->current->brief;
1923 auto briefLine = yyextra->current->briefLine;
1924 auto briefFile = yyextra->current->briefFile;
1925
1926 yyextra->previous = yyextra->current;
1927 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
1928 initEntry(yyscanner);
static void initEntry(yyscan_t yyscanner)
Definition pyscanner.l:1853
1929
1930 yyextra->current->doc = doc;
1931 yyextra->current->docLine = docLine;
1932 yyextra->current->docFile = docFile;
1933 yyextra->current->brief = brief;
1934 yyextra->current->briefLine = briefLine;
1935 yyextra->current->briefFile = briefFile;
1936}

◆ addFrom()

void addFrom ( yyscan_t yyscanner,
bool all )
static

Definition at line 2060 of file pyscanner.l.

2061{
2062 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2063 QCString item=all ? yyextra->packageName : yyextra->packageName+"."+yytext;
2064 yyextra->current->name=removeRedundantWhiteSpace(substitute(item,".","::"));
2065 yyextra->current->fileName = yyextra->fileName;
2066 //printf("Adding using declaration: found:%s:%d name=%s\n",qPrint(yyextra->fileName),yyextra->yyLineNr,qPrint(yyextra->current->name));
2067 yyextra->current->section=all ? EntryType::makeUsingDir() : EntryType::makeUsingDecl();
2068 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
2069 initEntry(yyscanner);
Wrapper class for the Entry type.
Definition types.h:816
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:571
QCString removeRedundantWhiteSpace(const QCString &s)
Definition util.cpp:568
2070}

References initEntry().

◆ addToString()

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

Definition at line 2174 of file pyscanner.l.

2175{
2176 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2177 if (yyextra->copyString) (*yyextra->copyString) << s;
2178}

◆ addVariable()

void addVariable ( yyscan_t yyscanner)
static

Definition at line 1985 of file pyscanner.l.

1986{
1987 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1988 setProtection(yyscanner);
1989 if (yyextra->current_root->section.isCompound()) // mark as class variable
1990 {
1991 yyextra->current->isStatic = TRUE;
1992 }
1993 addEntry(yyscanner);
static void setProtection(yyscan_t yyscanner)
Definition pyscanner.l:1938
static void addEntry(yyscan_t yyscanner)
Definition pyscanner.l:1915
#define TRUE
Definition qcstring.h:37
1994}

References TRUE.

◆ computeIndent()

int computeIndent ( const char * s)
inlinestatic

Definition at line 2011 of file pyscanner.l.

2012{
2013 int col=0;
2014 int tabSize=Config_getInt(TAB_SIZE);
2015 const char *p=s;
2016 char c;
2017 while ((c=*p++))
2018 {
2019 if (c==' ') col++;
2020 else if (c=='\t') col+=tabSize-(col%tabSize);
2021 else break;
2022 }
2023 return col;
#define Config_getInt(name)
Definition config.h:34
2024}

◆ docVariable()

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

Definition at line 1954 of file pyscanner.l.

1955{
1956 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1957 yyextra->current->name = name;
1958 yyextra->current->section=EntryType::makeVariable();
1959 yyextra->current->fileName = yyextra->fileName;
1960 yyextra->current->startLine = yyextra->yyLineNr;
1961 yyextra->current->bodyLine = yyextra->yyLineNr;
1962 yyextra->current->type.clear();
1963 setProtection(yyscanner);
1964 yyextra->checkDupEntry = true;
1965}

◆ endOfDef()

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

Definition at line 2161 of file pyscanner.l.

2162{
2163 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2164 //printf("endOfDef at=%d\n",yyextra->yyLineNr);
2165 if (yyextra->bodyEntry)
2166 {
2167 yyextra->bodyEntry->endBodyLine = yyextra->yyLineNr-correction;
2168 yyextra->bodyEntry = 0;
2169 }
2170 newEntry(yyscanner);
2171 //yyextra->insideConstructor = FALSE;
static void newEntry(yyscan_t yyscanner)
Definition pyscanner.l:1869
2172}

◆ findPackageScope()

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

Definition at line 2053 of file pyscanner.l.

2054{
2055 if (fileName.isEmpty()) return fileName;
2056 FileInfo fi(fileName.str());
2057 return findPackageScopeFromPath(yyscanner,fi.dirPath(true));
Minimal replacement for QFileInfo.
Definition fileinfo.h:23
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:163
const std::string & str() const
Definition qcstring.h:552
static QCString findPackageScopeFromPath(yyscan_t yyscanner, const QCString &path)
Definition pyscanner.l:2026
2058}

◆ findPackageScopeFromPath()

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

Definition at line 2026 of file pyscanner.l.

2027{
2028 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2029 auto it = yyextra->packageNameCache.find(path.str());
2030 if (it!=yyextra->packageNameCache.end())
2031 {
2032 return it->second;
2033 }
2034 FileInfo pf(path.str()+"/__init__.py"); // found package initialization file
2035 if (pf.exists())
2036 {
2037 int i=path.findRev('/');
2038 if (i!=-1)
2039 {
2040 QCString scope = findPackageScopeFromPath(yyscanner,path.left(i));
2041 if (!scope.isEmpty())
2042 {
2043 scope+="::";
2044 }
2045 scope+=path.mid(i+1);
2046 yyextra->packageNameCache.emplace(path.str(),scope.str());
2047 return scope;
2048 }
2049 }
2050 return "";
QCString mid(size_t index, size_t len=static_cast< size_t >(-1)) const
Definition qcstring.h:241
int findRev(char c, int index=-1, bool cs=TRUE) const
Definition qcstring.cpp:96
QCString left(size_t len) const
Definition qcstring.h:229
2051}

◆ getLexerFILE()

const char * getLexerFILE ( )
inlinestatic

Definition at line 169 of file pyscanner.l.

169{return __FILE__;}

◆ handleCommentBlock()

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

Definition at line 2106 of file pyscanner.l.

2107{
2108 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2109 //printf("handleCommentBlock(doc=[%s] brief=%d yyextra->docBlockInBody=%d yyextra->docBlockJavaStyle=%d\n",
2110 // qPrint(doc),brief,yyextra->docBlockInBody,yyextra->docBlockJavaStyle);
2111
2112 // TODO: Fix me
2113 yyextra->docBlockInBody=FALSE;
#define FALSE
Definition qcstring.h:34
2114
2115 if (!yyextra->current->doc.isEmpty())
2116 {
2117 yyextra->current->doc=yyextra->current->doc.stripWhiteSpace()+"\n\n";
2118 }
2119 if (yyextra->docBlockInBody && yyextra->previous && !yyextra->previous->doc.isEmpty())
2120 {
2121 yyextra->previous->doc=yyextra->previous->doc.stripWhiteSpace()+"\n\n";
2122 }
2123
2124 int position = 0;
2125 bool needsEntry = false;
2126 int lineNr = brief ? yyextra->current->briefLine : yyextra->current->docLine;
2127 Markdown markdown(yyextra->fileName,lineNr);
2128 GuardedSectionStack guards;
2129 QCString strippedDoc = stripIndentation(doc,true);
2130 //printf("stippedDoc=[%s]\n",qPrint(strippedDoc));
2131 QCString processedDoc = Config_getBool(MARKDOWN_SUPPORT) ? markdown.process(strippedDoc,lineNr) : strippedDoc;
2132 while (yyextra->commentScanner.parseCommentBlock(
2133 yyextra->thisParser,
2134 (yyextra->docBlockInBody && yyextra->previous) ? yyextra->previous.get() : yyextra->current.get(),
2135 processedDoc, // text
2136 yyextra->fileName, // file
2137 lineNr,
2138 yyextra->docBlockInBody ? FALSE : brief,
2139 yyextra->docBlockJavaStyle, // javadoc style // or FALSE,
2140 yyextra->docBlockInBody,
2141 yyextra->protection,
2142 position,
2143 needsEntry,
2144 Config_getBool(MARKDOWN_SUPPORT),
2145 &guards
2146 )
2147 ) // need to start a new entry
2148 {
2149 if (needsEntry)
2150 {
2151 newEntry(yyscanner);
2152 }
2153 }
2154 if (needsEntry)
2155 {
2156 newEntry(yyscanner);
2157 }
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, bool skipFirstLine)
Definition util.cpp:5952
2158
2159}

References FALSE.

◆ incLineNr()

void incLineNr ( yyscan_t yyscanner)
static

Definition at line 2083 of file pyscanner.l.

2084{
2085 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2086 DBG_CTX((stderr,"yyextra->yyLineNr=%d\n",yyextra->yyLineNr));
2087 yyextra->yyLineNr++;
#define DBG_CTX(x)
Definition pyscanner.l:65
2088}

◆ initEntry()

void initEntry ( yyscan_t yyscanner)
static

Definition at line 1853 of file pyscanner.l.

1854{
1855 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1856 //yyextra->current->python = TRUE;
1857 yyextra->current->protection = yyextra->protection ;
1858 yyextra->current->mtype = yyextra->mtype;
1859 yyextra->current->virt = yyextra->virt;
1860 yyextra->current->isStatic = yyextra->isStatic;
1861 yyextra->current->lang = SrcLangExt::Python;
1862 yyextra->current->type.clear();
1863 yyextra->current->name.clear();
1864 yyextra->current->initializer.clear();
1865 yyextra->commentScanner.initGroupInfo(yyextra->current.get());
1866 yyextra->isStatic = FALSE;
1867}

References FALSE.

◆ initParser()

void initParser ( yyscan_t yyscanner)
static

Definition at line 1842 of file pyscanner.l.

1843{
1844 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1845 yyextra->protection = Protection::Public;
1846 yyextra->mtype = MethodTypes::Method;
1847 yyextra->isStatic = FALSE;
1848 yyextra->virt = Specifier::Normal;
1849 yyextra->previous = 0;
1850 yyextra->packageCommentAllowed = TRUE;
1851}

References FALSE, and TRUE.

◆ initSpecialBlock()

void initSpecialBlock ( yyscan_t yyscanner)
static

Definition at line 2206 of file pyscanner.l.

2207{
2208 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2209 yyextra->docBlockContext = YY_START;
2210 yyextra->docBlockInBody = FALSE;
2211 yyextra->docBlockJavaStyle = TRUE;
2212 yyextra->docBrief = TRUE;
2213 yyextra->docBlock.clear();
2214 yyextra->commentIndent = yyextra->curIndent;
2215 startCommentBlock(yyscanner,FALSE);
static void startCommentBlock(yyscan_t yyscanner, bool brief)
Definition pyscanner.l:2091
2216}

References FALSE, and TRUE.

◆ initTriDoubleQuoteBlock()

void initTriDoubleQuoteBlock ( yyscan_t yyscanner)
static

Definition at line 2180 of file pyscanner.l.

2181{
2182 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2183 yyextra->docBlockContext = YY_START;
2184 yyextra->docBlockInBody = FALSE;
2185 yyextra->docBlockJavaStyle = TRUE;
2186 yyextra->docBlockSpecial = yytext[strlen(yytext) - 1]=='!' || !Config_getBool(PYTHON_DOCSTRING);
2187 yyextra->docBlock.clear();
2188 yyextra->commentIndent = yyextra->curIndent;
2189 yyextra->doubleQuote = TRUE;
2190 startCommentBlock(yyscanner,FALSE);
2191}

References FALSE, and TRUE.

◆ initTriSingleQuoteBlock()

void initTriSingleQuoteBlock ( yyscan_t yyscanner)
static

Definition at line 2193 of file pyscanner.l.

2194{
2195 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2196 yyextra->docBlockContext = YY_START;
2197 yyextra->docBlockInBody = FALSE;
2198 yyextra->docBlockJavaStyle = TRUE;
2199 yyextra->docBlockSpecial = yytext[strlen(yytext) - 1]=='!' || !Config_getBool(PYTHON_DOCSTRING);
2200 yyextra->docBlock.clear();
2201 yyextra->commentIndent = yyextra->curIndent;
2202 yyextra->doubleQuote = FALSE;
2203 startCommentBlock(yyscanner,FALSE);
2204}

References FALSE, and TRUE.

◆ lineCount()

void lineCount ( yyscan_t yyscanner)
static

Definition at line 2073 of file pyscanner.l.

2074{
2075 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2076 DBG_CTX((stderr,"yyextra->yyLineNr=%d\n",yyextra->yyLineNr));
2077 for (const char *p = yytext; *p; ++p)
2078 {
2079 yyextra->yyLineNr += (*p == '\n') ;
2080 }
2081}

◆ newEntry()

void newEntry ( yyscan_t yyscanner)
static

Definition at line 1869 of file pyscanner.l.

1870{
1871 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1872 if (yyextra->current->name.isEmpty())
1873 {
1874 initEntry(yyscanner);
1875 return;
1876 }
1877 bool found = false;
1878 if (yyextra->checkDupEntry)
1879 {
1880 for (auto &v : yyextra->current_root->children())
1881 {
1882 //printf("candidate %s<->%s section=%s!\n",qPrint(v->name),qPrint(yyextra->current->name), qPrint(v->section.to_string()));
1883 if (v->name==yyextra->current->name && v->section==yyextra->current->section) // name is already added, don't add it again
1884 {
1885 if (v->doc.isEmpty() && !yyextra->current->doc.isEmpty())
1886 {
1887 v->doc = yyextra->current->doc;
1888 v->docLine = yyextra->current->docLine;
1889 v->docFile = yyextra->current->docFile;
1890 }
1891 if (v->brief.isEmpty() && !yyextra->current->brief.isEmpty())
1892 {
1893 v->brief = yyextra->current->brief;
1894 v->briefLine = yyextra->current->briefLine;
1895 v->briefFile = yyextra->current->briefFile;
1896 }
1897 if (v->type.isEmpty() && !yyextra->current->type.isEmpty())
1898 {
1899 //printf("copying type '%s' from '%s' to '%s'\n",qPrint(yyextra->current->type),qPrint(yyextra->current->name),qPrint(v->name));
1900 v->type = yyextra->current->type;
1901 }
1902 found=true;
1903 break;
1904 }
1905 }
1906 }
1907 if (!found)
1908 {
1909 yyextra->previous = yyextra->current;
1910 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
1911 }
1912 initEntry(yyscanner);
1913}

References initEntry().

◆ newFunction()

void newFunction ( yyscan_t yyscanner)
static

Definition at line 1996 of file pyscanner.l.

1997{
1998 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1999 if (yyextra->current->name.startsWith("__") && yyextra->current->name.endsWith("__"))
2000 {
2001 // special method name, see
2002 // http://docs.python.org/ref/specialnames.html
2003 yyextra->current->protection=Protection::Public;
2004 }
2005 else
2006 {
2007 setProtection(yyscanner);
2008 }
2009}

◆ newTypeAlias()

void newTypeAlias ( yyscan_t yyscanner)
static

Definition at line 1978 of file pyscanner.l.

1979{
1980 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1981 printf("*** newTypeAlias %s\n",qPrint(yyextra->current->name));
1982 newEntry(yyscanner);
const char * qPrint(const char *s)
Definition qcstring.h:687
1983}

◆ newVariable()

void newVariable ( yyscan_t yyscanner)
static

Definition at line 1967 of file pyscanner.l.

1968{
1969 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1970 setProtection(yyscanner);
1971 if (yyextra->current_root->section.isCompound()) // mark as class variable
1972 {
1973 yyextra->current->isStatic = TRUE;
1974 }
1975 newEntry(yyscanner);
1976}

References TRUE.

◆ parseCompounds()

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

Definition at line 2265 of file pyscanner.l.

2266{
2267 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2268 //printf("parseCompounds(%s)\n",qPrint(rt->name));
2269 for (size_t i=0; i<rt->children().size(); ++i)
2270 {
2271 std::shared_ptr<Entry> ce = rt->children()[i];
2272 if (!ce->program.empty())
2273 {
2274 //fprintf(stderr,"parseCompounds: -- %s (line %d) ---------\n%s\n---------------\n",
2275 // qPrint(ce->name), ce->bodyLine, qPrint(ce->program));
2276 // init scanner state
2277 yyextra->programStr = ce->program.str();
2278 yyextra->inputString = yyextra->programStr.data();
2279 yyextra->inputPosition = 0;
2280 yyextra->firstPass = false;
2281 pyscannerYYrestart( nullptr, yyscanner );
2282 if (ce->section.isCompound())
2283 {
2284 yyextra->specialBlock = false;
2285 yyextra->current_root = ce;
2286 BEGIN( Search );
2287 }
2288 else if (ce->parent())
2289 {
2290 yyextra->current_root = rt;
2291 //printf("Searching for member variables in %s parent=%s\n",
2292 // qPrint(ce->name),qPrint(ce->parent->name));
2293 BEGIN( SearchMemVars );
2294 }
2295 yyextra->fileName = ce->fileName;
2296 yyextra->yyLineNr = ce->bodyLine ;
2297 yyextra->current = std::make_shared<Entry>();
2298 initEntry(yyscanner);
2299
2300 yyextra->checkDupEntry = false;
2301
2302 QCString name = ce->name;
2303 yyextra->commentScanner.enterCompound(yyextra->fileName,yyextra->yyLineNr,name);
2304
2305 pyscannerYYlex(yyscanner) ;
2306 yyextra->lexInit=TRUE;
2307
2308 yyextra->programStr.clear();
2309 ce->program.str(std::string());
2310
2311 yyextra->commentScanner.leaveCompound(yyextra->fileName,yyextra->yyLineNr,name);
2312
2313 }
2314 parseCompounds(yyscanner,ce);
2315 }
static void parseCompounds(yyscan_t yyscanner, std::shared_ptr< Entry > rt)
Definition pyscanner.l:2265
2316}

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

Referenced by parseCompounds(), and parseMain().

◆ parseMain()

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

Definition at line 2321 of file pyscanner.l.

2322{
2323 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2324 initParser(yyscanner);
static void initParser(yyscan_t yyscanner)
Definition pyscanner.l:1842
2325
2326 if (fileBuf==nullptr || fileBuf[0]=='\0') return;
2327
2328 yyextra->inputString = fileBuf;
2329 yyextra->inputPosition = 0;
2330
2331 yyextra->protection = Protection::Public;
2332 yyextra->mtype = MethodTypes::Method;
2333 yyextra->isStatic = false;
2334 yyextra->virt = Specifier::Normal;
2335 yyextra->current_root = rt;
2336 yyextra->specialBlock = false;
2337
2338 yyextra->yyLineNr = 1 ;
2339 yyextra->fileName = fileName;
2340 yyextra->checkDupEntry = false;
2341 yyextra->firstPass = true;
2342 //setContext();
2343 msg("Parsing file {}...\n",yyextra->fileName);
#define msg(fmt,...)
Definition message.h:94
2344
2345 FileInfo fi(fileName.str());
2346 yyextra->moduleScope = findPackageScope(yyscanner,fileName);
2347 QCString baseName=fi.baseName();
2348 if (baseName!="__init__") // package initializer file is not a package itself
2349 {
2350 if (!yyextra->moduleScope.isEmpty())
2351 {
2352 yyextra->moduleScope+="::";
2353 }
2354 yyextra->moduleScope+=baseName;
2355 }
static QCString findPackageScope(yyscan_t yyscanner, const QCString &fileName)
Definition pyscanner.l:2053
2356
2357 // add namespaces for each scope
2358 QCString scope = yyextra->moduleScope;
2359 int startPos = 0;
2360 int pos = 0;
2361 do
2362 {
2363 pos = scope.find("::",startPos);
2364 startPos=pos+2;
2365 if (pos==-1) pos=(int)scope.length();
2366 yyextra->current = std::make_shared<Entry>();
2367 initEntry(yyscanner);
2368 yyextra->current->name = scope.left(pos);
2369 yyextra->current->section = EntryType::makeNamespace();
2370 yyextra->current->type = "namespace";
2371 yyextra->current->fileName = yyextra->fileName;
2372 yyextra->current->startLine = yyextra->yyLineNr;
2373 yyextra->current->bodyLine = yyextra->yyLineNr;
2374 yyextra->current_root = yyextra->current;
2375 rt->moveToSubEntryAndRefresh(yyextra->current);
2376 } 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:166
2377
2378 initParser(yyscanner);
2379
2380 yyextra->commentScanner.enterFile(yyextra->fileName,yyextra->yyLineNr);
2381
2382 yyextra->current->reset();
2383 initEntry(yyscanner);
2384 pyscannerYYrestart(nullptr,yyscanner);
2385 BEGIN( Search );
2386 pyscannerYYlex(yyscanner);
2387 yyextra->lexInit=TRUE;
2388
2389 yyextra->commentScanner.leaveFile(yyextra->fileName,yyextra->yyLineNr);
2390
2391 yyextra->programStr.clear();
2392 yyextra->current_root->program.str(std::string());
2393
2394 parseCompounds(yyscanner, yyextra->current_root);
2395}

◆ parsePrototype()

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

Definition at line 2399 of file pyscanner.l.

2400{
2401 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2402 //printf("**** parsePrototype(%s) begin\n",qPrint(text));
2403 if (text.isEmpty())
2404 {
2405 warn(yyextra->fileName,yyextra->yyLineNr,"Empty prototype found!");
2406 return;
2407 }
#define warn(file, line, fmt,...)
Definition message.h:97
2408
2409 yyextra->specialBlock = FALSE;
2410 yyextra->packageCommentAllowed = FALSE;
2411
2412 // save scanner state
2413 YY_BUFFER_STATE orgState = YY_CURRENT_BUFFER;
2414 yy_switch_to_buffer(yy_create_buffer(nullptr, YY_BUF_SIZE, yyscanner), yyscanner);
2415 const char *orgInputString = yyextra->inputString;
2416 int orgInputPosition = yyextra->inputPosition;
#define YY_BUF_SIZE
Definition commentcnv.l:19
2417
2418 // set new string
2419 yyextra->inputString = text.data();
2420 yyextra->inputPosition = 0;
2421 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:172
2422
2423 BEGIN( FunctionDec );
2424
2425 pyscannerYYlex(yyscanner);
2426 yyextra->lexInit=TRUE;
2427
2428 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
2429 if (yyextra->current->section.isMemberDoc() && yyextra->current->args.isEmpty())
2430 {
2431 yyextra->current->section = EntryType::makeVariableDoc();
2432 }
2433
2434 // restore original scanner state
2435
2436 yy_delete_buffer(YY_CURRENT_BUFFER, yyscanner);
2437 yy_switch_to_buffer(orgState, yyscanner);
2438
2439 yyextra->inputString = orgInputString;
2440 yyextra->inputPosition = orgInputPosition;
2441
2442 //printf("**** parsePrototype end\n");
2443}

References warn.

◆ searchFoundClass()

void searchFoundClass ( yyscan_t yyscanner)
static

Definition at line 2238 of file pyscanner.l.

2239{
2240 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2241 yyextra->current->section = EntryType::makeClass();
2242 yyextra->current->argList.clear();
2243 yyextra->current->type += "class" ;
2244 yyextra->current->fileName = yyextra->fileName;
2245 yyextra->current->startLine = yyextra->yyLineNr;
2246 yyextra->current->bodyLine = yyextra->yyLineNr;
2247 yyextra->packageCommentAllowed = FALSE;
2248}

References FALSE.

◆ searchFoundDef()

void searchFoundDef ( yyscan_t yyscanner)
static

Definition at line 2218 of file pyscanner.l.

2219{
2220 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2221 yyextra->current->fileName = yyextra->fileName;
2222 yyextra->current->startLine = yyextra->yyLineNr;
2223 yyextra->current->bodyLine = yyextra->yyLineNr;
2224 yyextra->current->section = EntryType::makeFunction();
2225 yyextra->current->lang = SrcLangExt::Python;
2226 yyextra->current->virt = Specifier::Normal;
2227 yyextra->current->isStatic = yyextra->isStatic;
2228 yyextra->current->mtype = yyextra->mtype = MethodTypes::Method;
2229 yyextra->current->type.clear();
2230 yyextra->current->name.clear();
2231 yyextra->current->args.clear();
2232 yyextra->current->argList.clear();
2233 yyextra->packageCommentAllowed = FALSE;
2234 yyextra->isStatic=FALSE;
2235 //printf("searchFoundDef at=%d\n",yyextra->yyLineNr);
2236}

References FALSE.

◆ searchFoundTypeAlias()

void searchFoundTypeAlias ( yyscan_t yyscanner)
static

Definition at line 2250 of file pyscanner.l.

2251{
2252 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2253 yyextra->current->section = EntryType::makeVariable();
2254 yyextra->current->argList.clear();
2255 yyextra->current->type = "typedef " ;
2256 yyextra->current->spec.setAlias(true);
2257 yyextra->current->fileName = yyextra->fileName;
2258 yyextra->current->startLine = yyextra->yyLineNr;
2259 yyextra->current->bodyLine = yyextra->yyLineNr;
2260 yyextra->packageCommentAllowed = FALSE;
2261}

References FALSE.

◆ setProtection()

void setProtection ( yyscan_t yyscanner)
static

Definition at line 1938 of file pyscanner.l.

1939{
1940 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1941 if (!yyextra->current->name.isEmpty() && yyextra->current->name.at(0)=='_')
1942 {
1943 if (yyextra->current->name.at(1)=='_') // mark as private
1944 {
1945 yyextra->current->protection=Protection::Private;
1946 }
1947 else // mark as protected
1948 {
1949 yyextra->current->protection=Protection::Protected;
1950 }
1951 }
1952}

◆ startCommentBlock()

void startCommentBlock ( yyscan_t yyscanner,
bool brief )
static

Definition at line 2091 of file pyscanner.l.

2092{
2093 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2094 if (brief)
2095 {
2096 yyextra->current->briefFile = yyextra->fileName;
2097 yyextra->current->briefLine = yyextra->yyLineNr;
2098 }
2099 else
2100 {
2101 yyextra->current->docFile = yyextra->fileName;
2102 yyextra->current->docLine = yyextra->yyLineNr;
2103 }
2104}

◆ stateToString()

const char * stateToString ( int state)
static

◆ yylex()

int yylex ( yyscan_t yyscanner)

Definition at line 283 of file pyscanner.l.

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

◆ yyread()

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

Definition at line 1832 of file pyscanner.l.

1833{
1834 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1835 int c=0;
1836 const char *p = yyextra->inputString + yyextra->inputPosition;
1837 while ( c < max_size && *p ) { *buf++ = *p++; c++; }
1838 yyextra->inputPosition+=c;
1839 return c;
1840}