home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
ssvpar.zip
/
SSCALC.CPP
< prev
next >
Wrap
Text File
|
1994-11-25
|
11KB
|
405 lines
#if !defined( SSCALCSSHH)
# define SSCALCSSHH
# if defined( __BCPLUSPLUS__)
# include<iostream.h>
# define SSCDECL __cdecl
# else
# include<stream.h>
# define SSCDECL
# endif
# include<sslex.hpp>
# include<ssyacc.hpp>
# define ALexExpressionListMain 0
# define ALexExpressionListMLCom 1
# define ALexExpressionListSLCom 2
# define ALexEnd 4
# define ALexPlus 5
# define ALexMinus 6
# define ALexDiv 7
# define ALexMult 8
# define ALexMod 9
# define ALexPow 10
# define ALexOr 11
# define ALexAnd 12
# define ALexNot 13
# define ALexOParen 14
# define ALexCParen 15
# define ALexDec 16
# define ALexOct 17
# define ALexHex 18
# define AYaccStart 1
# define AYaccStartList 2
# define AYaccExprSingle 3
# define AYaccExprError 4
# define AYaccExprPlus 5
# define AYaccExprMinus 6
# define AYaccExprMult 7
# define AYaccExprDiv 8
# define AYaccExprMod 9
# define AYaccExprNot 10
# define AYaccExprAnd 11
# define AYaccExprOr 12
# define AYaccExprNested 13
# define AYaccExprNumber 14
# define AYaccNumberDec 15
# define AYaccNumberOct 16
# define AYaccNumberHex 17
class ALexClass : public SSLex
{
public:
SSConstr ALexClass( const char*);
const char* tokenToConstChar( SSUnsigned32);
};
ALexClass::ALexClass( const char* qpszFile) :
SSLex( qpszFile, "sscalc.dfa")
{
}
const char* ALexClass::tokenToConstChar( SSUnsigned32 qulToken)
{
const char* zpchToken;
switch ( qulToken)
{
case ALexEnd:
zpchToken = ";";
break;
case ALexPlus:
zpchToken = "+";
break;
case ALexMinus:
zpchToken = "-";
break;
case ALexDiv:
zpchToken = "/";
break;
case ALexMult:
zpchToken = "*";
break;
case ALexMod:
zpchToken = "%";
break;
case ALexPow:
zpchToken = "**";
break;
case ALexOr:
zpchToken = "or";
break;
case ALexAnd:
zpchToken = "and";
break;
case ALexNot:
zpchToken = "not";
break;
case ALexOParen:
zpchToken = "(";
break;
case ALexCParen:
zpchToken = ")";
break;
case ALexDec:
zpchToken = "dec";
break;
case ALexOct:
zpchToken = "oct";
break;
case ALexHex:
zpchToken = "hex";
break;
case SSYaccErrorToken:
zpchToken = "%error";
break;
case SSYaccEofToken:
zpchToken = "eof";
break;
default:
zpchToken = SSLexTokenNotFound;
}
return zpchToken;
}
class AYaccStackElement : public SSYaccStackElement
{
public:
SSConstr AYaccStackElement( void);
SSSigned32 value( void);
void refFree( void);
void setValue( SSSigned32);
protected:
SSSigned32 olVal;
};
class AYaccClass : public SSYacc
{
public:
SSConstr AYaccClass( const char*);
SSYaccStackElement* stackElement( void);
SSBooleanValue error( SSUnsigned32, SSLexLexeme&);
SSYaccStackElement* reduce( SSUnsigned32, SSUnsigned32);
AYaccStackElement* elementFromProduction( SSUnsigned32);
protected:
SSLexTable oTable;
SSLexStringConsumer oConsumer;
SSLex oLex;
};
SSInline AYaccClass::AYaccClass( const char* qpszString) :
SSYacc("sscalc.llr"),
oTable( "sscalc.dfa"),
oConsumer( qpszString),
oLex( oConsumer, oTable)
{
setLex( oLex);
}
SSBooleanValue AYaccClass::error( SSUnsigned32 qulState, SSLexLexeme& qLook)
{
cout << "Syntax error on " << qLook.asConstChar() << "\n";
if ( qLook.line() == 0xffffffff)
cout << "Probable missing semicolon\n";
return SSYacc::error( qulState, qLook);
}
SSYaccStackElement* AYaccClass::stackElement( void)
{
return new AYaccStackElement;
}
SSInline AYaccStackElement* AYaccClass::elementFromProduction(
SSUnsigned32 qulIndex)
{
return ( AYaccStackElement*) SSYacc::elementFromProduction( qulIndex);
}
AYaccStackElement::AYaccStackElement( void) : olVal( 0)
{
}
SSInline SSSigned32 AYaccStackElement::value( void)
{
return olVal;
}
SSInline void AYaccStackElement::setValue( SSSigned32 qlVal)
{
olVal = qlVal;
}
void AYaccStackElement::refFree( void)
{
delete this;
}
SSYaccStackElement* AYaccClass::reduce( SSUnsigned32 qulProd,
SSUnsigned32 qulSize)
{
SSSigned32 zlVal = 0;
switch ( qulProd)
{
case AYaccStart:
// start -> exprStatement
break;
case AYaccStartList:
// start -> start exprStatement
break;
case AYaccExprSingle:
// exprStatement -> expr ;
{
AYaccStackElement* zpEle = elementFromProduction( 0);
cout << dec << zpEle->value() << "," << hex <<
zpEle->value() << "\n";
break;
}
case AYaccExprError:
// exprStatement -> %error ;
break;
case AYaccExprPlus:
// expr -> expr + expr
{
AYaccStackElement* zpEle0 = elementFromProduction( 0);
AYaccStackElement* zpEle2 = elementFromProduction( 2);
zlVal = zpEle0->value() + zpEle2->value();
break;
}
case AYaccExprMinus:
// expr -> expr - expr
{
AYaccStackElement* zpEle0 = elementFromProduction( 0);
AYaccStackElement* zpEle2 = elementFromProduction( 2);
zlVal = zpEle0->value() - zpEle2->value();
break;
}
case AYaccExprMult:
// expr -> expr * expr
{
AYaccStackElement* zpEle0 = elementFromProduction( 0);
AYaccStackElement* zpEle2 = elementFromProduction( 2);
zlVal = zpEle0->value() * zpEle2->value();
break;
}
case AYaccExprDiv:
// expr -> expr / expr
{
AYaccStackElement* zpEle0 = elementFromProduction( 0);
AYaccStackElement* zpEle2 = elementFromProduction( 2);
if ( !zpEle2->value())
{
AYaccStackElement* zpEle = elementFromProduction( 1);
SSLexLexeme* zpLexeme = zpEle->lexeme();
cout << "Divide by 0 error on line " << zpLexeme->line()
<< "\n";
}
else
zlVal = zpEle0->value() / zpEle2->value();
break;
}
case AYaccExprMod:
// expr -> expr % expr
{
AYaccStackElement* zpEle0 = elementFromProduction( 0);
AYaccStackElement* zpEle2 = elementFromProduction( 2);
if ( !zpEle2->value())
{
AYaccStackElement* zpEle = elementFromProduction( 1);
SSLexLexeme* zpLexeme = zpEle->lexeme();
cout << "Divide by 0 error on line " << zpLexeme->line()
<< "\n";
}
else
zlVal = zpEle0->value() % zpEle2->value();
break;
}
case AYaccExprNot:
// expr -> not expr
{
AYaccStackElement* zpEle1 = elementFromProduction( 1);
zlVal = ~zpEle1->value();
break;
}
case AYaccExprAnd:
// expr -> expr and expr
{
AYaccStackElement* zpEle0 = elementFromProduction( 0);
AYaccStackElement* zpEle2 = elementFromProduction( 2);
zlVal = zpEle0->value() & zpEle2->value();
break;
}
case AYaccExprOr:
// expr -> expr or expr
{
AYaccStackElement* zpEle0 = elementFromProduction( 0);
AYaccStackElement* zpEle2 = elementFromProduction( 2);
zlVal = zpEle0->value() | zpEle2->value();
break;
}
case AYaccExprNested:
// expr -> ( expr )
{
AYaccStackElement* zpEle1 = elementFromProduction( 1);
zlVal = zpEle1->value();
break;
}
case AYaccExprNumber:
// expr -> number
{
AYaccStackElement* zpEle0 = elementFromProduction( 0);
zlVal = zpEle0->value();
break;
}
case AYaccNumberDec:
// number -> dec
{
AYaccStackElement* zpEle0 = elementFromProduction( 0);
SSLexLexeme* zpLexeme = zpEle0->lexeme();
zlVal = strtol( zpLexeme->asConstChar(), 0, 0);
break;
}
case AYaccNumberOct:
// number -> oct
{
AYaccStackElement* zpEle0 = elementFromProduction( 0);
SSLexLexeme* zpLexeme = zpEle0->lexeme();
zlVal = strtol( zpLexeme->asConstChar(), 0, 0);
break;
}
case AYaccNumberHex:
// number -> hex
{
AYaccStackElement* zpEle0 = elementFromProduction( 0);
SSLexLexeme* zpLexeme = zpEle0->lexeme();
const char* zpszHex = zpLexeme->asConstChar();
zlVal = strtol( zpszHex, 0, 0);
break;
}
}
AYaccStackElement* zpEle = ( AYaccStackElement*) stackElement();
zpEle->setValue( zlVal);
return zpEle;
}
int SSCDECL main( int qiArg, char* qapszArg[])
{
if ( qiArg < 2)
{
cout << "Missing argument\n";
return 1;
}
try
{
AYaccClass zYacc( qapszArg[ 1]);
zYacc.parse();
}
catch ( SSException zExcept)
{
cout << zExcept.text() << "\n";
}
return 0;
}
#endif