/*
*
* (c) COPYRIGHT INRIA and W3C, 2009
* Please first read the full copyright statement in file COPYRIGHT.
*
*/
/*
*
* Author: F. Wang
*/
%defines
%define "parser_class_name" "chemistry"
%pure-parser
%lex-param {quex::chemistry *qlex}
%parse-param {quex::chemistry *qlex}
%name-prefix="chemistry"
%{
#include "chemistry"
#include <iostream>
#include <math.h>
extern Element parser_new_el;
extern Document parser_doc;
extern Element NewSymbol(Document doc, int elTypeNum, CHAR_T symbol);
extern Element NewMathElement(Document doc, int elTypeNum, const char *string);
extern Element NewMROW(Document doc);
extern Element NewMSUP(Document doc, Element base, Element supscript);
extern Element NewMSUB(Document doc, Element base, Element subscript);
extern Element NewFencedExpression(Document doc, Element el, const char *open,
const char *close);
%}
%{
int chemistrylex(YYSTYPE *yylval, quex::chemistry *qlex);
void chemistryerror(quex::chemistry *qlex, const std::string& m);
%}
%union
{
};
%union {
Element node;
char *string;
}
%token<string> ATOM_Y
%token<string> INTEGER
%token<string> OXIDATION_NUMBER
%token<string> SIMPLE_BOND
%token<string> DOUBLE_BOND
%token<string> TRIPLE_BOND
%token<string> QUADRUPLE_BOND
%token<string> GENERIC_BOND
%token<string> DOT
%token<string> UNKNOWN_TOKEN
%type<node> atom
%type<node> atom2
%type<node> integer
%type<node> oxidation_number
%type<node> sign
%type<node> chemical_compound
%type<node> chemical_compound2
%type<node> chemical_entity
%type<node> chemical_entity2
%type<node> ionic_charge
%type<node> bond
%type<node> simple_bond
%type<node> double_bond
%type<node> triple_bond
%type<node> quadruple_bond
%type<node> generic_bond
%type<node> dot
%start result
%expect 1
%destructor {
printf("Element deleted\n");
TtaDeleteTree($$, parser_doc);
} atom atom2 integer oxidation_number sign chemical_compound chemical_compound2 chemical_entity chemical_entity2 ionic_charge bond simple_bond double_bond triple_bond quadruple_bond generic_bond dot
%%
result
:chemical_compound
{
parser_new_el = $1;
}
;
chemical_compound
: chemical_compound2 ionic_charge { $$ = NewMSUP(parser_doc, $1, $2); }
| chemical_compound2 { $$ = $1; }
;
chemical_compound2
: chemical_compound2 chemical_entity
{
Element leaf;
leaf = TtaGetLastChild($1);
TtaInsertSibling($2, leaf, FALSE, parser_doc);
$$ = $1;
}
| chemical_entity
{
$$ = NewMROW(parser_doc);
TtaInsertFirstChild(&($1), $$, parser_doc);
}
;
chemical_entity
:chemical_entity2 integer { $$ = NewMSUB(parser_doc, $1, $2); }
| chemical_entity2 { $$ = $1; }
| '[' chemical_compound2 ']'
{
$$ = NewFencedExpression(parser_doc, $2, "[", "]");
}
| bond { $$ = $1; }
| dot { $$ = $1; }
;
chemical_entity2
: atom { $$ = $1 }
| '(' chemical_compound2 ')'
{
$$ = NewFencedExpression(parser_doc, $2, "(", ")");
}
| '{' chemical_compound2 '}' { $$ = $2; }
;
ionic_charge
:integer sign
{
$$ = NewMROW(parser_doc);
TtaInsertFirstChild(&($1), $$, parser_doc);
TtaInsertSibling($2, $1, FALSE, parser_doc);
}
| sign { $$ = $1; }
| '*' { $$ = NewSymbol(parser_doc, MathML_EL_MO, '*'); }
;
integer:
INTEGER { $$ = NewMathElement(parser_doc, MathML_EL_MN, $1); }
;
atom
:atom2 { $$ = $1; }
|atom2 oxidation_number { $$ = NewMSUP(parser_doc, $1, $2); }
;
atom2:
ATOM_Y { $$ = NewMathElement(parser_doc, MathML_EL_MI, $1); }
;
oxidation_number:
OXIDATION_NUMBER { $$ = NewMathElement(parser_doc, MathML_EL_MTEXT, $1); }
;
bond
: simple_bond { $$ = $1; }
| double_bond { $$ = $1; }
| triple_bond { $$ = $1; }
| quadruple_bond { $$ = $1; }
| generic_bond { $$ = $1; }
simple_bond
: SIMPLE_BOND { $$ = NewSymbol(parser_doc, MathML_EL_MO, '-');}
double_bond
: DOUBLE_BOND { $$ = NewSymbol(parser_doc, MathML_EL_MO, '=');}
triple_bond
: TRIPLE_BOND { $$ = NewSymbol(parser_doc, MathML_EL_MO, 0x2261);}
quadruple_bond
: QUADRUPLE_BOND { $$ = NewSymbol(parser_doc, MathML_EL_MO, 0x2263);}
generic_bond
: GENERIC_BOND { $$ = NewSymbol(parser_doc, MathML_EL_MO, 0x20dB); }
sign
: '+' { $$ = NewSymbol(parser_doc, MathML_EL_MO, '+'); }
| '-' { $$ = NewSymbol(parser_doc, MathML_EL_MO, 0x2212); }
;
dot
: DOT { $$ = NewSymbol(parser_doc, MathML_EL_MO, 0x00b7); }
%%
void chemistryerror(quex::chemistry *qlex, const std::string& m)
{
std::cout << "Parsing error at " << qlex->line_number()
<< ":" << qlex->column_number() << " : " << m;
}
int chemistrylex(YYSTYPE *yylval, quex::chemistry *qlex)
{
quex::Token token;
qlex->receive(&token);
if (token.text().length()>0)
{
yylval->string = (char *)token.text().c_str();
}
return (int)token.type_id();
}
Webmaster