⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lexer.l

📁 这是关于RFC3261实现sip的源代码
💻 L
字号:
/* * The SIP lexer. * * Copyright (c) 2006 * 	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	1000static 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]*%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;}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] {				/* 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;}^%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;}^%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("Unexpected end of input\n");	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);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -