1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258
|
%{
/***************************************************************************
*
* $Id: lexer.l 184 2011-02-28 21:38:28Z Michael.McTernan $
*
* Mscgen language lexer definition.
* Copyright (C) 2009 Michael C McTernan, Michael.McTernan.2001@cs.bris.ac.uk
*
* This file is part of msclib.
*
* Msc is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* Msclib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with msclib; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
***************************************************************************/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "mscgen_config.h"
#include "mscgen_msc.h"
#include "mscgen_bool.h"
#include "mscgen_safe.h"
#include "mscgen_lexer.h"
#include "mscgen_language.h" /* Token definitions from Yacc/Bison */
#define USE_STATE2STRING 0
/* Counter for error reporting */
static unsigned long lex_linenum = 1;
static char *lex_line = NULL;
static Boolean lex_utf8 = FALSE;
/* Local function prototypes */
static void newline(const char *text, unsigned int n);
static char *trimQstring(char *s);
#if USE_STATE2STRING
static const char *stateToString(int state);
#endif
%}
/* Not used, so prevent compiler warning */
%option never-interactive
%option noinput
%option noyywrap
%x IN_COMMENT
%x BODY
%%
<INITIAL>{
\xef\xbb\xbf lex_utf8 = TRUE; BEGIN(BODY);
(\r\n).* newline(yytext, 2); BEGIN(BODY);
(\r|\n).* newline(yytext, 1); BEGIN(BODY);
. unput(yytext[0]); BEGIN(BODY);
}
<IN_COMMENT>{
"*/" BEGIN(BODY);
[^*\n]+
"*"
(\r\n).* newline(yytext, 2);
(\r|\n).* newline(yytext, 1);
}
<BODY>{
"/*" BEGIN(IN_COMMENT);
(\r\n).* newline(yytext, 2);
(\r|\n).* newline(yytext, 1);
#.*$ /* Ignore lines after '#' */
\/\/.*$ /* Ignore lines after '//' */
msc return TOK_MSC;
HSCALE|hscale yylval.optType = MSC_OPT_HSCALE; return TOK_OPT_HSCALE;
WIDTH|width yylval.optType = MSC_OPT_WIDTH; return TOK_OPT_WIDTH;
ARCGRADIENT|arcgradient yylval.optType = MSC_OPT_ARCGRADIENT; return TOK_OPT_ARCGRADIENT;
WORDWRAPARCS|wordwraparcs yylval.optType = MSC_OPT_WORDWRAPARCS; return TOK_OPT_WORDWRAPARCS;
URL|url yylval.attribType = MSC_ATTR_URL; return TOK_ATTR_URL;
LABEL|label yylval.attribType = MSC_ATTR_LABEL; return TOK_ATTR_LABEL;
IDURL|idurl yylval.attribType = MSC_ATTR_IDURL; return TOK_ATTR_IDURL;
ID|id yylval.attribType = MSC_ATTR_ID; return TOK_ATTR_ID;
LINECOLO(U?)R|linecolo(u?)r yylval.attribType = MSC_ATTR_LINE_COLOUR; return TOK_ATTR_LINE_COLOUR;
TEXTCOLO(U?)R|textcolo(u?)r yylval.attribType = MSC_ATTR_TEXT_COLOUR; return TOK_ATTR_TEXT_COLOUR;
TEXTBGCOLO(U?)R|textbgcolo(u?)r yylval.attribType = MSC_ATTR_TEXT_BGCOLOUR; return TOK_ATTR_TEXT_BGCOLOUR;
ARCLINECOLO(U?)R|arclinecolo(u?)r yylval.attribType = MSC_ATTR_ARC_LINE_COLOUR; return TOK_ATTR_ARC_LINE_COLOUR;
ARCTEXTCOLO(U?)R|arctextcolo(u?)r yylval.attribType = MSC_ATTR_ARC_TEXT_COLOUR; return TOK_ATTR_ARC_TEXT_COLOUR;
ARCTEXTBGCOLO(U?)R|arctextbgcolo(u?)r yylval.attribType = MSC_ATTR_ARC_TEXT_BGCOLOUR; return TOK_ATTR_ARC_TEXT_BGCOLOUR;
ARCSKIP|arcskip yylval.attribType = MSC_ATTR_ARC_SKIP; return TOK_ATTR_ARC_SKIP;
\.\.\. yylval.arctype = MSC_ARC_DISCO; return TOK_SPECIAL_ARC; /* ... */
--- yylval.arctype = MSC_ARC_DIVIDER; return TOK_SPECIAL_ARC; /* --- */
\|\|\| yylval.arctype = MSC_ARC_SPACE; return TOK_SPECIAL_ARC; /* ||| */
\<-\> yylval.arctype = MSC_ARC_SIGNAL; return TOK_REL_SIG_BI; /* <-> */
-\> yylval.arctype = MSC_ARC_SIGNAL; return TOK_REL_SIG_TO; /* -> */
\<- yylval.arctype = MSC_ARC_SIGNAL; return TOK_REL_SIG_FROM; /* <- */
-- yylval.arctype = MSC_ARC_SIGNAL; return TOK_REL_SIG; /* -- */
-[Xx] yylval.arctype = MSC_ARC_LOSS; return TOK_REL_LOSS_TO; /* -x */
[Xx]- yylval.arctype = MSC_ARC_LOSS; return TOK_REL_LOSS_FROM; /* x- */
\<=\> yylval.arctype = MSC_ARC_METHOD; return TOK_REL_METHOD_BI; /* <=> */
=\> yylval.arctype = MSC_ARC_METHOD; return TOK_REL_METHOD_TO; /* => */
\<= yylval.arctype = MSC_ARC_METHOD; return TOK_REL_METHOD_FROM; /* <= */
== yylval.arctype = MSC_ARC_METHOD; return TOK_REL_METHOD; /* == */
\<\<\>\> yylval.arctype = MSC_ARC_RETVAL; return TOK_REL_RETVAL_BI; /* <<>> */
\>\> yylval.arctype = MSC_ARC_RETVAL; return TOK_REL_RETVAL_TO; /* >> */
\<\< yylval.arctype = MSC_ARC_RETVAL; return TOK_REL_RETVAL_FROM; /* << */
\.\. yylval.arctype = MSC_ARC_RETVAL; return TOK_REL_RETVAL; /* .. */
\<:\> yylval.arctype = MSC_ARC_DOUBLE; return TOK_REL_DOUBLE_BI; /* <:> */
:\> yylval.arctype = MSC_ARC_DOUBLE; return TOK_REL_DOUBLE_TO; /* :> */
\<: yylval.arctype = MSC_ARC_DOUBLE; return TOK_REL_DOUBLE_FROM; /* <: */
:: yylval.arctype = MSC_ARC_DOUBLE; return TOK_REL_DOUBLE; /* :: */
\<\<=\>\> yylval.arctype = MSC_ARC_CALLBACK; return TOK_REL_CALLBACK_BI; /* <<=>> */
=\>\> yylval.arctype = MSC_ARC_CALLBACK; return TOK_REL_CALLBACK_TO; /* =>> */
\<\<= yylval.arctype = MSC_ARC_CALLBACK; return TOK_REL_CALLBACK_FROM; /* <<= */
BOX|box yylval.arctype = MSC_ARC_BOX; return TOK_REL_BOX; /* box */
ABOX|abox yylval.arctype = MSC_ARC_ABOX; return TOK_REL_ABOX; /* abox */
RBOX|rbox yylval.arctype = MSC_ARC_RBOX; return TOK_REL_RBOX; /* rbox */
NOTE|note yylval.arctype = MSC_ARC_NOTE; return TOK_REL_NOTE; /* note */
[A-Za-z0-9_]+ yylval.string = strdup_s(yytext); return TOK_STRING;
\"(\\\"|[^\"])*\" yylval.string = trimQstring(strdup_s(yytext)); return TOK_QSTRING;
= return TOK_EQUAL;
, return TOK_COMMA;
\; return TOK_SEMICOLON;
\{ return TOK_OCBRACKET;
\} return TOK_CCBRACKET;
\[ return TOK_OSBRACKET;
\] return TOK_CSBRACKET;
\* return TOK_ASTERISK;
[ \t]+ /* ignore whitespace */;
}
<*>.|\n|\r return TOK_UNKNOWN;
%%
/* Handle a new line of input.
* This counts the line number and duplicates the string in case we need
* it for error reporting. The line is then returned back for parsing
* without the newline characters prefixed.
*/
static void newline(const char *text, unsigned int n)
{
lex_linenum++;
if(lex_line != NULL)
{
free(lex_line);
}
lex_line = strdup(text + n);
yyless(n);
}
/* Trim a multi-line quoted string.
* This allows the parsed input quoted strings to span multiple lines of
* input but be condensed to only a single line of output e.g.
* a->b [label="line 1
* line 1 too"];
* Will parse to a string such as"line1\n line1 too". This function
* will collapse the \n and whitespace into a single space.
*/
static char *trimQstring(char *const s)
{
int i = 0, o = 0, skipmode = 0;
/* Strip leading " */
if(s[i] == '\"')
{
i++;
}
/* Copy body, compacting whitespace after newline sequences */
while(s[i] != '\0')
{
if(s[i] == '\r' || s[i] == '\n' || s[i] == '\f')
{
skipmode = 1;
}
else if(!skipmode || !isspace(s[i]))
{
if(skipmode)
{
s[o] = ' ';
o++;
}
skipmode = 0;
s[o] = s[i];
o++;
}
i++;
}
/* Null terminate */
s[o] = '\0';
/* Remove trailing " */
if(o >= 1 && s[o - 1] == '\"')
s[o-1] = '\0';
return s;
}
unsigned long lex_getlinenum(void)
{
return lex_linenum;
}
char *lex_getline(void)
{
return lex_line;
}
void lex_destroy(void)
{
if(lex_line != NULL)
{
free(lex_line);
lex_line = NULL;
}
}
Boolean lex_getutf8(void)
{
return lex_utf8;
}
void lex_resetparser()
{
lex_linenum = 1;
lex_line = NULL;
lex_utf8 = FALSE;
#ifdef FLEX_DEBUG
// in case of a debug build stll disable debug information
// as it disrupts the normal doxygen output
yy_flex_debug = 0;
#endif
}
#if USE_STATE2STRING
#include "mscgen_lexer.l.h"
#endif
/* END OF FILE */
|