summaryrefslogtreecommitdiffstats
path: root/python/sip/sipgen/lexer.l
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit90825e2392b2d70e43c7a25b8a3752299a933894 (patch)
treee33aa27f02b74604afbfd0ea4f1cfca8833d882a /python/sip/sipgen/lexer.l
downloadtdebindings-90825e2392b2d70e43c7a25b8a3752299a933894.tar.gz
tdebindings-90825e2392b2d70e43c7a25b8a3752299a933894.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebindings@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'python/sip/sipgen/lexer.l')
-rw-r--r--python/sip/sipgen/lexer.l567
1 files changed, 567 insertions, 0 deletions
diff --git a/python/sip/sipgen/lexer.l b/python/sip/sipgen/lexer.l
new file mode 100644
index 00000000..ef234193
--- /dev/null
+++ b/python/sip/sipgen/lexer.l
@@ -0,0 +1,567 @@
+/*
+ * The SIP lexer.
+ *
+ * Copyright (c) 2007
+ * Riverbank Computing Limited <info@riverbankcomputing.co.uk>
+ *
+ * This file is part of SIP.
+ *
+ * This copy of SIP is licensed for use under the terms of the SIP License
+ * Agreement. See the file LICENSE for more details.
+ *
+ * SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+%{
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "sip.h"
+#include "parser.h"
+
+
+#ifndef FLEX_SCANNER
+#error "Only flex is supported at the moment"
+#endif
+
+
+#define YY_FATAL_ERROR(s) fatallex(s)
+
+#define MAX_INCLUDE_DEPTH 10
+#define MAX_CODE_LINE_LENGTH 1000
+
+
+static struct inputFile {
+ int lineno; /* The line number. */
+ YY_BUFFER_STATE bs; /* The flex buffer state handle. */
+ char *name; /* The file name. */
+ char *cwd; /* The path part of the file name. */
+ parserContext pc; /* The parser context. */
+} inputFileStack[MAX_INCLUDE_DEPTH];
+
+static int currentFile = -1; /* Index of the current input file. */
+static char codeLine[MAX_CODE_LINE_LENGTH + 2]; /* The current code line. */
+static int codeIdx = -1; /* Index of next code character. */
+
+static FILE *openFile(char *);
+static void fatallex(char *);
+%}
+
+%x code
+%x ccomment
+
+%%
+
+^[ \t]*%SIPOptions {return TK_OPTIONS;}
+^[ \t]*%SIPNoEmitters {return TK_NOEMITTERS;}
+^[ \t]*%Include {return TK_INCLUDE;}
+^[ \t]*%OptionalInclude {return TK_OPTINCLUDE;}
+^[ \t]*%Import {return TK_IMPORT;}
+^[ \t]*%Module {return TK_MODULE;}
+^[ \t]*%CModule {return TK_CMODULE;}
+^[ \t]*%Timeline {return TK_TIMELINE;}
+^[ \t]*%Platforms {return TK_PLATFORMS;}
+^[ \t]*%Feature {return TK_FEATURE;}
+^[ \t]*%License {return TK_LICENSE;}
+^[ \t]*%MappedType {return TK_MAPPEDTYPE;}
+^[ \t]*%Exception {return TK_EXCEPTION;}
+^[ \t]*%If {return TK_IF;}
+<INITIAL>^[ \t]*%End {return TK_END;}
+class {return TK_CLASS;}
+struct {return TK_STRUCT;}
+public {return TK_PUBLIC;}
+protected {return TK_PROTECTED;}
+private {return TK_PRIVATE;}
+signals {return TK_SIGNALS;}
+slots {return TK_SLOTS;}
+char {return TK_CHAR;}
+wchar_t {return TK_WCHAR_T;}
+bool {return TK_BOOL;}
+short {return TK_SHORT;}
+int {return TK_INT;}
+long {return TK_LONG;}
+float {return TK_FLOAT;}
+double {return TK_DOUBLE;}
+void {return TK_VOID;}
+virtual {return TK_VIRTUAL;}
+enum {return TK_ENUM;}
+signed {return TK_SIGNED;}
+unsigned {return TK_UNSIGNED;}
+const {return TK_CONST;}
+static {return TK_STATIC;}
+true {return TK_TRUE;}
+false {return TK_FALSE;}
+NULL {return TK_NULL;}
+typedef {return TK_TYPEDEF;}
+namespace {return TK_NAMESPACE;}
+operator {return TK_OPERATOR;}
+throw {return TK_THROW;}
+explicit {return TK_EXPLICIT;}
+template {return TK_TEMPLATE;}
+:: {return TK_SCOPE;}
+\|\| {return TK_LOGICAL_OR;}
+SIP_PYOBJECT {return TK_PYOBJECT;}
+SIP_PYTUPLE {return TK_PYTUPLE;}
+SIP_PYLIST {return TK_PYLIST;}
+SIP_PYDICT {return TK_PYDICT;}
+SIP_PYCALLABLE {return TK_PYCALLABLE;}
+SIP_PYSLICE {return TK_PYSLICE;}
+SIP_PYTYPE {return TK_PYTYPE;}
+SIP_SIGNAL {return TK_SIPSIGNAL;}
+SIP_SLOT {return TK_SIPSLOT;}
+SIP_ANYSLOT {return TK_SIPANYSLOT;}
+SIP_RXOBJ_CON {return TK_SIPRXCON;}
+SIP_RXOBJ_DIS {return TK_SIPRXDIS;}
+SIP_SLOT_CON {return TK_SIPSLOTCON;}
+SIP_SLOT_DIS {return TK_SIPSLOTDIS;}
+SIP_QOBJECT {return TK_QOBJECT;}
+\.\.\. {return TK_ELLIPSIS;}
+
+
+[ \t\r] { /* Ignore whitespace. */
+ ;
+}
+
+\n { /* Maintain the line number. */
+ ++inputFileStack[currentFile].lineno;
+
+ if (codeIdx == 0)
+ {
+ BEGIN code;
+ }
+}
+
+\/\/.* { /* Ignore C++ style comments. */
+ ;
+}
+
+
+-?[0-9]+ { /* A signed decimal number. */
+ yylval.number = strtol(yytext,NULL,0);
+ return TK_NUMBER;
+}
+
+
+-?(([0-9]+)|([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?) {/* A floating point number. */
+ yylval.real = strtod(yytext,NULL);
+ return TK_REAL;
+}
+
+
+0x[0-9a-fA-F]+ { /* An unsigned hexadecimal number. */
+ yylval.number = strtol(yytext,NULL,16);
+ return TK_NUMBER;
+}
+
+
+[_A-Za-z][_A-Za-z0-9]* { /* An identifier name. */
+ yylval.text = sipStrdup(yytext);
+ return TK_NAME;
+}
+
+
+[._A-Za-z][._/A-Za-z0-9\-]*[._A-Za-z0-9] { /* A relative pathname. */
+ yylval.text = sipStrdup(yytext);
+ return TK_PATHNAME;
+}
+
+
+\"[^"\n]*["\n] { /* A double-quoted string. */
+ char *dp, *sp;
+
+ /* Copy the string without the quotes. */
+
+ yylval.text = sipMalloc(strlen(yytext) + 1);
+
+ dp = yylval.text;
+ sp = yytext;
+
+ while (*sp != '\0')
+ {
+ if (*sp != '"')
+ *dp++ = *sp;
+
+ ++sp;
+ }
+
+ *dp = '\0';
+
+ return TK_STRING;
+}
+
+
+\'[^'\n]*['\n] { /* A single-quoted character. */
+ if (strlen(yytext) != 3)
+ fatallex("Exactly one character expected between single quotes");
+
+ yylval.qchar = yytext[1];
+
+ return TK_QCHAR;
+}
+
+
+\/\* { /* Ignore C-style comments. */
+ BEGIN ccomment;
+}
+<ccomment>\n {
+ ++inputFileStack[currentFile].lineno;
+}
+<ccomment>\*\/ {
+ BEGIN INITIAL;
+}
+<ccomment>. {
+ ;
+}
+
+
+^%Copying { /* The software license. */
+ codeIdx = 0;
+ return TK_COPYING;
+}
+
+^%ConvertFromTypeCode { /* The start of a from-type code block. */
+ codeIdx = 0;
+ return TK_FROMTYPE;
+}
+
+^%ConvertToTypeCode { /* The start of a to-type code block. */
+ codeIdx = 0;
+ return TK_TOTYPE;
+}
+
+^%ConvertToSubClassCode { /* The start of a to-sub-class code block. */
+ codeIdx = 0;
+ return TK_TOSUBCLASS;
+}
+
+^%ExportedHeaderCode { /* The start of an exported header code block. */
+ codeIdx = 0;
+ return TK_EXPHEADERCODE;
+}
+
+^%ModuleHeaderCode { /* The start of a module header code block. */
+ codeIdx = 0;
+ return TK_MODHEADERCODE;
+}
+
+^%TypeHeaderCode { /* The start of a type header code block. */
+ codeIdx = 0;
+ return TK_TYPEHEADERCODE;
+}
+
+^%PreInitialisationCode { /* The start of a pre-initialisation code block. */
+ codeIdx = 0;
+ return TK_PREINITCODE;
+}
+
+^%PostInitialisationCode { /* The start of a post-initialisation code block. */
+ codeIdx = 0;
+ return TK_POSTINITCODE;
+}
+
+^%UnitCode { /* The start of a unit code block. */
+ codeIdx = 0;
+ return TK_UNITCODE;
+}
+
+^%ModuleCode { /* The start of a module code block. */
+ codeIdx = 0;
+ return TK_MODCODE;
+}
+
+^%TypeCode { /* The start of a type code block. */
+ codeIdx = 0;
+ return TK_TYPECODE;
+}
+
+^%MethodCode { /* The start of a C++ method code block. */
+ codeIdx = 0;
+ return TK_METHODCODE;
+}
+
+^%VirtualCatcherCode { /* The start of a C++ virtual code block. */
+ codeIdx = 0;
+ return TK_VIRTUALCATCHERCODE;
+}
+
+^%GCTraverseCode { /* The start of a traverse code block. */
+ codeIdx = 0;
+ return TK_TRAVERSECODE;
+}
+
+^%GCClearCode { /* The start of a clear code block. */
+ codeIdx = 0;
+ return TK_CLEARCODE;
+}
+
+^%BIGetReadBufferCode { /* The start of a read buffer code block. */
+ codeIdx = 0;
+ return TK_READBUFFERCODE;
+}
+
+^%BIGetWriteBufferCode { /* The start of a write buffer code block. */
+ codeIdx = 0;
+ return TK_WRITEBUFFERCODE;
+}
+
+^%BIGetSegCountCode { /* The start of a segment count code block. */
+ codeIdx = 0;
+ return TK_SEGCOUNTCODE;
+}
+
+^%BIGetCharBufferCode { /* The start of a char buffer code block. */
+ codeIdx = 0;
+ return TK_CHARBUFFERCODE;
+}
+
+^%PrePythonCode { /* The start of a pre-Python code block. */
+ codeIdx = 0;
+ return TK_PREPYCODE;
+}
+
+^%RaiseCode { /* The start of a raise exception code block. */
+ codeIdx = 0;
+ return TK_RAISECODE;
+}
+
+^%Doc { /* The start of a documentation block. */
+ codeIdx = 0;
+ return TK_DOC;
+}
+
+^%ExportedDoc { /* The start of an exported documentation block. */
+ codeIdx = 0;
+ return TK_EXPORTEDDOC;
+}
+
+^%Makefile { /* The start of a Makefile code block. */
+ codeIdx = 0;
+ return TK_MAKEFILE;
+}
+
+^%AccessCode { /* The start of an access code block. */
+ codeIdx = 0;
+ return TK_ACCESSCODE;
+}
+
+^%GetCode { /* The start of a get code block. */
+ codeIdx = 0;
+ return TK_GETCODE;
+}
+
+^%SetCode { /* The start of a set code block. */
+ codeIdx = 0;
+ return TK_SETCODE;
+}
+
+<code>^%End { /* The end of a code block. */
+ BEGIN INITIAL;
+ codeIdx = -1;
+ return TK_END;
+}
+
+<code>\n { /* The end of a code line . */
+ struct inputFile *ifp;
+
+ codeLine[codeIdx] = '\n';
+ codeLine[codeIdx + 1] = '\0';
+ codeIdx = 0;
+
+ ifp = &inputFileStack[currentFile];
+
+ yylval.codeb = sipMalloc(sizeof (codeBlock));
+
+ yylval.codeb -> frag = sipStrdup(codeLine);
+ yylval.codeb -> linenr = ifp -> lineno++;
+ yylval.codeb -> filename = sipStrdup(ifp -> name);
+ yylval.codeb -> next = NULL;
+
+ return TK_CODELINE;
+}
+
+<code>. { /* The contents of a code line. */
+ if (codeIdx == MAX_CODE_LINE_LENGTH)
+ fatallex("Line is too long");
+
+ codeLine[codeIdx++] = yytext[0];
+}
+
+. { /* Anything else is returned as is. */
+ return yytext[0];
+}
+
+%%
+
+/*
+ * Hook into EOF handling. Return 0 if there is more to process.
+ */
+
+int yywrap()
+{
+ char *cwd;
+ struct inputFile *ifp;
+
+ if ((cwd = inputFileStack[currentFile].cwd) != NULL)
+ free(cwd);
+
+ ifp = &inputFileStack[currentFile--];
+
+ /* Tell the parser if this is the end of a file. */
+
+ parserEOF(ifp -> name,&ifp -> pc);
+
+ /* Tidy up this file. */
+
+ fclose(yyin);
+ free(ifp -> name);
+
+ /* See if this was the original file. */
+
+ if (currentFile < 0)
+ return 1;
+
+ yy_delete_buffer(YY_CURRENT_BUFFER);
+ yy_switch_to_buffer(ifp -> bs);
+
+ return 0;
+}
+
+
+/*
+ * Set up an input file to be read by the lexer, opening it if necessary.
+ */
+void setInputFile(FILE *fp,char *name,parserContext *pc,int optional)
+{
+ char *fullname = NULL;
+
+ if (currentFile >= MAX_INCLUDE_DEPTH - 1)
+ fatal("Too many nested %%Include, %%OptionalInclude or %%Import statements\n");
+
+ if (fp != NULL || (fp = openFile(name)) != NULL)
+ fullname = sipStrdup(name);
+ else
+ {
+ char *cwd;
+
+ /* Try the directory that contains the current file. */
+ if (currentFile >= 0 && (cwd = inputFileStack[currentFile].cwd) != NULL)
+ {
+ fullname = concat(cwd,"/",name,NULL);
+
+ if ((fp = openFile(fullname)) == NULL)
+ {
+ free(fullname);
+ fullname = NULL;
+ }
+ }
+ }
+
+ /* Try the include path if we haven't found anything yet. */
+ if (fullname == NULL)
+ {
+ stringList *sl;
+
+ fullname = NULL;
+
+ for (sl = includeDirList; sl != NULL; sl = sl -> next)
+ {
+ if (fullname != NULL)
+ free(fullname);
+
+ fullname = concat(sl -> s,"/",name,NULL);
+
+ if ((fp = openFile(fullname)) != NULL)
+ break;
+ }
+
+ if (fp == NULL && !optional)
+ fatal("Unable to find file \"%s\"\n",name);
+ }
+
+ if (fp != NULL)
+ {
+ char *cwd;
+
+ yyin = fp;
+
+ ++currentFile;
+
+ /*
+ * Remember the directory containing the new file and make it
+ * "current".
+ */
+ if ((cwd = strchr(fullname,'/')) != NULL)
+ {
+ cwd = sipStrdup(fullname);
+ *strrchr(cwd,'/') = '\0';
+ }
+
+ inputFileStack[currentFile].lineno = 1;
+ inputFileStack[currentFile].name = fullname;
+ inputFileStack[currentFile].pc = *pc;
+ inputFileStack[currentFile].cwd = cwd;
+
+ if (currentFile > 0)
+ {
+ inputFileStack[currentFile].bs = YY_CURRENT_BUFFER;
+ yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE));
+ }
+ }
+}
+
+
+/*
+ * Open a file for reading or return NULL if it doesn't exist. Any other error
+ * is fatal.
+ */
+static FILE *openFile(char *name)
+{
+ FILE *fp;
+
+ if ((fp = fopen(name,"r")) == NULL && errno != ENOENT)
+ fatal("Error in opening file %s\n",name);
+
+ return fp;
+}
+
+
+/*
+ * Handle fatal yacc errors.
+ */
+void yyerror(char *s)
+{
+ if (currentFile < 0)
+ fatal("%s\n", s);
+
+ fatal("%s:%d: %s\n",
+ inputFileStack[currentFile].name,
+ inputFileStack[currentFile].lineno,
+ s);
+}
+
+
+/*
+ * Handle warnings while parsing.
+ */
+void yywarning(char *s)
+{
+ warning("%s:%d: %s\n",
+ inputFileStack[currentFile].name,
+ inputFileStack[currentFile].lineno,
+ s);
+}
+
+
+/*
+ * Handle fatal lex errors.
+ */
+static void fatallex(char *s)
+{
+ fatal("%s:%d: Lexical analyser error: %s\n",
+ inputFileStack[currentFile].name,
+ inputFileStack[currentFile].lineno,
+ s);
+}