Commit d38d62b0 authored by Frank B. Brokken's avatar Frank B. Brokken

Imported Upstream version 5.00.00

parent 789db5af
......@@ -53,8 +53,8 @@
// the directory where the standard documentation is stored
#define DOC "/usr/share/doc/"${PROGRAM}
// the directory whre the manual page is stored
#define MAN "/usr/share/man/man1"
// the directory below where the man pages are stored
#define MAN "/usr/share/man"
// the directory whre the user-guide is stored
#define UGUIDE "/usr/share/doc/"${PROGRAM}"-doc/manual"
......
enum class Tag__
defines the tags that are associated with the various semantic value
types. Examples of tags:
VECTOR,
TEXTTYPE,
namespace Meta__
1. defines struct templates TagOf that, when provided with the actual data
types, provide the associated Tag__ as
TagOf<data-type>::tag
Example:
template <>
struct TagOf<FlexTypes::TextType>
{
static Tag__ const tag = Tag__::TEXTTYPE;
};
2. defines struct templates TypeOf that, when provided with a tag,
provides the associated data type as
typename TypeOf<Tag__>::type
Example:
template <>
struct TypeOf<Tag__::VECTOR>
{
typedef std::vector<std::string> type;
};
The semantic polymorphic value is available as STYPE__ inside the parser:
typedef Meta__::SType STYPE__;
The struct Stype holds a shared_ptr to a Base class object.
SType::get<Tag__>() returns the data type of the stored value
(so, the tag is available).
Given an Stype variable (like d_val__), it can be used to assign a value
of the requested type:
d_val__.get<Tag__::TEXTTYPE>() = d_matched.
If a rhs value is available, then it is known as a Semantic *, and it can
be assigned to the SType object.
The free functions (in the parser's namespace (if defined)) semantic__ can
be used to obtain a Semantic *.
All semantic values are stored in class template Semantic objects. Semantic is
derived from Base, and must be initialized with a Tag__. The Tag__ allows
Semantic to define a DataType (via TypeOf<Tag__>) and
Semantic has as data() const member returning a const reference to its
value
The class Base is Semantic's base class. A pointer to a Base class can use
members
tag() to obtain the value's tag;
get<Tag__>() to obtain a (const or non-const) reference to the
data stored in the Semantic object. Internallly, as the known, and since
Base is a base class of Semantic, it can statically cast this (the Base
class pointer to a Semantic<tag> pointer.
Assignment (Stype = value) is handled by a member template operator=(Tp &&arg)
The Base class implements polymorphism without using virtual
functions. This is realized by defining interface functions that can be called
from Base & or Base * objects. These functions then call a function via a
pointer to function (e.g., clone() calls the function pointed to by
d_baseClone. Those functions are static functions, expecting a pointer to a
Base const object. Derived classes initialize the pointers to function with
the address of their own function. When clone() is called, the Base object
passes its own address as argument to d_baseClone. If the Base object was
derived from, e.g., Semantic<Tag__::INT>, then the Base pointer is also a
pointer to Semantic<Tag__::INT>. As the derived class (Semantic<Tag__::INT>)
has assigned the address of its own clone function to d_baseClone,
Semantic<Tag__::INT>'s clone function is called. It defines a Base const *
parameter, but it knows that it has been called with a pointer to a
Semantic<Tag__::INT>, and therefore it can safely static_cast the Base const *
to a Semantic<Tag__::INT> *, if needed.
Base:
d_baseClone: ptr to static member function
clone(): calls d_baseClone(this)
Semantic<Tag__>
implements static member clone, having Base::d_baseClone's
prototype.
at construction time: assigns &clone to d_baseClone
run-time call:
Base::clone() is called, calling
d_basClone(this) where 'this' is the address of the actual
Semantic object
d_baseClone points to Semantic<Tag__>'s clone,
Semantic<Tag__>::clone is called, statically casting its Base *
parameter to a Semantic<Tag__> *
%polymorphic and %union support tag/field checks. Correct type assignments for
missing rules is checked in parser/handleproductionelement.cc and
parser/checkemptyblocktype.cc
See also parser/indextooffset.cc for a description how $-indices are converted
to offsets.
#define VERSION "4.13.01"
#define YEARS "2005-2015"
#define VERSION "5.00.00"
#define YEARS "2005-2016"
#include "atdollar.ih"
AtDollar::Action AtDollar::action() const
{
if (d_nr == numeric_limits<int>::max())
return d_id.length() ? TYPED_RETURN_VALUE : RETURN_VALUE;
return d_id.length() ? TYPED_NUMBERED_ELEMENT : NUMBERED_ELEMENT;
}
......@@ -10,58 +10,83 @@ class AtDollar
friend std::ostream &operator<<(std::ostream &out, AtDollar const &atd);
public:
enum Type
{
AT,
DOLLAR
};
enum Action
{
RETURN_VALUE,
NUMBERED_ELEMENT,
TYPED_RETURN_VALUE,
TYPED_NUMBERED_ELEMENT
};
// Pattern is determined by the constructor
// Update stackElement if another $$ or @@ element is added
enum Pattern // A: at, D represents $, ref: (), _: -nr, n: nr
{ // m (= member): . p (= pointer) -> t: <TAG>
// par (open parenthesis)
AA, // @@
An, // @nr
DD, // $$
refDD, // _$$
DDm, // $$.
DDp, // $$->
Dn, // $nr
refDn, // _$nr
Dnm, // $nr.
Dnp, // $nr->
D_, // $-nr
refD_, // _$-nr
D_m, // $-nr.
D_p, // $-nr->
Dt_, // $<TAG>-nr
Dt_m, // $<TAG>-nr.
Dt_p, // $<TAG>-nr->
DDpar, // $$(
};
private:
Type d_type;
size_t d_lineNr;
size_t d_pos;
size_t d_length;
size_t d_lineNr;
std::string d_text;
std::string d_id;
int d_nr; // $$ if numeric_limits<int>::max()
bool d_member;
bool d_stype;
size_t d_length;
Pattern d_pattern;
std::string d_tag;
bool d_refByScanner; // scanner.assignment substututed
// $$ ($nr) by _$$ (_$nr)
// $$ or @@ if numeric_limits<int>::max()
int d_nr = std::numeric_limits<int>::max();
public:
AtDollar() = default; // only used by std::vector in Block
// 1 $$, $$., $NR, $NR., @@ or @NR
AtDollar(Type type, size_t blockPos, size_t lineNr,
std::string const &text, int nr, bool member);
// 3 $<ID>$ or $<ID>-?NR
AtDollar(Type type, size_t blockPos, size_t lineNr,
std::string const &text, std::string const &id, int nr);
Type type() const;
int nr() const;
std::string const &text() const;
std::string const &id() const;
size_t pos() const;
size_t length() const;
size_t lineNr() const;
Action action() const;
bool callsMember() const;
bool returnValue() const; // $$ is being referred to
bool stype() const; // id == STYPE__
AtDollar(size_t blockPos, size_t lineNr, std::string const &text,
bool refByScanner);
Pattern pattern() const;
int nr() const; // nr used in $nr constructions
std::string const &text() const;// the matched text
std::string const &tag() const; // ID in $<ID>.. constructions
size_t pos() const; // offset inside the block
size_t length() const; // matched text length
size_t lineNr() const; // line nr in the grammar file
bool refByScanner() const; // ref. inserted scanner.assignment()
bool stackElement() const; // referring to an element in the
// stack, so not $$ or @@
private:
void setTagNr(size_t idx); // idx beyond <
void setAtPatterns(); // text[0] == '@'
void setRefPatterns(); // text[0] == '_'
void setDollarPatterns(); // text[0] == '$'
void setDollarDollarPatterns();
void setTagPatterns();
void setNumberPatterns();
};
inline AtDollar::Type AtDollar::type() const
inline AtDollar::Pattern AtDollar::pattern() const
{
return d_type;
return d_pattern;
}
inline int AtDollar::nr() const
......@@ -69,19 +94,9 @@ inline int AtDollar::nr() const
return d_nr;
}
inline bool AtDollar::callsMember() const
{
return d_member;
}
inline bool AtDollar::returnValue() const
{
return d_nr == std::numeric_limits<int>::max();
}
inline bool AtDollar::stype() const
inline bool AtDollar::refByScanner() const
{
return d_stype;
return d_refByScanner;
}
inline size_t AtDollar::pos() const
......@@ -104,9 +119,9 @@ inline std::string const &AtDollar::text() const
return d_text;
}
inline std::string const &AtDollar::id() const
inline std::string const &AtDollar::tag() const
{
return d_id;
return d_tag;
}
#endif
......
#include "atdollar.ih"
// ${NR}, ${NR}. or @{NR}
AtDollar::AtDollar(Type type,
size_t blockPos, size_t lineNr, std::string const &text,
int nr, bool member)
AtDollar::AtDollar(size_t blockPos, size_t lineNr, std::string const &text,
bool refByScanner)
:
d_type(type),
d_lineNr(lineNr),
d_pos(blockPos),
d_length(text.length() - member),
d_lineNr(lineNr),
d_text(text),
d_nr(nr),
d_member(member),
d_stype(false)
{}
d_length(text.length()),
d_refByScanner(refByScanner)
{
switch (text[0])
{
case '$':
setDollarPatterns();
return;
case '_':
setRefPatterns();
return;
case '@':
setAtPatterns();
return;
}
}
// // ${NR}, ${NR}. or @{NR}
//
//AtDollar::AtDollar(Type type,
// size_t blockPos, size_t lineNr, std::string const &text,
// int nr)
//:
// d_type(type),
// d_lineNr(lineNr),
// d_pos(blockPos),
// d_length(text.length()),
// d_text(text),
// d_nr(nr)
//{
// suffixAndMember();
//}
#include "atdollar.ih"
// $<ID>$ or $<ID>-?NR
AtDollar::AtDollar(Type type, size_t blockPos, size_t lineNr,
string const &text, string const &id, int nr)
:
d_type(type),
d_lineNr(lineNr),
d_pos(blockPos),
d_length(text.length()),
d_text(text),
d_id(id.empty() ? "STYPE__" : id),
d_nr(nr),
d_member(false),
d_stype(d_id == "STYPE__")
{}
......@@ -3,20 +3,19 @@
std::ostream &operator<<(std::ostream &out, AtDollar const &atd)
{
out << "At line " << atd.d_lineNr << ", block pos. " << atd.d_pos <<
", length: " << atd.d_length << ": " <<
(atd.d_type == AtDollar::AT ? '@' : '$');
", length: " << atd.d_length << ": `" <<
atd.text() << "' (Pattern = " << atd.d_pattern << ')';
if (atd.d_id.length())
out << '<' << atd.d_id << '>';
if (atd.d_tag.length())
out << "; <" << atd.d_tag << '>';
if (atd.d_nr == numeric_limits<int>::max())
out << '$';
out << " $";
else
out << atd.d_nr;
out << ' ' << atd.d_nr;
if (atd.d_member)
out << ". (member call)";
if (atd.d_refByScanner)
out << " (ref. by scanner)";
return out;
}
#include "atdollar.ih"
void AtDollar::setAtPatterns() // text[0] == '@'
{
if (d_text[1] == '@')
d_pattern = AA;
else
{
d_pattern = An;
d_nr = stol(d_text.substr(1));
}
}
#include "atdollar.ih"
// DD, // $$
// DDm, // $$.
// DDp, // $$->
// DDpar, // $$(
void AtDollar::setDollarDollarPatterns()
{
switch (d_text.back())
{
case '$':
d_pattern = DD;
return;
case '.':
d_pattern = DDm;
return;
case '>':
d_pattern = DDp;
return;
case '(':
d_pattern = DDpar;
return;
}
}
#include "atdollar.ih"
// DD, // $$
// DDm, // $$.
// DDp, // $$->
// DDpar, // $$(
//
// Dn, // $nr
// Dnm, // $nr.
// Dnp, // $nr->
//
// D_, // $-nr
// D_m, // $-nr.
// D_p, // $-nr->
//
// Dt_, // $<TAG>-nr
// Dt_m, // $<TAG>-nr.
// Dt_p, // $<TAG>-nr->
void AtDollar::setDollarPatterns() // text[0] == '$'
{
switch (d_text[1])
{
case '$':
setDollarDollarPatterns();
return;
default:
setNumberPatterns();
return;
case '<':
setTagPatterns();
return;
}
}
#include "atdollar.ih"
// Dn, // $nr
// Dnm, // $nr.
// Dnp, // $nr->
//
// D_, // $-nr
// D_m, // $-nr.
// D_p, // $-nr->
void AtDollar::setNumberPatterns()
{
d_nr = stol(d_text.substr(1));
switch (d_text.back())
{
default:
d_pattern = d_nr > 0 ? Dn : D_;
return;
case '.':
d_pattern = d_nr > 0 ? Dnm : D_m;
return;
case '>':
d_pattern = d_nr > 0 ? Dnp : D_p;
return;
}
}
#include "atdollar.ih"
// refDD, // _$$
// refDn, // _$nr
// refD_, // _$-nr
void AtDollar::setRefPatterns() // text[0] == '_'
{
switch (d_text[2])
{
case '$':
d_pattern = refDD;
return;
default:
d_pattern = refDn;
break;
case '-':
d_pattern = refD_;
break;
}
d_nr = stol(d_text.substr(2));
}
#include "atdollar.ih"
void AtDollar::setTagNr(size_t begin) // idx beyond <
{
size_t end = d_text.find('>');
d_tag = d_text.substr(begin, end - begin);
d_nr = stol(d_text.substr(end + 1));
}
#include "atdollar.ih"
// Dt_, // $<TAG>-nr
// Dt_m, // $<TAG>-nr.
// Dt_p, // $<TAG>-nr->
void AtDollar::setTagPatterns()
{
setTagNr(2);
switch (d_text.back())
{
default:
d_pattern = Dt_;
return;
case '.':
d_pattern = Dt_m;
return;
case '>':