%{
/*
TikZiT - a GUI diagram editor for TikZ
Copyright (C) 2018 Aleks Kissinger, Chris Heunen,
K. Johan Paulsson, Alex Merry
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
/*!
* \file tikzlexer.l
*
* The lexer for tikz input.
*/
#include "tikzparserdefs.h"
#include "tikzparser.parser.hpp"
#include
#define YY_USER_ACTION \
yylloc->first_line = yylloc->last_line; \
yylloc->first_column = yylloc->last_column + 1; \
yylloc->last_column = yylloc->first_column + yyleng - 1;
%}
%option reentrant bison-bridge bison-locations 8bit
%option bison-locations 8bit
%option nounput
%option yylineno
%option noyywrap
%option header-file="tikzlexer.h"
%option extra-type="TikzAssembler *"
%s props
%s xcoord
%s ycoord
%s noderef
FLOAT \-?[0-9]*(\.[0-9]+)?
%%
/* whitespace is ignored, except for position counting; we don't
count formfeed and vtab as whitespace, because it's not obvious
how they should be dealt with and no-one actually uses them */
/* lex will take the longest-matching string */
\r\n|\r|\n {
yylloc->first_line += 1;
yylloc->last_line = yylloc->first_line;
yylloc->first_column = yylloc->last_column = 0;
}
[\t ]+ { }
%.*$ { }
\\begin\{tikzpicture\} { return BEGIN_TIKZPICTURE_CMD; }
\\end\{tikzpicture\} { return END_TIKZPICTURE_CMD; }
\\tikzstyle { return TIKZSTYLE_CMD; }
\\begin\{pgfonlayer\} { return BEGIN_PGFONLAYER_CMD; }
\\end\{pgfonlayer\} { return END_PGFONLAYER_CMD; }
\\draw { return DRAW_CMD; }
\\node { return NODE_CMD; }
\\path { return PATH_CMD; }
; { return SEMICOLON; }
= { return EQUALS; }
rectangle { return RECTANGLE; }
node { return NODE; }
at { return AT; }
to { return TO; }
\([ ]*{FLOAT}[ ]*,[ ]*{FLOAT}[ ]*\) {
yylloc->last_column = yylloc->first_column + 1;
yyless(1);
BEGIN(xcoord);
}
{FLOAT} {
yylval->pt = new QPointF();
QString s(yytext);
yylval->pt->setX(s.toDouble());
BEGIN(ycoord);
}
, { }
{FLOAT} {
QString s(yytext);
yylval->pt->setY(s.toDouble());
}
\) {
BEGIN(INITIAL);
return TCOORD;
}
/* when we see "[", change parsing mode */
\[ /*syntaxhlfix]*/ {
BEGIN(props);
return LEFTBRACKET;
}
= { return EQUALS; }
, { return COMMA; }
/* technically, it is possible to have newlines in the middle of
property names or values, but in practice this is unlikely and
screws up our line counting */
[^=,\{\] \t\n]([^=,\{\]\n]*[^=,\{\] \t\n])? {
char *str = (char*)malloc(sizeof(char)*yyleng + 1);
strncpy(str, yytext, yyleng + 1);
yylval->str = str;
return PROPSTRING;
}
\] {
BEGIN(INITIAL);
return RIGHTBRACKET;
}
\( {
BEGIN(noderef);
return LEFTPARENTHESIS;
}
\. {
return FULLSTOP;
}
/* we assume node names (and anchor names) never contain
newlines */
[^\.\{\)\n]+ {
//qDebug() << "nodename: " << yytext << " size: " << strlen(yytext);
char *str = (char*)malloc(sizeof(char)*yyleng + 1);
strncpy(str, yytext, yyleng+1);
yylval->str = str;
return REFSTRING;
}
\) {
BEGIN(INITIAL);
return RIGHTPARENTHESIS;
}
\{ {
std::stringstream buf;
unsigned int brace_depth = 1;
unsigned int escape = 0;
while (1) {
char c = yyinput(yyscanner);
// eof reached before closing brace
if (c == '\0' || c == EOF) {
return UNCLOSED_DELIM_STR;
}
yylloc->last_column += 1;
yyleng += 1;
if (escape) {
escape = 0;
} else if (c == '\\') {
escape = 1;
} else if (c == '{') {
brace_depth++;
} else if (c == '}') {
brace_depth--;
if (brace_depth == 0) break;
} else if (c == '\n') {
yylloc->last_line += 1;
yylloc->last_column = 0;
}
buf << c;
}
char *str = (char*)malloc(sizeof(char) * yyleng + 1);
strncpy(str, buf.str().c_str(), yyleng + 1);
//str[len] = 0;
yylval->str = str;
//qDebug() << "got delim string: " << str;
return DELIMITEDSTRING;
}
\\begin { return UNKNOWN_BEGIN_CMD; }
\\end { return UNKNOWN_END_CMD; }
\\[a-zA-Z0-9]+ { return UNKNOWN_CMD; }
[a-zA-Z0-9]+ { return UNKNOWN_STR; }
. { return UNKNOWN_STR; }
/* vi:ft=lex:noet:ts=4:sts=4:sw=4:
*/