/* * File: math_parser.C * Purpose: Parser for mathed * Author: Alejandro Aguilar Sierra <asierra@servidor.unam.mx> * Created: January 1996 * Description: Parse LaTeX2e math mode code. * * Dependencies: Xlib, XForms * * Copyright: (c) 1996, Alejandro Aguilar Sierra * * Version: 0.8beta. * * You are free to use and modify this code under the terms of * the GNU General Public Licence version 2 or later.
*/
enum {
FLAG_BRACE = 1, // A { needed
FLAG_BRACE_ARG = 2, // Next { is argument
FLAG_BRACE_OPT = 4, // Optional {
FLAG_BRACE_LAST = 8, // Last } ends the parsing process
FLAG_BRACK_ARG = 16, // Optional [
FLAG_RIGHT = 32, // Next right ends the parsing process
FLAG_END = 64, // Next end ends the parsing process
FLAG_BRACE_FONT = 128 // Next } closes a font
};
for (int i=accent-1; i>=0; i--) { if (i==accent-1)
ac = new MathAccentInset(c, t, nestaccent[i]); else
ac = new MathAccentInset(ac, nestaccent[i]);
}
accent = 0; // consumed!
for (int i=accent-1; i>=0; i--) { if (i==accent-1)
ac = new MathAccentInset(p, nestaccent[i]); else
ac = new MathAccentInset(ac, nestaccent[i]);
}
accent = 0; // consumed!
int brace = 0; int acc_brace = 0; int acc_braces[8];
MathParInset *mt = (mtx) ? *mtx: 0;//(MathParInset*)NULL;
MathedRowSt *crow = (mt) ? mt->getRowSt(): 0;
plevel++; if (!array) array = new LyxArrayBase;
MathedIter data(array); while (t) { if ((flags & FLAG_BRACE) && t != LM_TK_OPEN) { if ((flags & FLAG_BRACK_ARG) && t=='[') {
} else {
mathPrintError("Expected {. Maybe you forgot to enclose an argument in {}");
panic = true; break;
}
}
MathedInsetTypes fractype = LM_OT_FRAC; switch (t) { case LM_TK_ALPHA:
{ if (accent) {
data.Insert(doAccent(yylval.i, varcode));
} else
data.Insert (yylval.i, varcode); //LM_TC_VAR); break;
} case LM_TK_ARGUMENT:
{ if (macro) {
data.Insert(macro->getMacroPar(yylval.i-1), LM_TC_INSET);
} break;
} case LM_TK_NEWCOMMAND:
{ int na = 0;
LexGetArg('{'); // This name lives until quitting, for that reason // I didn't care on deleting explicitly. Later I will. charconst *name = strnew(&yytext[1]); // ugly trick to be removed soon (lyx3) char c = getc(yyin);
ungetc(c, yyin); if (c=='[') {
LexGetArg('[');
na = atoi(yytext);
}
macro = new MathMacroTemplate(name, na);
flags = FLAG_BRACE|FLAG_BRACE_LAST;
*mtx = macro;
macro->SetData(array); break;
} case LM_TK_SPECIAL:
{
data.Insert (yylval.i, LM_TC_SPECIAL); break;
} case LM_TK_STR:
{ if (accent) {
data.Insert(doAccent(yylval.i, LM_TC_CONST));
} else
data.Insert (yylval.i, LM_TC_CONST); break;
} case LM_TK_OPEN:
{
brace++; if (accent && tprev==LM_TK_ACCENT) {
acc_braces[acc_brace++] = brace; break;
} if (flags & FLAG_BRACE_OPT) {
flags &= ~FLAG_BRACE_OPT;
flags |= FLAG_BRACE;
}
case LM_TK_LIMIT:
{ if (binset) {
binset->SetLimits((bool)(yylval.l->id));
binset = NULL;
} break;
}
case'&': // Tab
{ if ((flags & FLAG_END) && mt && data.getCol()<mt->GetColumns()-1) {
data.setNumCols(mt->GetColumns());
data.Insert('T', LM_TC_TAB);
} else
mathPrintError("Unexpected tab"); // debug info. [made that conditional -JMarc] if (lyxerr.debugging(Error::MATHED))
fprintf(stderr, "%d %d\n", data.getCol(), mt->GetColumns()); break;
} case LM_TK_NEWLINE:
{ if (mt && (flags & FLAG_END)) { if (mt->Permit(LMPF_ALLOW_CR)) { if (crow) {
crow->setNext(new MathedRowSt(mt->GetColumns()+1)); // this leaks
crow = crow->getNext();
}
data.Insert('K', LM_TC_CR);
} else
mathPrintError("Unexpected newline");
} break;
} case LM_TK_BIGSYM:
{
binset = new MathBigopInset(yylval.l->name,yylval.l->id);
data.Insert(binset); break;
} case LM_TK_SYM:
{ if (yylval.l->id < 256) {
MathedTextCodes tc = MathIsBOPS(yylval.l->id) ? LM_TC_BOPS: LM_TC_SYMB; if (accent) {
data.Insert(doAccent(yylval.l->id, tc));
} else
data.Insert (yylval.l->id, tc);
} else {
MathFuncInset *bg = new MathFuncInset(yylval.l->name); if (accent) {
data.Insert(doAccent(bg));
} else
data.Insert(bg, true);
} break;
} case LM_TK_BOP:
{ if (accent) {
data.Insert(doAccent(yylval.i, LM_TC_BOP));
} else
data.Insert (yylval.i, LM_TC_BOP); break;
} case LM_TK_STY:
{ if (mt) {
mt->UserSetSize(yylval.l->id);
} break;
} case LM_TK_SPACE:
{ if (yylval.i>=0) {
MathSpaceInset *sp = new MathSpaceInset(yylval.i);
data.Insert(sp);
} break;
} case LM_TK_DOTS:
{
MathDotsInset *p = new MathDotsInset(yylval.l->name, yylval.l->id);
data.Insert(p); break;
} case LM_TK_STACK:
fractype = LM_OT_STACKREL; case LM_TK_FRAC:
{
MathFracInset *fc = new MathFracInset(fractype);
LyxArrayBase* num = mathed_parse(FLAG_BRACE|FLAG_BRACE_LAST);
LyxArrayBase* den = mathed_parse(FLAG_BRACE|FLAG_BRACE_LAST);
fc->SetData(num, den);
data.Insert(fc, LM_TC_ACTIVE_INSET); break;
} case LM_TK_SQRT:
{
MathSqrtInset *sq = new MathSqrtInset(size);
sq->SetData(mathed_parse(FLAG_BRACE|FLAG_BRACE_LAST, 0, (MathParInset **)&sq));
data.Insert(sq, LM_TC_ACTIVE_INSET); break;
}
case LM_TK_LEFT:
{ int lfd, rgd;
lfd=yylex(); if (lfd==LM_TK_SYM || lfd==LM_TK_STR || lfd==LM_TK_BOP|| lfd==LM_TK_SPECIAL)
lfd = (lfd==LM_TK_SYM) ? yylval.l->id: yylval.i; // fprintf(stderr, "L[%d %c]", lfd, lfd);
LyxArrayBase* a = mathed_parse(FLAG_RIGHT);
rgd=yylex(); // fprintf(stderr, "R[%d]", rgd); if (rgd==LM_TK_SYM || rgd==LM_TK_STR || rgd==LM_TK_BOP || rgd==LM_TK_SPECIAL)
rgd = (rgd==LM_TK_SYM) ? yylval.l->id: yylval.i;
MathDelimInset *dl = new MathDelimInset(lfd, rgd);
dl->SetData(a);
data.Insert(dl, LM_TC_ACTIVE_INSET); // fprintf(stderr, "RL[%d %d]", lfd, rgd); break;
} case LM_TK_RIGHT:
{ if (flags & FLAG_RIGHT) {
plevel--; return array;
} else {
mathPrintError("Unmatched right delimiter"); // panic = true;
} break;
}
case LM_TK_FONT:
{
varcode = (MathedTextCodes)yylval.l->id;
yy_mtextmode = (bool)(varcode==LM_TC_TEXTRM);
flags |= (FLAG_BRACE|FLAG_BRACE_FONT); break;
} case LM_TK_WIDE:
{
MathDecorationInset *sq = new MathDecorationInset(yylval.l->id, size);
sq->SetData(mathed_parse(FLAG_BRACE|FLAG_BRACE_LAST));
data.Insert(sq, LM_TC_ACTIVE_INSET); break;
}
case LM_TK_ACCENT: setAccent(yylval.l->id); break;
case LM_TK_NONUM:
{ if (crow)
crow->setNumbered(false); break;
}
case LM_TK_PMOD: case LM_TK_FUNC:
{
MathedInset *bg = new MathFuncInset(yylval.l->name); if (accent) {
data.Insert(t);
} else
data.Insert(bg); break;
} case LM_TK_FUNCLIM:
{
data.Insert(new MathFuncInset(yylval.l->name, LM_OT_FUNCLIM)); break;
} case LM_TK_UNDEF:
{
MathMacro* p =
MathMacroTable::mathMTable.getMacro(yylval.s); if (p) { if (accent)
data.Insert(doAccent(p), p->getTCode()); else
data.Insert(p, p->getTCode()); for (int i=0; p->setArgumentIdx(i); i++)
p->SetData(mathed_parse(FLAG_BRACE|FLAG_BRACE_LAST));
} else {
MathedInset *q = new MathFuncInset(yylval.s, LM_OT_UNDEF); if (accent) {
data.Insert(doAccent(q));
} else {
data.Insert(q);
}
} break;
} case LM_TK_END:
{ if (mathed_env != yylval.i && yylval.i!=LM_EN_ARRAY)
mathPrintError("Unmatched environment"); // debug info [made that conditional -JMarc] if (lyxerr.debugging(Error::MATHED))
fprintf(stderr, "[%d]\n", yylval.i);
plevel--; if (mt) { // && (flags & FLAG_END)) {
mt->SetData(array);
array = NULL;
} return array;
} case LM_TK_BEGIN:
{ if (yylval.i==LM_EN_ARRAY) { char ar[120], ar2[8];
ar[0] = ar2[0] = '\0'; char rg=LexGetArg(0); if (rg==']') {
strcpy(ar2, yytext);
rg = LexGetArg('{');
}
strcpy(ar, yytext); int nc = parse_align(ar, ar2);
MathParInset* mm = new MathMatrixInset(nc, 0);
mm->SetAlign(ar2[0], ar);
data.Insert(mm, LM_TC_ACTIVE_INSET);
mathed_parse(FLAG_END, mm->GetData(), &mm);
} else if (yylval.i>=LM_EN_INTEXT && yylval.i<=LM_EN_EQNARRAY) { if (plevel!=0) {
mathPrintError("Misplaced environment"); break;
} if (!mt) {
mathPrintError("NULL paragraph.");
panic = true;
}
case LM_TK_MACRO:
{
MathedInset* p =
MathMacroTable::mathMTable.getMacro(yylval.l->name);
if (p) { if (accent) {
data.Insert(doAccent(p));
} else
data.Insert(p, ((MathMacro*)p)->getTCode());
} break;
}
case LM_TK_LABEL:
{ char rg = LexGetArg('\0', true); if (rg != '}') {
mathPrintError("Expected '{'"); // debug info
fprintf(stderr, "[%s]\n", yytext); fflush(stderr);
panic = true; break;
} if (crow) { // This is removed by crow's destructor. Bad design? yes, this // will be changed after 0.12
crow->setLabel(strnew(yytext));
} else { // where is this math_label free'ed? // Supposedly in ~formula, another bad hack, // give me some time please.
mathed_label = strnew(yytext);
} #ifdef DEBUG
fprintf(stderr, "Label[%d]\n", mathed_label); #endif break;
} default:
mathPrintError("Unrecognized token"); // debug info
fprintf(stderr, "[%d %s]\n", t, yytext); break;
}
tprev = t; if (panic) {
fprintf(stderr, " Math Panic, expect problems!\n"); // Search for the end command. do t = yylex (); while (t != LM_TK_END && t);
} else
t = yylex ();
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.