home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ssvpar.zip / SSCALC.CPP < prev    next >
Text File  |  1994-11-25  |  11KB  |  405 lines

  1. #if !defined( SSCALCSSHH)
  2. #  define SSCALCSSHH
  3. #  if defined( __BCPLUSPLUS__)
  4. #     include<iostream.h>
  5. #     define SSCDECL __cdecl
  6. #  else
  7. #     include<stream.h>
  8. #     define SSCDECL
  9. #  endif
  10. #  include<sslex.hpp>
  11. #  include<ssyacc.hpp>
  12.  
  13. #  define ALexExpressionListMain       0
  14. #  define ALexExpressionListMLCom      1
  15. #  define ALexExpressionListSLCom      2
  16.  
  17. #  define ALexEnd                      4
  18. #  define ALexPlus                     5
  19. #  define ALexMinus                    6
  20. #  define ALexDiv                      7
  21. #  define ALexMult                     8
  22. #  define ALexMod                      9
  23. #  define ALexPow                      10
  24. #  define ALexOr                       11
  25. #  define ALexAnd                      12
  26. #  define ALexNot                      13
  27. #  define ALexOParen                   14
  28. #  define ALexCParen                   15
  29. #  define ALexDec                      16
  30. #  define ALexOct                      17
  31. #  define ALexHex                      18
  32.  
  33. #  define AYaccStart                   1
  34. #  define AYaccStartList               2
  35. #  define AYaccExprSingle              3
  36. #  define AYaccExprError               4
  37. #  define AYaccExprPlus                5
  38. #  define AYaccExprMinus               6
  39. #  define AYaccExprMult                7
  40. #  define AYaccExprDiv                 8
  41. #  define AYaccExprMod                 9
  42. #  define AYaccExprNot                 10
  43. #  define AYaccExprAnd                 11
  44. #  define AYaccExprOr                  12
  45. #  define AYaccExprNested              13
  46. #  define AYaccExprNumber              14
  47. #  define AYaccNumberDec               15
  48. #  define AYaccNumberOct               16
  49. #  define AYaccNumberHex               17
  50.  
  51.    class ALexClass : public SSLex
  52.       {
  53.       public:
  54.          SSConstr            ALexClass( const char*);
  55.          const char*         tokenToConstChar( SSUnsigned32);
  56.       };
  57.  
  58.    ALexClass::ALexClass( const char* qpszFile) : 
  59.       SSLex( qpszFile, "sscalc.dfa")
  60.       {
  61.       }
  62.  
  63.    const char* ALexClass::tokenToConstChar( SSUnsigned32 qulToken)
  64.       {
  65.       const char* zpchToken;
  66.       switch ( qulToken)
  67.          {
  68.          case ALexEnd:
  69.             zpchToken = ";";
  70.             break;
  71.  
  72.          case ALexPlus:
  73.             zpchToken = "+";
  74.             break;
  75.  
  76.          case ALexMinus:
  77.             zpchToken = "-";
  78.             break;
  79.  
  80.          case ALexDiv:
  81.             zpchToken = "/";
  82.             break;
  83.  
  84.          case ALexMult:
  85.             zpchToken = "*";
  86.             break;
  87.  
  88.          case ALexMod:
  89.             zpchToken = "%";
  90.             break;
  91.  
  92.          case ALexPow:
  93.             zpchToken = "**";
  94.             break;
  95.  
  96.          case ALexOr:
  97.             zpchToken = "or";
  98.             break;
  99.  
  100.          case ALexAnd:
  101.             zpchToken = "and";
  102.             break;
  103.  
  104.          case ALexNot:
  105.             zpchToken = "not";
  106.             break;
  107.  
  108.          case ALexOParen:
  109.             zpchToken = "(";
  110.             break;
  111.  
  112.          case ALexCParen:
  113.             zpchToken = ")";
  114.             break;
  115.  
  116.          case ALexDec:
  117.             zpchToken = "dec";
  118.             break;
  119.  
  120.          case ALexOct:
  121.             zpchToken = "oct";
  122.             break;
  123.  
  124.          case ALexHex:
  125.             zpchToken = "hex";
  126.             break;
  127.  
  128.          case SSYaccErrorToken:
  129.             zpchToken = "%error";
  130.             break;
  131.  
  132.          case SSYaccEofToken:
  133.             zpchToken = "eof";
  134.             break;
  135.  
  136.          default:
  137.             zpchToken = SSLexTokenNotFound;
  138.          }
  139.       return zpchToken;
  140.       }
  141.  
  142.    class AYaccStackElement : public SSYaccStackElement
  143.       {
  144.       public:
  145.          SSConstr         AYaccStackElement( void);
  146.  
  147.          SSSigned32       value( void);
  148.          void             refFree( void);
  149.          void             setValue( SSSigned32);
  150.  
  151.       protected:
  152.          SSSigned32       olVal;
  153.       };
  154.  
  155.    class AYaccClass : public SSYacc
  156.       {
  157.       public:
  158.          SSConstr            AYaccClass( const char*);
  159.  
  160.          SSYaccStackElement* stackElement( void);
  161.          SSBooleanValue      error( SSUnsigned32, SSLexLexeme&);
  162.          SSYaccStackElement* reduce( SSUnsigned32, SSUnsigned32);
  163.          AYaccStackElement*  elementFromProduction( SSUnsigned32);
  164.  
  165.       protected:
  166.          SSLexTable          oTable;
  167.          SSLexStringConsumer oConsumer;
  168.          SSLex               oLex;
  169.       };
  170.  
  171.    SSInline AYaccClass::AYaccClass( const char* qpszString) :
  172.       SSYacc("sscalc.llr"),
  173.       oTable( "sscalc.dfa"),
  174.       oConsumer( qpszString),
  175.       oLex( oConsumer, oTable)
  176.       {
  177.       setLex( oLex);
  178.       }
  179.  
  180.    SSBooleanValue AYaccClass::error( SSUnsigned32 qulState, SSLexLexeme& qLook)
  181.       {
  182.       cout << "Syntax error on " << qLook.asConstChar() << "\n";
  183.       if ( qLook.line() == 0xffffffff)
  184.          cout << "Probable missing semicolon\n";
  185.       return SSYacc::error( qulState, qLook);
  186.       }
  187.  
  188.    SSYaccStackElement* AYaccClass::stackElement( void)
  189.       {
  190.       return new AYaccStackElement;
  191.       }
  192.  
  193.    SSInline AYaccStackElement* AYaccClass::elementFromProduction( 
  194.       SSUnsigned32 qulIndex)
  195.       {
  196.       return ( AYaccStackElement*) SSYacc::elementFromProduction( qulIndex);
  197.       }
  198.  
  199.    AYaccStackElement::AYaccStackElement( void) : olVal( 0)
  200.       {
  201.       }
  202.  
  203.    SSInline SSSigned32 AYaccStackElement::value( void)
  204.       {
  205.       return olVal;
  206.       }
  207.  
  208.    SSInline void AYaccStackElement::setValue( SSSigned32 qlVal)
  209.       {
  210.       olVal = qlVal;
  211.       }
  212.  
  213.    void AYaccStackElement::refFree( void)
  214.       {
  215.       delete this;
  216.       }
  217.  
  218.    SSYaccStackElement* AYaccClass::reduce( SSUnsigned32 qulProd,
  219.       SSUnsigned32 qulSize)
  220.       {
  221.       SSSigned32 zlVal = 0;
  222.       switch ( qulProd)
  223.          {
  224.          case AYaccStart:
  225.          // start -> exprStatement 
  226.             break;
  227.  
  228.          case AYaccStartList:
  229.          // start -> start exprStatement 
  230.             break;
  231.  
  232.          case AYaccExprSingle:
  233.          // exprStatement -> expr ; 
  234.             {
  235.             AYaccStackElement* zpEle = elementFromProduction( 0);
  236.             cout << dec << zpEle->value() << "," << hex << 
  237.                zpEle->value() << "\n";
  238.             break;
  239.             }
  240.  
  241.          case AYaccExprError:
  242.          // exprStatement -> %error ; 
  243.             break;
  244.  
  245.          case AYaccExprPlus:
  246.          // expr -> expr + expr 
  247.             {
  248.             AYaccStackElement* zpEle0 = elementFromProduction( 0);
  249.             AYaccStackElement* zpEle2 = elementFromProduction( 2);
  250.             zlVal = zpEle0->value() + zpEle2->value();
  251.             break;
  252.             }
  253.  
  254.          case AYaccExprMinus:
  255.          // expr -> expr - expr 
  256.             {
  257.             AYaccStackElement* zpEle0 = elementFromProduction( 0);
  258.             AYaccStackElement* zpEle2 = elementFromProduction( 2);
  259.             zlVal = zpEle0->value() - zpEle2->value();
  260.             break;
  261.             }
  262.  
  263.          case AYaccExprMult:
  264.          // expr -> expr * expr 
  265.             {
  266.             AYaccStackElement* zpEle0 = elementFromProduction( 0);
  267.             AYaccStackElement* zpEle2 = elementFromProduction( 2);
  268.             zlVal = zpEle0->value() * zpEle2->value();
  269.             break;
  270.             }
  271.  
  272.          case AYaccExprDiv:
  273.          // expr -> expr / expr 
  274.             {
  275.             AYaccStackElement* zpEle0 = elementFromProduction( 0);
  276.             AYaccStackElement* zpEle2 = elementFromProduction( 2);
  277.             if ( !zpEle2->value())
  278.                {
  279.                AYaccStackElement* zpEle = elementFromProduction( 1);
  280.                SSLexLexeme* zpLexeme = zpEle->lexeme();
  281.                cout << "Divide by 0 error on line " << zpLexeme->line() 
  282.                   << "\n";
  283.                }
  284.             else
  285.                zlVal = zpEle0->value() / zpEle2->value();
  286.             break;
  287.             }
  288.  
  289.          case AYaccExprMod:
  290.          // expr -> expr % expr 
  291.             {
  292.             AYaccStackElement* zpEle0 = elementFromProduction( 0);
  293.             AYaccStackElement* zpEle2 = elementFromProduction( 2);
  294.             if ( !zpEle2->value())
  295.                {
  296.                AYaccStackElement* zpEle = elementFromProduction( 1);
  297.                SSLexLexeme* zpLexeme = zpEle->lexeme();
  298.                cout << "Divide by 0 error on line " << zpLexeme->line() 
  299.                   << "\n";
  300.                }
  301.             else
  302.                zlVal = zpEle0->value() % zpEle2->value();
  303.             break;
  304.             }
  305.  
  306.          case AYaccExprNot:
  307.          // expr -> not expr 
  308.             {
  309.             AYaccStackElement* zpEle1 = elementFromProduction( 1);
  310.             zlVal = ~zpEle1->value();
  311.             break;
  312.             }
  313.  
  314.          case AYaccExprAnd:
  315.          // expr -> expr and expr 
  316.             {
  317.             AYaccStackElement* zpEle0 = elementFromProduction( 0);
  318.             AYaccStackElement* zpEle2 = elementFromProduction( 2);
  319.             zlVal = zpEle0->value() & zpEle2->value();
  320.             break;
  321.             }
  322.  
  323.          case AYaccExprOr:
  324.          // expr -> expr or expr 
  325.             {
  326.             AYaccStackElement* zpEle0 = elementFromProduction( 0);
  327.             AYaccStackElement* zpEle2 = elementFromProduction( 2);
  328.             zlVal = zpEle0->value() | zpEle2->value();
  329.             break;
  330.             }
  331.  
  332.          case AYaccExprNested:
  333.          // expr -> ( expr ) 
  334.             {
  335.             AYaccStackElement* zpEle1 = elementFromProduction( 1);
  336.             zlVal = zpEle1->value();
  337.             break;
  338.             }
  339.  
  340.          case AYaccExprNumber:
  341.          // expr -> number 
  342.             {
  343.             AYaccStackElement* zpEle0 = elementFromProduction( 0);
  344.             zlVal = zpEle0->value();
  345.             break;
  346.             }
  347.  
  348.          case AYaccNumberDec:
  349.          // number -> dec 
  350.             {
  351.             AYaccStackElement* zpEle0 = elementFromProduction( 0);
  352.             SSLexLexeme* zpLexeme = zpEle0->lexeme();
  353.             zlVal = strtol( zpLexeme->asConstChar(), 0, 0);
  354.             break;
  355.             }
  356.  
  357.          case AYaccNumberOct:
  358.          // number -> oct 
  359.             {
  360.             AYaccStackElement* zpEle0 = elementFromProduction( 0);
  361.             SSLexLexeme* zpLexeme = zpEle0->lexeme();
  362.             zlVal = strtol( zpLexeme->asConstChar(), 0, 0);
  363.             break;
  364.             }
  365.  
  366.          case AYaccNumberHex:
  367.          // number -> hex 
  368.             {
  369.             AYaccStackElement* zpEle0 = elementFromProduction( 0);
  370.             SSLexLexeme* zpLexeme = zpEle0->lexeme();
  371.             const char* zpszHex = zpLexeme->asConstChar();
  372.             zlVal = strtol( zpszHex, 0, 0);
  373.             break;
  374.             }
  375.  
  376.          }
  377.  
  378.       AYaccStackElement* zpEle = ( AYaccStackElement*) stackElement();
  379.       zpEle->setValue( zlVal);
  380.       return zpEle;
  381.       }
  382.  
  383.    int SSCDECL main( int qiArg, char* qapszArg[])
  384.       {
  385.       if ( qiArg < 2)
  386.          {
  387.          cout << "Missing argument\n";
  388.          return 1;
  389.          }
  390.  
  391.       try
  392.          {
  393.          AYaccClass zYacc( qapszArg[ 1]);
  394.          zYacc.parse();
  395.          }
  396.       catch ( SSException zExcept)
  397.          {
  398.          cout << zExcept.text() << "\n";
  399.          }
  400.  
  401.       return 0;
  402.       }
  403.  
  404. #endif
  405.