Doxygen
Loading...
Searching...
No Matches
pyscanner.l File Reference
#include <stdint.h>
#include "pyscanner.h"
#include <algorithm>
#include <memory>
#include <string>
#include <vector>
#include "arguments.h"
#include "commentscan.h"
#include "config.h"
#include "debug.h"
#include "defargs.h"
#include "entry.h"
#include "fileinfo.h"
#include "markdown.h"
#include "message.h"
#include "stringutil.h"
#include "util.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 DString findPackageScopeFromPath (yyscan_t yyscanner, const DString &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 DString &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 DString findPackageScope (yyscan_t yyscanner, const DString &fileName)
static void setProtection (yyscan_t yyscanner)
static void handleParamComment (yyscan_t yyscanner, const DString &doc)
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 DString &fileName, const char *fileBuf, const std::shared_ptr< Entry > &rt)
static void parsePrototype (yyscan_t yyscanner, const DString &text)

Macro Definition Documentation

◆ DBG_CTX

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

Definition at line 60 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 65 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:3981

Definition at line 162 of file pyscanner.l.

◆ YY_NO_INPUT

#define YY_NO_INPUT   1

Definition at line 62 of file pyscanner.l.

◆ YY_NO_UNISTD_H

#define YY_NO_UNISTD_H   1

Definition at line 63 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 1927 of file pyscanner.l.

1928{
1929 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1930
1931 auto doc = yyextra->current->doc;
1932 auto docLine = yyextra->current->docLine;
1933 auto docFile = yyextra->current->docFile;
1934 auto brief = yyextra->current->brief;
1935 auto briefLine = yyextra->current->briefLine;
1936 auto briefFile = yyextra->current->briefFile;
1937
1938 yyextra->previous = yyextra->current;
1939 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
1940 initEntry(yyscanner);
static void initEntry(yyscan_t yyscanner)
Definition pyscanner.l:1865
1941
1942 yyextra->current->doc = doc;
1943 yyextra->current->docLine = docLine;
1944 yyextra->current->docFile = docFile;
1945 yyextra->current->brief = brief;
1946 yyextra->current->briefLine = briefLine;
1947 yyextra->current->briefFile = briefFile;
1948}

References initEntry().

Referenced by addVariable().

◆ addFrom()

void addFrom ( yyscan_t yyscanner,
bool all )
static

Definition at line 2072 of file pyscanner.l.

2073{
2074 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2075 DString item=all ? yyextra->packageName : yyextra->packageName+"."+yytext;
2076 yyextra->current->name=removeRedundantWhiteSpace(substitute(item,".","::"));
2077 yyextra->current->fileName = yyextra->fileName;
2078 //printf("Adding using declaration: found:%s:%d name=%s\n",qPrint(yyextra->fileName),yyextra->yyLineNr,qPrint(yyextra->current->name));
2079 yyextra->current->section=all ? EntryType::makeUsingDir() : EntryType::makeUsingDecl();
2080 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
2081 initEntry(yyscanner);
A String class for use with Doxygen wrapping std::string and adding some additional functionality off...
Definition dstring.h:84
Wrapper class for the Entry type.
Definition types.h:856
DString substitute(const DString &s, const DString &src, const DString &dst)
substitute all occurrences of src in s by dst
Definition dstring.cpp:485
DString removeRedundantWhiteSpace(const DString &s)
Definition util.cpp:426
2082}

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

◆ addToString()

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

Definition at line 2186 of file pyscanner.l.

2187{
2188 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2189 if (yyextra->copyString) (*yyextra->copyString) << s;
2190}

◆ addVariable()

void addVariable ( yyscan_t yyscanner)
static

Definition at line 1997 of file pyscanner.l.

1998{
1999 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2000 setProtection(yyscanner);
2001 if (yyextra->current_root->section.isCompound()) // mark as class variable
2002 {
2003 yyextra->current->isStatic = true;
2004 }
2005 addEntry(yyscanner);
static void setProtection(yyscan_t yyscanner)
Definition pyscanner.l:1950
static void addEntry(yyscan_t yyscanner)
Definition pyscanner.l:1927
2006}

References addEntry(), and setProtection().

◆ computeIndent()

int computeIndent ( const char * s)
inlinestatic

Definition at line 2023 of file pyscanner.l.

2024{
2025 int col=0;
2026 int tabSize=Config_getInt(TAB_SIZE);
2027 const char *p=s;
2028 char c;
2029 while ((c=*p++))
2030 {
2031 if (c==' ') col++;
2032 else if (c=='\t') col+=tabSize-(col%tabSize);
2033 else break;
2034 }
2035 return col;
#define Config_getInt(name)
Definition config.h:34
2036}

References Config_getInt.

◆ docVariable()

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

Definition at line 1966 of file pyscanner.l.

1967{
1968 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1969 yyextra->current->name = name;
1970 yyextra->current->section=EntryType::makeVariable();
1971 yyextra->current->fileName = yyextra->fileName;
1972 yyextra->current->startLine = yyextra->yyLineNr;
1973 yyextra->current->bodyLine = yyextra->yyLineNr;
1974 yyextra->current->type.clear();
1975 setProtection(yyscanner);
1976 yyextra->checkDupEntry = true;
1977}

References setProtection().

◆ endOfDef()

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

Definition at line 2173 of file pyscanner.l.

2174{
2175 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2176 //printf("endOfDef at=%d\n",yyextra->yyLineNr);
2177 if (yyextra->bodyEntry)
2178 {
2179 yyextra->bodyEntry->endBodyLine = yyextra->yyLineNr-correction;
2180 yyextra->bodyEntry = 0;
2181 }
2182 newEntry(yyscanner);
2183 //yyextra->insideConstructor = false;
static void newEntry(yyscan_t yyscanner)
Definition pyscanner.l:1881
2184}

References newEntry().

◆ findPackageScope()

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

Definition at line 2065 of file pyscanner.l.

2066{
2067 if (fileName.empty()) return fileName;
2068 FileInfo fi(fileName.str());
2069 return findPackageScopeFromPath(yyscanner,fi.dirPath(true));
bool empty() const
Returns true iff the string is empty (std::string compatible alias for isEmpty()).
Definition dstring.h:148
const std::string & str() const
Definition dstring.h:645
Minimal replacement for QFileInfo.
Definition fileinfo.h:26
static DString findPackageScopeFromPath(yyscan_t yyscanner, const DString &path)
Definition pyscanner.l:2038
2070}

References FileInfo::dirPath(), DString::empty(), findPackageScopeFromPath(), and DString::str().

Referenced by parseMain().

◆ findPackageScopeFromPath()

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

Definition at line 2038 of file pyscanner.l.

2039{
2040 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2041 auto it = yyextra->packageNameCache.find(path.str());
2042 if (it!=yyextra->packageNameCache.end())
2043 {
2044 return it->second;
2045 }
2046 FileInfo pf(path.str()+"/__init__.py"); // found package initialization file
2047 if (pf.exists())
2048 {
2049 size_t i=path.rfind('/');
2050 if (i!=DString::npos)
2051 {
2052 DString scope = findPackageScopeFromPath(yyscanner,path.left(i));
2053 if (!scope.empty())
2054 {
2055 scope+="::";
2056 }
2057 scope+=path.mid(i+1);
2058 yyextra->packageNameCache.emplace(path.str(),scope.str());
2059 return scope;
2060 }
2061 }
2062 return "";
size_t rfind(char c, size_t pos=npos) const
Definition dstring.h:244
DString mid(size_t index, size_t len=npos) const
Definition dstring.h:318
static constexpr size_t npos
value used to indicate 'not found' or 'to the end of the string', matching std::string::npos
Definition dstring.h:178
DString left(size_t len) const
Definition dstring.h:306
2063}

References DString::empty(), FileInfo::exists(), DString::find(), findPackageScopeFromPath(), DString::left(), DString::mid(), DString::npos, DString::rfind(), and DString::str().

Referenced by findPackageScope(), and findPackageScopeFromPath().

◆ getLexerFILE()

const char * getLexerFILE ( )
inlinestatic

Definition at line 165 of file pyscanner.l.

165{return __FILE__;}

◆ handleCommentBlock()

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

Definition at line 2118 of file pyscanner.l.

2119{
2120 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2121 //printf("handleCommentBlock(doc=[%s] brief=%d yyextra->docBlockInBody=%d yyextra->docBlockJavaStyle=%d\n",
2122 // qPrint(doc),brief,yyextra->docBlockInBody,yyextra->docBlockJavaStyle);
2123
2124 // TODO: Fix me
2125 yyextra->docBlockInBody=false;
2126
2127 if (!yyextra->current->doc.empty())
2128 {
2129 yyextra->current->doc=yyextra->current->doc.stripWhiteSpace()+"\n\n";
2130 }
2131 if (yyextra->docBlockInBody && yyextra->previous && !yyextra->previous->doc.empty())
2132 {
2133 yyextra->previous->doc=yyextra->previous->doc.stripWhiteSpace()+"\n\n";
2134 }
2135
2136 int position = 0;
2137 bool needsEntry = false;
2138 int lineNr = brief ? yyextra->current->briefLine : yyextra->current->docLine;
2139 Markdown markdown(yyextra->fileName,lineNr);
2140 GuardedSectionStack guards;
2141 DString strippedDoc = stripIndentation(doc,true);
2142 //printf("stippedDoc=[%s]\n",qPrint(strippedDoc));
2143 DString processedDoc = Config_getBool(MARKDOWN_SUPPORT) ? markdown.process(strippedDoc,lineNr) : strippedDoc;
2144 while (yyextra->commentScanner.parseCommentBlock(
2145 yyextra->thisParser,
2146 (yyextra->docBlockInBody && yyextra->previous) ? yyextra->previous.get() : yyextra->current.get(),
2147 processedDoc, // text
2148 yyextra->fileName, // file
2149 lineNr,
2150 yyextra->docBlockInBody ? false : brief,
2151 yyextra->docBlockJavaStyle, // javadoc style // or false,
2152 yyextra->docBlockInBody,
2153 yyextra->protection,
2154 position,
2155 needsEntry,
2156 Config_getBool(MARKDOWN_SUPPORT),
2157 &guards
2158 )
2159 ) // need to start a new entry
2160 {
2161 if (needsEntry)
2162 {
2163 newEntry(yyscanner);
2164 }
2165 }
2166 if (needsEntry)
2167 {
2168 newEntry(yyscanner);
2169 }
Helper class to process markdown formatted text.
Definition markdown.h:33
std::stack< GuardedSection > GuardedSectionStack
Definition commentscan.h:48
#define Config_getBool(name)
Definition config.h:33
DString stripIndentation(const DString &s, bool skipFirstLine)
Definition util.cpp:4683
2170
2171}

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

◆ handleParamComment()

void handleParamComment ( yyscan_t yyscanner,
const DString & doc )
static

Definition at line 2275 of file pyscanner.l.

2276{
2277 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2278 yyextra->curIndent=computeIndent(yytext);
2279 initSpecialBlock(yyscanner);
2280 if (!yyextra->current->argList.empty())
2281 {
2282 yyextra->docBlock += "@param ";
2283 yyextra->docBlock += yyextra->current->argList.back().name;
2284 yyextra->docBlock += " ";
2285 }
2286 yyextra->docBlockContext = YY_START;
static void initSpecialBlock(yyscan_t yyscanner)
Definition pyscanner.l:2218
static int computeIndent(const char *s)
Definition pyscanner.l:2023
2287}

References computeIndent(), and initSpecialBlock().

◆ incLineNr()

void incLineNr ( yyscan_t yyscanner)
static

Definition at line 2095 of file pyscanner.l.

2096{
2097 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2098 DBG_CTX((stderr,"yyextra->yyLineNr=%d\n",yyextra->yyLineNr));
2099 yyextra->yyLineNr++;
#define DBG_CTX(x)
Definition pyscanner.l:60
2100}

References DBG_CTX.

◆ initEntry()

void initEntry ( yyscan_t yyscanner)
static

Definition at line 1865 of file pyscanner.l.

1866{
1867 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1868 //yyextra->current->python = true;
1869 yyextra->current->protection = yyextra->protection ;
1870 yyextra->current->mtype = yyextra->mtype;
1871 yyextra->current->virt = yyextra->virt;
1872 yyextra->current->isStatic = yyextra->isStatic;
1873 yyextra->current->lang = SrcLangExt::Python;
1874 yyextra->current->type.clear();
1875 yyextra->current->name.clear();
1876 yyextra->current->initializer.clear();
1877 yyextra->commentScanner.initGroupInfo(yyextra->current.get());
1878 yyextra->isStatic = false;
1879}

◆ initParser()

void initParser ( yyscan_t yyscanner)
static

Definition at line 1854 of file pyscanner.l.

1855{
1856 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1857 yyextra->protection = Protection::Public;
1858 yyextra->mtype = MethodTypes::Method;
1859 yyextra->isStatic = false;
1860 yyextra->virt = Specifier::Normal;
1861 yyextra->previous = 0;
1862 yyextra->packageCommentAllowed = true;
1863}

◆ initSpecialBlock()

void initSpecialBlock ( yyscan_t yyscanner)
static

Definition at line 2218 of file pyscanner.l.

2219{
2220 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2221 yyextra->docBlockContext = YY_START;
2222 yyextra->docBlockInBody = false;
2223 yyextra->docBlockJavaStyle = true;
2224 yyextra->docBrief = true;
2225 yyextra->docBlock.clear();
2226 yyextra->commentIndent = yyextra->curIndent;
2227 startCommentBlock(yyscanner,false);
static void startCommentBlock(yyscan_t yyscanner, bool brief)
Definition pyscanner.l:2103
2228}

References startCommentBlock().

Referenced by handleParamComment().

◆ initTriDoubleQuoteBlock()

void initTriDoubleQuoteBlock ( yyscan_t yyscanner)
static

Definition at line 2192 of file pyscanner.l.

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

References Config_getBool, and startCommentBlock().

◆ initTriSingleQuoteBlock()

void initTriSingleQuoteBlock ( yyscan_t yyscanner)
static

Definition at line 2205 of file pyscanner.l.

2206{
2207 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2208 yyextra->docBlockContext = YY_START;
2209 yyextra->docBlockInBody = false;
2210 yyextra->docBlockJavaStyle = true;
2211 yyextra->docBlockSpecial = yytext[strlen(yytext) - 1]=='!' || !Config_getBool(PYTHON_DOCSTRING);
2212 yyextra->docBlock.clear();
2213 yyextra->commentIndent = yyextra->curIndent;
2214 yyextra->doubleQuote = false;
2215 startCommentBlock(yyscanner,false);
2216}

References Config_getBool, and startCommentBlock().

◆ lineCount()

void lineCount ( yyscan_t yyscanner)
static

Definition at line 2085 of file pyscanner.l.

2086{
2087 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2088 DBG_CTX((stderr,"yyextra->yyLineNr=%d\n",yyextra->yyLineNr));
2089 for (const char *p = yytext; *p; ++p)
2090 {
2091 yyextra->yyLineNr += (*p == '\n') ;
2092 }
2093}

References DBG_CTX.

◆ newEntry()

void newEntry ( yyscan_t yyscanner)
static

Definition at line 1881 of file pyscanner.l.

1882{
1883 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1884 if (yyextra->current->name.empty())
1885 {
1886 initEntry(yyscanner);
1887 return;
1888 }
1889 bool found = false;
1890 if (yyextra->checkDupEntry)
1891 {
1892 for (auto &v : yyextra->current_root->children())
1893 {
1894 //printf("candidate %s<->%s section=%s!\n",qPrint(v->name),qPrint(yyextra->current->name), qPrint(v->section.to_string()));
1895 if (v->name==yyextra->current->name && v->section==yyextra->current->section) // name is already added, don't add it again
1896 {
1897 if (v->doc.empty() && !yyextra->current->doc.empty())
1898 {
1899 v->doc = yyextra->current->doc;
1900 v->docLine = yyextra->current->docLine;
1901 v->docFile = yyextra->current->docFile;
1902 }
1903 if (v->brief.empty() && !yyextra->current->brief.empty())
1904 {
1905 v->brief = yyextra->current->brief;
1906 v->briefLine = yyextra->current->briefLine;
1907 v->briefFile = yyextra->current->briefFile;
1908 }
1909 if (v->type.empty() && !yyextra->current->type.empty())
1910 {
1911 //printf("copying type '%s' from '%s' to '%s'\n",qPrint(yyextra->current->type),qPrint(yyextra->current->name),qPrint(v->name));
1912 v->type = yyextra->current->type;
1913 }
1914 found=true;
1915 break;
1916 }
1917 }
1918 }
1919 if (!found)
1920 {
1921 yyextra->previous = yyextra->current;
1922 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
1923 }
1924 initEntry(yyscanner);
1925}

References initEntry().

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

◆ newFunction()

void newFunction ( yyscan_t yyscanner)
static

Definition at line 2008 of file pyscanner.l.

2009{
2010 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2011 if (yyextra->current->name.startsWith("__") && yyextra->current->name.endsWith("__"))
2012 {
2013 // special method name, see
2014 // http://docs.python.org/ref/specialnames.html
2015 yyextra->current->protection=Protection::Public;
2016 }
2017 else
2018 {
2019 setProtection(yyscanner);
2020 }
2021}

References setProtection().

◆ newTypeAlias()

void newTypeAlias ( yyscan_t yyscanner)
static

Definition at line 1990 of file pyscanner.l.

1991{
1992 //struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1993 //printf("*** newTypeAlias %s\n",qPrint(yyextra->current->name));
1994 newEntry(yyscanner);
1995}

References newEntry().

◆ newVariable()

void newVariable ( yyscan_t yyscanner)
static

Definition at line 1979 of file pyscanner.l.

1980{
1981 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1982 setProtection(yyscanner);
1983 if (yyextra->current_root->section.isCompound()) // mark as class variable
1984 {
1985 yyextra->current->isStatic = true;
1986 }
1987 newEntry(yyscanner);
1988}

References newEntry(), and setProtection().

◆ parseCompounds()

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

Definition at line 2291 of file pyscanner.l.

2292{
2293 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2294 //printf("parseCompounds(%s)\n",qPrint(rt->name));
2295 for (size_t i=0; i<rt->children().size(); ++i)
2296 {
2297 std::shared_ptr<Entry> ce = rt->children()[i];
2298 if (!ce->program.empty())
2299 {
2300 //fprintf(stderr,"parseCompounds: -- %s (line %d) ---------\n%s\n---------------\n",
2301 // qPrint(ce->name), ce->bodyLine, qPrint(ce->program));
2302 // init scanner state
2303 yyextra->programStr = ce->program.str();
2304 yyextra->inputString = yyextra->programStr.data();
2305 yyextra->inputPosition = 0;
2306 yyextra->firstPass = false;
2307 pyscannerYYrestart( nullptr, yyscanner );
2308 if (ce->section.isCompound())
2309 {
2310 yyextra->specialBlock = false;
2311 yyextra->current_root = ce;
2312 BEGIN( Search );
2313 }
2314 else if (ce->parent())
2315 {
2316 yyextra->current_root = rt;
2317 //printf("Searching for member variables in %s parent=%s\n",
2318 // qPrint(ce->name),qPrint(ce->parent->name));
2319 BEGIN( SearchMemVars );
2320 }
2321 yyextra->fileName = ce->fileName;
2322 yyextra->yyLineNr = ce->bodyLine ;
2323 yyextra->current = std::make_shared<Entry>();
2324 initEntry(yyscanner);
2325
2326 yyextra->checkDupEntry = false;
2327
2328 DString name = ce->name;
2329 yyextra->commentScanner.enterCompound(yyextra->fileName,yyextra->yyLineNr,name);
2330
2331 pyscannerYYlex(yyscanner) ;
2332 yyextra->lexInit=true;
2333
2334 yyextra->programStr.clear();
2335 ce->program.str(std::string());
2336
2337 yyextra->commentScanner.leaveCompound(yyextra->fileName,yyextra->yyLineNr,name);
2338
2339 }
2340 parseCompounds(yyscanner,ce);
2341 }
static void parseCompounds(yyscan_t yyscanner, std::shared_ptr< Entry > rt)
Definition pyscanner.l:2291
2342}

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

Referenced by parseCompounds(), and parseMain().

◆ parseMain()

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

Definition at line 2347 of file pyscanner.l.

2348{
2349 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2350 initParser(yyscanner);
static void initParser(yyscan_t yyscanner)
Definition pyscanner.l:1854
2351
2352 if (fileBuf==nullptr || fileBuf[0]=='\0') return;
2353
2354 yyextra->inputString = fileBuf;
2355 yyextra->inputPosition = 0;
2356
2357 yyextra->protection = Protection::Public;
2358 yyextra->mtype = MethodTypes::Method;
2359 yyextra->isStatic = false;
2360 yyextra->virt = Specifier::Normal;
2361 yyextra->current_root = rt;
2362 yyextra->specialBlock = false;
2363
2364 yyextra->yyLineNr = 1 ;
2365 yyextra->fileName = fileName;
2366 yyextra->checkDupEntry = false;
2367 yyextra->firstPass = true;
2368 //setContext();
2369 msg("Parsing file {}...\n",yyextra->fileName);
#define msg(fmt,...)
Definition message.h:94
2370
2371 FileInfo fi(fileName.str());
2372 yyextra->moduleScope = findPackageScope(yyscanner,fileName);
2373 DString baseName=fi.baseName();
2374 if (baseName!="__init__") // package initializer file is not a package itself
2375 {
2376 if (!yyextra->moduleScope.empty())
2377 {
2378 yyextra->moduleScope+="::";
2379 }
2380 yyextra->moduleScope+=baseName;
2381 }
static DString findPackageScope(yyscan_t yyscanner, const DString &fileName)
Definition pyscanner.l:2065
2382
2383 // add namespaces for each scope
2384 DString scope = yyextra->moduleScope;
2385 size_t startPos = 0;
2386 size_t pos = 0;
2387 do
2388 {
2389 pos = scope.find("::",startPos);
2390 if (pos==DString::npos)
2391 {
2392 startPos = pos = scope.length();
2393 }
2394 else
2395 {
2396 startPos = pos+2;
2397 }
2398 yyextra->current = std::make_shared<Entry>();
2399 initEntry(yyscanner);
2400 yyextra->current->name = scope.left(pos);
2401 yyextra->current->section = EntryType::makeNamespace();
2402 yyextra->current->type = "namespace";
2403 yyextra->current->fileName = yyextra->fileName;
2404 yyextra->current->startLine = yyextra->yyLineNr;
2405 yyextra->current->bodyLine = yyextra->yyLineNr;
2406 yyextra->current_root = yyextra->current;
2407 rt->moveToSubEntryAndRefresh(yyextra->current);
2408 } while (pos<scope.length());
size_t find(char c, size_t pos=0) const
Definition dstring.h:239
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition dstring.h:151
2409
2410 initParser(yyscanner);
2411
2412 yyextra->commentScanner.enterFile(yyextra->fileName,yyextra->yyLineNr);
2413
2414 yyextra->current->reset();
2415 initEntry(yyscanner);
2416 pyscannerYYrestart(nullptr,yyscanner);
2417 BEGIN( Search );
2418 pyscannerYYlex(yyscanner);
2419 yyextra->lexInit=true;
2420
2421 yyextra->commentScanner.leaveFile(yyextra->fileName,yyextra->yyLineNr);
2422
2423 yyextra->programStr.clear();
2424 yyextra->current_root->program.str(std::string());
2425
2426 parseCompounds(yyscanner, yyextra->current_root);
2427}

References FileInfo::baseName(), DString::find(), findPackageScope(), initEntry(), initParser(), DString::left(), DString::length(), msg, DString::npos, parseCompounds(), Search, and DString::str().

Referenced by PythonOutlineParser::parseInput().

◆ parsePrototype()

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

Definition at line 2431 of file pyscanner.l.

2432{
2433 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2434 //printf("**** parsePrototype(%s) begin\n",qPrint(text));
2435 if (text.empty())
2436 {
2437 warn(yyextra->fileName,yyextra->yyLineNr,"Empty prototype found!");
2438 return;
2439 }
#define warn(file, line, fmt,...)
Definition message.h:97
2440
2441 yyextra->specialBlock = false;
2442 yyextra->packageCommentAllowed = false;
2443
2444 // save scanner state
2445 YY_BUFFER_STATE orgState = YY_CURRENT_BUFFER;
2446 yy_switch_to_buffer(yy_create_buffer(nullptr, YY_BUF_SIZE, yyscanner), yyscanner);
2447 const char *orgInputString = yyextra->inputString;
2448 int orgInputPosition = yyextra->inputPosition;
#define YY_BUF_SIZE
Definition commentcnv.l:19
2449
2450 // set new string
2451 yyextra->inputString = text.data();
2452 yyextra->inputPosition = 0;
2453 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 dstring.h:157
2454
2455 BEGIN( FunctionDec );
2456
2457 pyscannerYYlex(yyscanner);
2458 yyextra->lexInit=true;
2459
2460 yyextra->current->name = yyextra->current->name.stripWhiteSpace();
2461 if (yyextra->current->section.isMemberDoc() && yyextra->current->args.empty())
2462 {
2463 yyextra->current->section = EntryType::makeVariableDoc();
2464 }
2465
2466 // restore original scanner state
2467
2468 yy_delete_buffer(YY_CURRENT_BUFFER, yyscanner);
2469 yy_switch_to_buffer(orgState, yyscanner);
2470
2471 yyextra->inputString = orgInputString;
2472 yyextra->inputPosition = orgInputPosition;
2473
2474 //printf("**** parsePrototype end\n");
2475}

References DString::data(), DString::empty(), warn, and YY_BUF_SIZE.

◆ searchFoundClass()

void searchFoundClass ( 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::makeClass();
2254 yyextra->current->argList.clear();
2255 yyextra->current->type += "class" ;
2256 yyextra->current->fileName = yyextra->fileName;
2257 yyextra->current->startLine = yyextra->yyLineNr;
2258 yyextra->current->bodyLine = yyextra->yyLineNr;
2259 yyextra->packageCommentAllowed = false;
2260}

◆ searchFoundDef()

void searchFoundDef ( yyscan_t yyscanner)
static

Definition at line 2230 of file pyscanner.l.

2231{
2232 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2233 yyextra->current->fileName = yyextra->fileName;
2234 yyextra->current->startLine = yyextra->yyLineNr;
2235 yyextra->current->bodyLine = yyextra->yyLineNr;
2236 yyextra->current->section = EntryType::makeFunction();
2237 yyextra->current->lang = SrcLangExt::Python;
2238 yyextra->current->virt = Specifier::Normal;
2239 yyextra->current->isStatic = yyextra->isStatic;
2240 yyextra->current->mtype = yyextra->mtype = MethodTypes::Method;
2241 yyextra->current->type.clear();
2242 yyextra->current->name.clear();
2243 yyextra->current->args.clear();
2244 yyextra->current->argList.clear();
2245 yyextra->packageCommentAllowed = false;
2246 yyextra->isStatic=false;
2247 //printf("searchFoundDef at=%d\n",yyextra->yyLineNr);
2248}

◆ searchFoundTypeAlias()

void searchFoundTypeAlias ( yyscan_t yyscanner)
static

Definition at line 2262 of file pyscanner.l.

2263{
2264 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2265 yyextra->current->section = EntryType::makeVariable();
2266 yyextra->current->argList.clear();
2267 yyextra->current->type = "typedef " ;
2268 yyextra->current->spec.setAlias(true);
2269 yyextra->current->fileName = yyextra->fileName;
2270 yyextra->current->startLine = yyextra->yyLineNr;
2271 yyextra->current->bodyLine = yyextra->yyLineNr;
2272 yyextra->packageCommentAllowed = false;
2273}

◆ setProtection()

void setProtection ( yyscan_t yyscanner)
static

Definition at line 1950 of file pyscanner.l.

1951{
1952 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1953 if (!yyextra->current->name.empty() && yyextra->current->name.at(0)=='_')
1954 {
1955 if (yyextra->current->name.at(1)=='_') // mark as private
1956 {
1957 yyextra->current->protection=Protection::Private;
1958 }
1959 else // mark as protected
1960 {
1961 yyextra->current->protection=Protection::Protected;
1962 }
1963 }
1964}

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

◆ startCommentBlock()

void startCommentBlock ( yyscan_t yyscanner,
bool brief )
static

Definition at line 2103 of file pyscanner.l.

2104{
2105 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2106 if (brief)
2107 {
2108 yyextra->current->briefFile = yyextra->fileName;
2109 yyextra->current->briefLine = yyextra->yyLineNr;
2110 }
2111 else
2112 {
2113 yyextra->current->docFile = yyextra->fileName;
2114 yyextra->current->docLine = yyextra->yyLineNr;
2115 }
2116}

◆ stateToString()

const char * stateToString ( int state)
static

◆ yylex()

int yylex ( yyscan_t yyscanner)

Definition at line 279 of file pyscanner.l.

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

◆ yyread()

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

Definition at line 1844 of file pyscanner.l.

1845{
1846 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1847 int c=0;
1848 const char *p = yyextra->inputString + yyextra->inputPosition;
1849 while ( c < max_size && *p ) { *buf++ = *p++; c++; }
1850 yyextra->inputPosition+=c;
1851 return c;
1852}