wrap mathed parser in a class, the main parsing functions should be

re-entrant now


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@2473 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
André Pönitz 2001-08-10 09:30:02 +00:00
parent 8898791bc6
commit 23638ef606

View File

@ -58,6 +58,36 @@ using std::endl;
namespace { namespace {
MathScriptInset * prevScriptInset(MathArray const & array)
{
MathInset * p = array.back();
return (p && p->isScriptInset()) ? static_cast<MathScriptInset *>(p) : 0;
}
MathInset * lastScriptInset(MathArray & array, bool up, bool down, int limits)
{
MathScriptInset * p = prevScriptInset(array);
if (!p) {
MathInset * b = array.back();
if (b && b->isScriptable()) {
p = new MathScriptInset(up, down, b->clone());
array.pop_back();
} else {
p = new MathScriptInset(up, down);
}
array.push_back(p);
}
if (up)
p->up(true);
if (down)
p->down(down);
if (limits)
p->limits(limits);
return p;
}
// These are lexical codes, not semantic // These are lexical codes, not semantic
enum lexcode_enum { enum lexcode_enum {
LexNone, LexNone,
@ -78,18 +108,6 @@ enum lexcode_enum {
lexcode_enum lexcode[256]; lexcode_enum lexcode[256];
void mathed_parse_into(MathArray & array, unsigned flags);
unsigned char getuchar(std::istream * is)
{
char c = 0;
is->get(c);
if (!is->good())
lyxerr << "The input stream is not well..." << endl;
return static_cast<unsigned char>(c);
}
const unsigned char LM_TK_OPEN = '{'; const unsigned char LM_TK_OPEN = '{';
const unsigned char LM_TK_CLOSE = '}'; const unsigned char LM_TK_CLOSE = '}';
@ -107,21 +125,6 @@ enum {
FLAG_OPTARG = 1 << 10 // reads an argument in [] FLAG_OPTARG = 1 << 10 // reads an argument in []
}; };
///
struct {
///
int i;
///
latexkeys const * l;
} yylval;
string yytext;
int yylineno;
istream * yyis;
struct latex_mathenv_type { struct latex_mathenv_type {
char const * name; char const * name;
@ -150,13 +153,6 @@ int const latex_mathenv_num = sizeof(latex_mathenv)/sizeof(latex_mathenv[0]);
void mathPrintError(string const & msg)
{
//lyxerr[Debug::MATHED] << "Line ~" << yylineno << ": Math parse error: " << msg << endl;
lyxerr << "Line ~" << yylineno << ": Math parse error: " << msg << endl;
}
void lexInit() void lexInit()
{ {
for (int i = 0; i <= 255; ++i) { for (int i = 0; i <= 255; ++i) {
@ -190,18 +186,84 @@ void lexInit()
} }
string lexArg(unsigned char lf, bool accept_spaces = false)
//
// Helper class for parsing
//
class Parser {
public:
///
Parser(LyXLex & lex) : is_(lex.getStream()), lineno_(lex.getLineNo()) {}
///
Parser(istream & is) : is_(is), lineno_(0) {}
///
MathMacroTemplate * parse_macro();
///
MathMatrixInset * parse_normal();
///
void parse_into(MathArray & array, unsigned flags);
///
int lineno() const { return lineno_; }
private:
///
int yylex();
///
string lexArg(unsigned char lf, bool accept_spaces = false);
///
unsigned char getuchar();
///
void error(string const & msg);
///
void parse_lines(MathGridInset * p, int col, bool numbered, bool outmost);
///
latexkeys const * read_delim();
private:
///
istream & is_;
///
int lineno_;
///
int ival_;
///
latexkeys const * lval_;
///
string sval_;
///
bool curr_num_;
//
string curr_label_;
};
unsigned char Parser::getuchar()
{
char c = 0;
is_.get(c);
if (!is_.good())
lyxerr << "The input stream is not well..." << endl;
return static_cast<unsigned char>(c);
}
string Parser::lexArg(unsigned char lf, bool accept_spaces = false)
{ {
string result; string result;
unsigned char c = 0; unsigned char c = 0;
while (yyis->good()) { while (is_.good()) {
c = getuchar(yyis); c = getuchar();
if (!isspace(c)) if (!isspace(c))
break; break;
} }
if (c != lf) { if (c != lf) {
yyis->putback(c); is_.putback(c);
return result; return result;
} }
@ -217,20 +279,20 @@ string lexArg(unsigned char lf, bool accept_spaces = false)
int depth = 1; int depth = 1;
do { do {
unsigned char c = getuchar(yyis); unsigned char c = getuchar();
if (c == lf) if (c == lf)
++depth; ++depth;
if (c == rg) if (c == rg)
--depth; --depth;
if ((!isspace(c) || (c == ' ' && accept_spaces)) && depth > 0) if ((!isspace(c) || (c == ' ' && accept_spaces)) && depth > 0)
result += c; result += c;
} while (depth > 0 && yyis->good()); } while (depth > 0 && is_.good());
return result; return result;
} }
int yylex() int Parser::yylex()
{ {
static bool init_done = false; static bool init_done = false;
@ -239,41 +301,41 @@ int yylex()
init_done = true; init_done = true;
} }
while (yyis->good()) { while (is_.good()) {
unsigned char c = getuchar(yyis); unsigned char c = getuchar();
//lyxerr << "reading byte: '" << c << "' code: " << lexcode[c] << endl; //lyxerr << "reading byte: '" << c << "' code: " << lexcode[c] << endl;
if (lexcode[c] == LexNewLine) { if (lexcode[c] == LexNewLine) {
++yylineno; ++lineno_;
continue; continue;
} else if (lexcode[c] == LexComment) { } else if (lexcode[c] == LexComment) {
do { do {
c = getuchar(yyis); c = getuchar();
} while (c != '\n' && yyis->good()); // eat comments } while (c != '\n' && is_.good()); // eat comments
} else if (lexcode[c] == LexOther) { } else if (lexcode[c] == LexOther) {
yylval.i = c; ival_ = c;
return LM_TK_STR; return LM_TK_STR;
} else if (lexcode[c] == LexAlpha || lexcode[c] == LexSpace) { } else if (lexcode[c] == LexAlpha || lexcode[c] == LexSpace) {
yylval.i = c; ival_ = c;
return LM_TK_ALPHA; return LM_TK_ALPHA;
} else if (lexcode[c] == LexBOP) { } else if (lexcode[c] == LexBOP) {
yylval.i = c; ival_ = c;
return LM_TK_BOP; return LM_TK_BOP;
} else if (lexcode[c] == LexMath) { } else if (lexcode[c] == LexMath) {
yylval.i = 0; ival_ = 0;
return LM_TK_MATH; return LM_TK_MATH;
} else if (lexcode[c] == LexSelf) { } else if (lexcode[c] == LexSelf) {
return c; return c;
} else if (lexcode[c] == LexArgument) { } else if (lexcode[c] == LexArgument) {
c = getuchar(yyis); c = getuchar();
yylval.i = c - '0'; ival_ = c - '0';
return LM_TK_ARGUMENT; return LM_TK_ARGUMENT;
} else if (lexcode[c] == LexOpen) { } else if (lexcode[c] == LexOpen) {
return LM_TK_OPEN; return LM_TK_OPEN;
} else if (lexcode[c] == LexClose) { } else if (lexcode[c] == LexClose) {
return LM_TK_CLOSE; return LM_TK_CLOSE;
} else if (lexcode[c] == LexESC) { } else if (lexcode[c] == LexESC) {
c = getuchar(yyis); c = getuchar();
//lyxerr << "reading second byte: '" << c << "' code: " << lexcode[c] << endl; //lyxerr << "reading second byte: '" << c << "' code: " << lexcode[c] << endl;
string s; string s;
s += c; s += c;
@ -282,24 +344,24 @@ int yylex()
//lyxerr << "found key: " << l << endl; //lyxerr << "found key: " << l << endl;
//lyxerr << "found key name: " << l->name << endl; //lyxerr << "found key name: " << l->name << endl;
//lyxerr << "found key token: " << l->token << endl; //lyxerr << "found key token: " << l->token << endl;
yylval.l = l; lval_ = l;
yylval.i = l->id; ival_ = l->id;
return l->token; return l->token;
} }
if (lexcode[c] == LexAlpha) { if (lexcode[c] == LexAlpha) {
yytext.erase(); sval_.erase();
while (lexcode[c] == LexAlpha && yyis->good()) { while (lexcode[c] == LexAlpha && is_.good()) {
yytext += c; sval_ += c;
c = getuchar(yyis); c = getuchar();
} }
while (lexcode[c] == LexSpace && yyis->good()) while (lexcode[c] == LexSpace && is_.good())
c = getuchar(yyis); c = getuchar();
if (lexcode[c] != LexSpace) if (lexcode[c] != LexSpace)
yyis->putback(c); is_.putback(c);
//lyxerr[Debug::MATHED] << "reading: text '" << yytext << "'\n"; //lyxerr[Debug::MATHED] << "reading: text '" << sval_ << "'\n";
//lyxerr << "reading: text '" << yytext << "'\n"; //lyxerr << "reading: text '" << sval_ << "'\n";
latexkeys const * l = in_word_set(yytext); latexkeys const * l = in_word_set(sval_);
if (!l) if (!l)
return LM_TK_UNDEF; return LM_TK_UNDEF;
@ -308,11 +370,11 @@ int yylex()
int i = 0; int i = 0;
while (i < latex_mathenv_num && name != latex_mathenv[i].name) while (i < latex_mathenv_num && name != latex_mathenv[i].name)
++i; ++i;
yylval.i = i; ival_ = i;
} else if (l->token == LM_TK_SPACE) } else if (l->token == LM_TK_SPACE)
yylval.i = l->id; ival_ = l->id;
else else
yylval.l = l; lval_ = l;
return l->token; return l->token;
} }
} }
@ -321,79 +383,52 @@ int yylex()
} }
MathScriptInset * prevScriptInset(MathArray const & array) void Parser::error(string const & msg)
{ {
MathInset * p = array.back(); lyxerr << "Line ~" << lineno_ << ": Math parse error: " << msg << endl;
return (p && p->isScriptInset()) ? static_cast<MathScriptInset *>(p) : 0;
} }
MathInset * lastScriptInset(MathArray & array, bool up, bool down, int limits) void Parser::parse_lines(MathGridInset * p, int col, bool numbered, bool outmost)
{
MathScriptInset * p = prevScriptInset(array);
if (!p) {
MathInset * b = array.back();
if (b && b->isScriptable()) {
p = new MathScriptInset(up, down, b->clone());
array.pop_back();
} else {
p = new MathScriptInset(up, down);
}
array.push_back(p);
}
if (up)
p->up(true);
if (down)
p->down(down);
if (limits)
p->limits(limits);
return p;
}
static bool curr_num;
static string curr_label;
void mathed_parse_lines(MathGridInset * p, int col, bool numbered, bool outmost)
{ {
// save global variables // save global variables
bool const saved_num = curr_num; bool const saved_num = curr_num_;
string const saved_label = curr_label; string const saved_label = curr_label_;
for (int row = 0; true; ++row) { for (int row = 0; true; ++row) {
// reset global variables // reset global variables
curr_num = numbered; curr_num_ = numbered;
curr_label.erase(); curr_label_.erase();
// reading a row // reading a row
int idx = p->nargs() - p->ncols(); int idx = p->nargs() - p->ncols();
for (int i = 0; i < col - 1; ++i, ++idx) for (int i = 0; i < col - 1; ++i, ++idx)
mathed_parse_into(p->cell(idx), FLAG_AMPERSAND); parse_into(p->cell(idx), FLAG_AMPERSAND);
mathed_parse_into(p->cell(idx), FLAG_NEWLINE | FLAG_END); parse_into(p->cell(idx), FLAG_NEWLINE | FLAG_END);
if (outmost) { if (outmost) {
MathMatrixInset * m = static_cast<MathMatrixInset *>(p); MathMatrixInset * m = static_cast<MathMatrixInset *>(p);
m->numbered(row, curr_num); m->numbered(row, curr_num_);
m->label(row, curr_label); m->label(row, curr_label_);
} }
#ifdef WITH_WARNINGS #ifdef WITH_WARNINGS
#warning Hack! #warning Hack!
#endif #endif
// no newline // no newline
if (yylval.i != -1) if (ival_ != -1)
break; break;
p->appendRow(); p->appendRow();
} }
// restore global variables // restore "global" variables
curr_num = saved_num; curr_num_ = saved_num;
curr_label = saved_label; curr_label_ = saved_label;
} }
MathMacroTemplate * mathed_parse_macro() MathMacroTemplate * Parser::parse_macro()
{ {
if (yylex() != LM_TK_NEWCOMMAND) { if (yylex() != LM_TK_NEWCOMMAND) {
lyxerr << "\\newcommand expected\n"; lyxerr << "\\newcommand expected\n";
@ -404,12 +439,12 @@ MathMacroTemplate * mathed_parse_macro()
string arg = lexArg('['); string arg = lexArg('[');
int narg = arg.empty() ? 0 : atoi(arg.c_str()); int narg = arg.empty() ? 0 : atoi(arg.c_str());
MathMacroTemplate * p = new MathMacroTemplate(name, narg); MathMacroTemplate * p = new MathMacroTemplate(name, narg);
mathed_parse_into(p->cell(0), FLAG_BRACE | FLAG_BRACE_LAST); parse_into(p->cell(0), FLAG_BRACE | FLAG_BRACE_LAST);
return p; return p;
} }
MathMatrixInset * mathed_parse_normal() MathMatrixInset * Parser::parse_normal()
{ {
MathMatrixInset * p = 0; MathMatrixInset * p = 0;
int t = yylex(); int t = yylex();
@ -417,7 +452,7 @@ MathMatrixInset * mathed_parse_normal()
switch (t) { switch (t) {
case LM_TK_MATH: case LM_TK_MATH:
case LM_TK_BEGIN: { case LM_TK_BEGIN: {
int i = yylval.i; int i = ival_;
lyxerr[Debug::MATHED] lyxerr[Debug::MATHED]
<< "reading math environment " << i << " " << "reading math environment " << i << " "
<< latex_mathenv[i].name << "\n"; << latex_mathenv[i].name << "\n";
@ -428,37 +463,37 @@ MathMatrixInset * mathed_parse_normal()
switch (typ) { switch (typ) {
case LM_OT_SIMPLE: { case LM_OT_SIMPLE: {
curr_num = latex_mathenv[i].numbered; curr_num_ = latex_mathenv[i].numbered;
curr_label.erase(); curr_label_.erase();
mathed_parse_into(p->cell(0), 0); parse_into(p->cell(0), 0);
p->numbered(0, curr_num); p->numbered(0, curr_num_);
p->label(0, curr_label); p->label(0, curr_label_);
break; break;
} }
case LM_OT_EQUATION: { case LM_OT_EQUATION: {
curr_num = latex_mathenv[i].numbered; curr_num_ = latex_mathenv[i].numbered;
curr_label.erase(); curr_label_.erase();
mathed_parse_into(p->cell(0), FLAG_END); parse_into(p->cell(0), FLAG_END);
p->numbered(0, curr_num); p->numbered(0, curr_num_);
p->label(0, curr_label); p->label(0, curr_label_);
break; break;
} }
case LM_OT_EQNARRAY: { case LM_OT_EQNARRAY: {
mathed_parse_lines(p, 3, latex_mathenv[i].numbered, true); parse_lines(p, 3, latex_mathenv[i].numbered, true);
break; break;
} }
case LM_OT_ALIGN: { case LM_OT_ALIGN: {
p->halign(lexArg('{')); p->halign(lexArg('{'));
mathed_parse_lines(p, 2, latex_mathenv[i].numbered, true); parse_lines(p, 2, latex_mathenv[i].numbered, true);
break; break;
} }
case LM_OT_ALIGNAT: { case LM_OT_ALIGNAT: {
p->halign(lexArg('{')); p->halign(lexArg('{'));
mathed_parse_lines(p, 2, latex_mathenv[i].numbered, true); parse_lines(p, 2, latex_mathenv[i].numbered, true);
break; break;
} }
@ -479,7 +514,7 @@ MathMatrixInset * mathed_parse_normal()
} }
latexkeys const * read_delim() latexkeys const * Parser::read_delim()
{ {
int ld = yylex(); int ld = yylex();
//lyxerr << "found symbol: " << ld << "\n"; //lyxerr << "found symbol: " << ld << "\n";
@ -489,13 +524,13 @@ latexkeys const * read_delim()
case LM_TK_NOGLYPH: case LM_TK_NOGLYPH:
case LM_TK_SPECIAL: case LM_TK_SPECIAL:
case LM_TK_BEGIN: case LM_TK_BEGIN:
l = yylval.l; l = lval_;
//lyxerr << "found key 1: '" << l << "'\n"; //lyxerr << "found key 1: '" << l << "'\n";
//lyxerr << "found key 1: '" << l->name << "'\n"; //lyxerr << "found key 1: '" << l->name << "'\n";
break; break;
case LM_TK_STR: case LM_TK_STR:
string s; string s;
s += yylval.i; s += ival_;
l = in_word_set(s); l = in_word_set(s);
//lyxerr << "found key 2: '" << l->name << "'\n"; //lyxerr << "found key 2: '" << l->name << "'\n";
} }
@ -503,7 +538,7 @@ latexkeys const * read_delim()
} }
void mathed_parse_into(MathArray & array, unsigned flags) void Parser::parse_into(MathArray & array, unsigned flags)
{ {
static int plevel = -1; static int plevel = -1;
@ -516,8 +551,8 @@ void mathed_parse_into(MathArray & array, unsigned flags)
int limits = 0; int limits = 0;
while (t) { while (t) {
//lyxerr << "t: " << t << " flags: " << flags << " i: " << yylval.i //lyxerr << "t: " << t << " flags: " << flags << " i: " << ival_
// << " '" << yytext << "'\n"; // << " '" << sval_ << "'\n";
//array.dump(lyxerr); //array.dump(lyxerr);
//lyxerr << "\n"; //lyxerr << "\n";
@ -536,7 +571,7 @@ void mathed_parse_into(MathArray & array, unsigned flags)
} }
if ((flags & FLAG_BRACE) && t != LM_TK_OPEN) { if ((flags & FLAG_BRACE) && t != LM_TK_OPEN) {
mathPrintError( error(
"Expected {. Maybe you forgot to enclose an argument in {}"); "Expected {. Maybe you forgot to enclose an argument in {}");
panic = true; panic = true;
break; break;
@ -545,23 +580,23 @@ void mathed_parse_into(MathArray & array, unsigned flags)
switch (t) { switch (t) {
case LM_TK_ALPHA: case LM_TK_ALPHA:
if (!isspace(yylval.i) || yyvarcode == LM_TC_TEXTRM) if (!isspace(ival_) || yyvarcode == LM_TC_TEXTRM)
array.push_back(new MathCharInset(yylval.i, yyvarcode)); array.push_back(new MathCharInset(ival_, yyvarcode));
break; break;
case LM_TK_ARGUMENT: { case LM_TK_ARGUMENT: {
MathMacroArgument * p = new MathMacroArgument(yylval.i); MathMacroArgument * p = new MathMacroArgument(ival_);
p->code(yyvarcode); p->code(yyvarcode);
array.push_back(p); array.push_back(p);
break; break;
} }
case LM_TK_SPECIAL: case LM_TK_SPECIAL:
array.push_back(new MathCharInset(yylval.i, LM_TC_SPECIAL)); array.push_back(new MathCharInset(ival_, LM_TC_SPECIAL));
break; break;
case LM_TK_STR: case LM_TK_STR:
array.push_back(new MathCharInset(yylval.i, LM_TC_CONST)); array.push_back(new MathCharInset(ival_, LM_TC_CONST));
break; break;
case LM_TK_OPEN: case LM_TK_OPEN:
@ -575,7 +610,7 @@ void mathed_parse_into(MathArray & array, unsigned flags)
case LM_TK_CLOSE: case LM_TK_CLOSE:
--brace; --brace;
if (brace < 0) { if (brace < 0) {
mathPrintError("Unmatching braces"); error("Unmatching braces");
panic = true; panic = true;
break; break;
} }
@ -602,17 +637,17 @@ void mathed_parse_into(MathArray & array, unsigned flags)
break; break;
case '^': case '^':
mathed_parse_into( parse_into(
lastScriptInset(array, true, false, limits)->cell(0), FLAG_ITEM); lastScriptInset(array, true, false, limits)->cell(0), FLAG_ITEM);
break; break;
case '_': case '_':
mathed_parse_into( parse_into(
lastScriptInset(array, false, true, limits)->cell(1), FLAG_ITEM); lastScriptInset(array, false, true, limits)->cell(1), FLAG_ITEM);
break; break;
case LM_TK_LIMIT: case LM_TK_LIMIT:
limits = yylval.l->id; limits = lval_->id;
//lyxerr << "setting limit to " << limits << "\n"; //lyxerr << "setting limit to " << limits << "\n";
break; break;
@ -642,42 +677,42 @@ void mathed_parse_into(MathArray & array, unsigned flags)
case LM_TK_NOGLYPH: case LM_TK_NOGLYPH:
case LM_TK_NOGLYPHB: case LM_TK_NOGLYPHB:
limits = 0; limits = 0;
array.push_back(new MathNoglyphInset(yylval.l)); array.push_back(new MathNoglyphInset(lval_));
break; break;
case LM_TK_BIGSYM: case LM_TK_BIGSYM:
limits = 0; limits = 0;
array.push_back(new MathBigopInset(yylval.l)); array.push_back(new MathBigopInset(lval_));
break; break;
case LM_TK_FUNCLIM: case LM_TK_FUNCLIM:
limits = 0; limits = 0;
array.push_back(new MathFuncLimInset(yylval.l)); array.push_back(new MathFuncLimInset(lval_));
break; break;
case LM_TK_SYM: case LM_TK_SYM:
limits = 0; limits = 0;
array.push_back(new MathSymbolInset(yylval.l)); array.push_back(new MathSymbolInset(lval_));
break; break;
case LM_TK_BOP: case LM_TK_BOP:
array.push_back(new MathCharInset(yylval.i, LM_TC_BOP)); array.push_back(new MathCharInset(ival_, LM_TC_BOP));
break; break;
case LM_TK_SPACE: case LM_TK_SPACE:
if (yylval.i >= 0) if (ival_ >= 0)
array.push_back(new MathSpaceInset(yylval.i)); array.push_back(new MathSpaceInset(ival_));
break; break;
case LM_TK_DOTS: case LM_TK_DOTS:
array.push_back(new MathDotsInset(yylval.l)); array.push_back(new MathDotsInset(lval_));
break; break;
case LM_TK_STACK: case LM_TK_STACK:
{ {
MathStackrelInset * p = new MathStackrelInset; MathStackrelInset * p = new MathStackrelInset;
mathed_parse_into(p->cell(0), FLAG_ITEM); parse_into(p->cell(0), FLAG_ITEM);
mathed_parse_into(p->cell(1), FLAG_ITEM); parse_into(p->cell(1), FLAG_ITEM);
array.push_back(p); array.push_back(p);
break; break;
} }
@ -685,23 +720,23 @@ void mathed_parse_into(MathArray & array, unsigned flags)
case LM_TK_FRAC: case LM_TK_FRAC:
{ {
MathFracInset * p = new MathFracInset; MathFracInset * p = new MathFracInset;
mathed_parse_into(p->cell(0), FLAG_ITEM); parse_into(p->cell(0), FLAG_ITEM);
mathed_parse_into(p->cell(1), FLAG_ITEM); parse_into(p->cell(1), FLAG_ITEM);
array.push_back(p); array.push_back(p);
break; break;
} }
case LM_TK_SQRT: case LM_TK_SQRT:
{ {
unsigned char c = getuchar(yyis); unsigned char c = getuchar();
if (c == '[') { if (c == '[') {
array.push_back(new MathRootInset); array.push_back(new MathRootInset);
mathed_parse_into(array.back()->cell(0), FLAG_BRACK_END); parse_into(array.back()->cell(0), FLAG_BRACK_END);
mathed_parse_into(array.back()->cell(1), FLAG_ITEM); parse_into(array.back()->cell(1), FLAG_ITEM);
} else { } else {
yyis->putback(c); is_.putback(c);
array.push_back(new MathSqrtInset); array.push_back(new MathSqrtInset);
mathed_parse_into(array.back()->cell(0), FLAG_ITEM); parse_into(array.back()->cell(0), FLAG_ITEM);
} }
break; break;
} }
@ -710,7 +745,7 @@ void mathed_parse_into(MathArray & array, unsigned flags)
{ {
latexkeys const * l = read_delim(); latexkeys const * l = read_delim();
MathArray ar; MathArray ar;
mathed_parse_into(ar, FLAG_RIGHT); parse_into(ar, FLAG_RIGHT);
latexkeys const * r = read_delim(); latexkeys const * r = read_delim();
MathDelimInset * dl = new MathDelimInset(l, r); MathDelimInset * dl = new MathDelimInset(l, r);
dl->cell(0) = ar; dl->cell(0) = ar;
@ -723,12 +758,12 @@ void mathed_parse_into(MathArray & array, unsigned flags)
--plevel; --plevel;
return; return;
} }
mathPrintError("Unmatched right delimiter"); error("Unmatched right delimiter");
// panic = true; // panic = true;
break; break;
case LM_TK_FONT: case LM_TK_FONT:
yyvarcode = static_cast<MathTextCodes>(yylval.l->id); yyvarcode = static_cast<MathTextCodes>(lval_->id);
flags |= (FLAG_BRACE | FLAG_BRACE_FONT); flags |= (FLAG_BRACE | FLAG_BRACE_FONT);
break; break;
@ -736,38 +771,37 @@ void mathed_parse_into(MathArray & array, unsigned flags)
{ {
lyxerr[Debug::MATHED] << "LM_TK_STY not implemented\n"; lyxerr[Debug::MATHED] << "LM_TK_STY not implemented\n";
//MathArray tmp = array; //MathArray tmp = array;
//MathSizeInset * p = new MathSizeInset(MathStyles(yylval.l->id)); //MathSizeInset * p = new MathSizeInset(MathStyles(lval_->id));
//array.push_back(p); //array.push_back(p);
//mathed_parse_into(p->cell(0), FLAG_BRACE_FONT); //parse_into(p->cell(0), FLAG_BRACE_FONT);
break; break;
} }
case LM_TK_DECORATION: case LM_TK_DECORATION:
{ {
MathDecorationInset * p = new MathDecorationInset(yylval.l); MathDecorationInset * p = new MathDecorationInset(lval_);
mathed_parse_into(p->cell(0), FLAG_ITEM); parse_into(p->cell(0), FLAG_ITEM);
array.push_back(p); array.push_back(p);
break; break;
} }
case LM_TK_NONUM: case LM_TK_NONUM:
curr_num = false; curr_num_ = false;
break; break;
case LM_TK_FUNC: case LM_TK_FUNC:
array.push_back(new MathSymbolInset(yylval.l)); array.push_back(new MathSymbolInset(lval_));
break; break;
case LM_TK_UNDEF: case LM_TK_UNDEF:
if (MathMacroTable::hasTemplate(yytext)) { if (MathMacroTable::hasTemplate(sval_)) {
MathMacro * m = MathMacroTable::cloneTemplate(yytext); MathMacro * m = MathMacroTable::cloneTemplate(sval_);
for (int i = 0; i < m->nargs(); ++i) for (int i = 0; i < m->nargs(); ++i)
mathed_parse_into(m->cell(i), FLAG_ITEM); parse_into(m->cell(i), FLAG_ITEM);
array.push_back(m); array.push_back(m);
m->metrics(LM_ST_TEXT); m->metrics(LM_ST_TEXT);
} else } else
array.push_back(new MathFuncInset(yytext)); array.push_back(new MathFuncInset(sval_));
break; break;
case LM_TK_MATH: case LM_TK_MATH:
@ -777,7 +811,7 @@ void mathed_parse_into(MathArray & array, unsigned flags)
case LM_TK_BEGIN: case LM_TK_BEGIN:
{ {
int i = yylval.i; int i = ival_;
MathInsetTypes typ = latex_mathenv[i].typ; MathInsetTypes typ = latex_mathenv[i].typ;
if (typ == LM_OT_MATRIX) { if (typ == LM_OT_MATRIX) {
@ -789,7 +823,7 @@ void mathed_parse_into(MathArray & array, unsigned flags)
m->valign(valign[0]); m->valign(valign[0]);
m->halign(halign); m->halign(halign);
mathed_parse_lines(m, halign.size(), latex_mathenv[i].numbered, false); parse_lines(m, halign.size(), latex_mathenv[i].numbered, false);
array.push_back(m); array.push_back(m);
//lyxerr << "read matrix " << *m << "\n"; //lyxerr << "read matrix " << *m << "\n";
break; break;
@ -799,16 +833,16 @@ void mathed_parse_into(MathArray & array, unsigned flags)
} }
case LM_TK_MACRO: case LM_TK_MACRO:
array.push_back(MathMacroTable::cloneTemplate(yylval.l->name)); array.push_back(MathMacroTable::cloneTemplate(lval_->name));
break; break;
case LM_TK_LABEL: case LM_TK_LABEL:
curr_label = lexArg('{', true); curr_label_ = lexArg('{', true);
break; break;
default: default:
mathPrintError("Unrecognized token"); error("Unrecognized token");
lyxerr[Debug::MATHED] << "[" << t << " " << yytext << "]" << endl; lyxerr[Debug::MATHED] << "[" << t << " " << sval_ << "]" << endl;
break; break;
} // end of big switch } // end of big switch
@ -823,7 +857,7 @@ void mathed_parse_into(MathArray & array, unsigned flags)
// Search for the end command. // Search for the end command.
do { do {
t = yylex(); t = yylex();
} while (yyis->good() && t != LM_TK_END && t); } while (is_.good() && t != LM_TK_END && t);
} else { } else {
t = yylex(); t = yylex();
} }
@ -831,10 +865,11 @@ void mathed_parse_into(MathArray & array, unsigned flags)
--plevel; --plevel;
} }
void mathed_parse_end(LyXLex & lex)
void parse_end(LyXLex & lex, int lineno)
{ {
// Update line number // Update line number
lex.setLineNo(yylineno); lex.setLineNo(lineno);
// reading of end_inset // reading of end_inset
while (lex.isOK()) { while (lex.isOK()) {
@ -846,16 +881,16 @@ void mathed_parse_end(LyXLex & lex)
} }
} }
} } // anonymous namespace
MathArray mathed_parse_cell(string const & str) MathArray mathed_parse_cell(string const & str)
{ {
istringstream is(str.c_str()); istringstream is(str.c_str());
yyis = &is; Parser parser(is);
yylineno = 0;
MathArray ar; MathArray ar;
mathed_parse_into(ar, 0); parser.parse_into(ar, 0);
return ar; return ar;
} }
@ -864,22 +899,21 @@ MathArray mathed_parse_cell(string const & str)
MathMacroTemplate * mathed_parse_macro(string const & str) MathMacroTemplate * mathed_parse_macro(string const & str)
{ {
istringstream is(str.c_str()); istringstream is(str.c_str());
return mathed_parse_macro(is); Parser parser(is);
return parser.parse_macro();
} }
MathMacroTemplate * mathed_parse_macro(istream & is) MathMacroTemplate * mathed_parse_macro(istream & is)
{ {
yyis = &is; Parser parser(is);
yylineno = 0; return parser.parse_macro();
return mathed_parse_macro();
} }
MathMacroTemplate * mathed_parse_macro(LyXLex & lex) MathMacroTemplate * mathed_parse_macro(LyXLex & lex)
{ {
yyis = &lex.getStream(); Parser parser(lex);
yylineno = lex.getLineNo(); MathMacroTemplate * p = parser.parse_macro();
MathMacroTemplate * p = mathed_parse_macro(); parse_end(lex, parser.lineno());
mathed_parse_end(lex);
return p; return p;
} }
@ -888,22 +922,21 @@ MathMacroTemplate * mathed_parse_macro(LyXLex & lex)
MathMatrixInset * mathed_parse_normal(string const & str) MathMatrixInset * mathed_parse_normal(string const & str)
{ {
istringstream is(str.c_str()); istringstream is(str.c_str());
return mathed_parse_normal(is); Parser parser(is);
return parser.parse_normal();
} }
MathMatrixInset * mathed_parse_normal(istream & is) MathMatrixInset * mathed_parse_normal(istream & is)
{ {
yyis = &is; Parser parser(is);
yylineno = 0; return parser.parse_normal();
return mathed_parse_normal();
} }
MathMatrixInset * mathed_parse_normal(LyXLex & lex) MathMatrixInset * mathed_parse_normal(LyXLex & lex)
{ {
yyis = &lex.getStream(); Parser parser(lex);
yylineno = lex.getLineNo(); MathMatrixInset * p = parser.parse_normal();
MathMatrixInset * p = mathed_parse_normal(); parse_end(lex, parser.lineno());
mathed_parse_end(lex);
return p; return p;
} }