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
|
/*
Copyright (C) 2013-2015 Michael Goffioul
This file is part of Octave.
Octave 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.
Octave 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 Octave; see the file COPYING. If not, see
<http://www.gnu.org/licenses/>.
*/
%{
#define YYDEBUG 1
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "txt-eng.h"
#include "oct-tex-parser.h"
extern int octave_tex_lex (YYSTYPE *, void *);
static void yyerror (text_parser_tex& parser, const char *s);
#if defined (GNULIB_NAMESPACE)
// Calls to the following functions appear in the generated output from
// Bison without the namespace tag. Redefine them so we will use them
// via the gnulib namespace.
#define fclose GNULIB_NAMESPACE::fclose
#define fprintf GNULIB_NAMESPACE::fprintf
#define malloc GNULIB_NAMESPACE::malloc
#endif
#define scanner parser.get_scanner ()
%}
%API_PREFIX_DECL%
%define api.pure
%parse-param { text_parser_tex& parser }
%lex-param { void *scanner }
%code requires {#include <string>}
%union {
/* Leaf symbols produced by the scanner */
char ch;
double num;
int sym;
/* Used for string buffering */
std::string* str;
/* Objects produced by the parser */
text_element* e_base;
text_element_list* e_list;
}
%token BF IT SL RM
%token FONTNAME FONTSIZE
%token COLOR COLOR_RGB
%token START END SUPER SUB
%token<ch> CH
%token<num> NUM
%token<sym> SYM
%type<str> simple_string
%type<e_base> string_element symbol_element
%type<e_base> superscript_element subscript_element combined_script_element
%type<e_base> font_modifier_element fontname_element fontsize_element color_element
%type<e_list> string_element_list scoped_string_element_list
/* Make sure there's no memory leak on parse error. */
%destructor { } <ch> <num> <sym>
%destructor { delete $$; } <*>
%nonassoc SCRIPT
%nonassoc SUB SUPER
%nonassoc STR
%nonassoc CH
%start string
%%
simple_string : CH
{ $$ = new std::string (1, $1); }
| simple_string CH
{ $1->append (1, $2); $$ = $1; }
;
symbol_element : SYM
{ $$ = new text_element_symbol ($1); }
;
font_modifier_element : BF
{ $$ = new text_element_fontstyle (text_element_fontstyle::bold); }
| IT
{ $$ = new text_element_fontstyle (text_element_fontstyle::italic); }
| SL
{ $$ = new text_element_fontstyle (text_element_fontstyle::oblique); }
| RM
{ $$ = new text_element_fontstyle (text_element_fontstyle::normal); }
;
fontsize_element : FONTSIZE START NUM END
{ $$ = new text_element_fontsize ($3); }
;
fontname_element : FONTNAME START simple_string END
{
$$ = new text_element_fontname (*$3);
delete $3;
}
;
color_element : COLOR START simple_string END
{
$$ = new text_element_color (*$3);
delete $3;
}
| COLOR_RGB START NUM NUM NUM END
{
$$ = new text_element_color ($3, $4, $5);
}
;
string_element : simple_string %prec STR
{
$$ = new text_element_string (*$1);
delete $1;
}
| scoped_string_element_list
/* This is just to avoid a warning in bison. */
{ $$ = $1; }
| symbol_element
| font_modifier_element
| fontsize_element
| fontname_element
| color_element
| superscript_element %prec SCRIPT
| subscript_element %prec SCRIPT
| combined_script_element
;
superscript_element : SUPER CH
{ $$ = new text_element_superscript ($2); }
| SUPER scoped_string_element_list
{ $$ = new text_element_superscript ($2); }
| SUPER symbol_element
{ $$ = new text_element_superscript ($2); }
;
subscript_element : SUB CH
{ $$ = new text_element_subscript ($2); }
| SUB scoped_string_element_list
{ $$ = new text_element_subscript ($2); }
| SUB symbol_element
{ $$ = new text_element_subscript ($2); }
;
combined_script_element : subscript_element superscript_element
{ $$ = new text_element_combined ($1, $2); }
| superscript_element subscript_element
{ $$ = new text_element_combined ($1, $2); }
;
string_element_list : string_element
{ $$ = new text_element_list ($1); }
| string_element_list string_element
{ $1->push_back ($2); $$ = $1; }
;
scoped_string_element_list : START string_element_list END
{ $$ = $2; }
| START END
{ $$ = new text_element_list (); }
;
string : /* empty */
{ parser.set_parse_result (new text_element_string ("")); }
| string_element_list
{ parser.set_parse_result ($1); }
;
%%
text_element*
text_parser_tex::parse (const std::string& s)
{
octave_tex_debug = 0;
if (init_lexer (s))
{
result = 0;
if (octave_tex_parse (*this) == 0)
return result;
}
return new text_element_string (s);
}
static void
yyerror (text_parser_tex&, const char *s)
{
fprintf (stderr, "TeX parse error: %s\n", s);
}
|