www.pudn.com > cppcc.rar > dfa_re_node_builder.cc
/*
* File: dfa_re_node_builder.cc
* $Id: dfa_re_node_builder.cc,v 1.6 2002/05/27 02:59:27 alec Exp $
*
* Author: Alec Panoviciu (alecu@email.com)
*
* Comments:
*
* Revision history:
*
* $Log: dfa_re_node_builder.cc,v $
* Revision 1.6 2002/05/27 02:59:27 alec
* doc update
*
* Revision 1.5 2002/05/22 01:23:12 alec
* case sensitivity support
*
* Revision 1.4 2002/05/01 09:18:26 alec
* - vBitset fixes
* - FOLLOWPOS written (not tested yet)
*
* Revision 1.3 2002/04/30 16:24:38 alec
* tested the scanner ptree & vBitVector implementation -> ok
*
* Revision 1.2 2002/04/30 09:22:32 alec
* bitset fixes
*
* Revision 1.1 2002/04/29 09:40:01 alec
* *** empty log message ***
*
*/
/*
Copyright (C) 2002 Alexandru Panoviciu (alecu@email.com)
This program 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 2 of the License, or
(at your option) any later version.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "dfa_re_node_builder.hh"
#include "dfa_source_re.hh"
#include "vbitset.hh"
#include "parse_util.hh"
#include "prop_registry.hh"
ReNode* DfaReNodeBuilder::createOrNode (ReNode *pre,
ReNode *post, const Position &pos)
{
return new ReOrNode(dynamic_cast(pre),
dynamic_cast(post), pos);
}
ReNode* DfaReNodeBuilder::createCatNode (ReNode *pre, ReNode *post,
const Position &pos)
{
return new ReCatNode(dynamic_cast(pre),
dynamic_cast(post), pos);
}
ReNode* DfaReNodeBuilder::createPlusNode (ReNode *in, const Position &pos)
{ // r+ -> rr*
return new ReCatNode(dynamic_cast(in->clone()),
new ReStarNode(dynamic_cast(in), pos),
pos);
}
ReNode* DfaReNodeBuilder::createOptionalNode (ReNode *in, const Position &pos)
{ // r? -> r | lambda
return new ReOrNode(dynamic_cast(in),
new ReLambdaNode(pos), pos);
}
ReNode* DfaReNodeBuilder::createStarNode (ReNode *in, const Position &pos)
{
return new ReStarNode(dynamic_cast(in), pos);
}
ReNode* DfaReNodeBuilder::createStringLiteralNode (const string& s,
const Position &pos)
{
if (s.size() == 0) //empty string => lambda
return new ReLambdaNode(pos);
else {
DfaSourceRe *res = new ReCharNode(s[0], pos);
for (int i = 1; i < s.size(); i++)
res = new ReCatNode(res, createCharNode(s[i], pos), pos);
return res;
}
}
ReNode* DfaReNodeBuilder::createCharListNode (bool negated,
const vector &chars,
const Position &pos)
{
vBitset chset(256);
for (int i = 0; i < chars.size(); i++)
for (int c = chars[i].first; c <= chars[i].last; c++)
chset[c].set();
if (negated) chset.flip();
if (chset.count1() == 0)
die(formatError(pos, "Character class does not match any character."));
DfaSourceRe *res = NULL;
bool caseSensitive = registry["CASE_SENSITIVE"];
for (int c = 0; c < 256; c++)
if (chset[c].get()) {
if (!caseSensitive) // avoid unnecesasry duplicate nodes.
if (isupper(c) && chset[tolower(c)].get()) continue;
if (res == NULL) res = createCharNode(c, pos);
else res = new ReOrNode(res, createCharNode(c, pos), pos);
}
return res;
}
DfaSourceRe* DfaReNodeBuilder::createEotNode (int tokId, const Position &pos)
{
return new ReEotNode(tokId, pos);
}
DfaSourceRe* DfaReNodeBuilder::createCharNode (unsigned char match,
const Position &pos)
{
if (!registry["CASE_SENSITIVE"])
{
if (isupper(match)) return new ReOrNode(new ReCharNode(match, pos),
new ReCharNode(tolower( match),
pos),
pos);
if (islower(match)) return new ReOrNode(new ReCharNode(match, pos),
new ReCharNode(toupper( match),
pos),
pos);
}
return new ReCharNode(match, pos);
}