001 package com.croftsoft.apps.compiler; 002 003 import java.io.*; 004 005 import java_cup.runtime.Symbol; 006 007 /********************************************************************* 008 * A calculator capable of parsing input. 009 * 010 * <P> 011 * 012 * Built using the 013 * 014 * CUP Parser Generator for Java 015 * (<A HREF="http://www.cs.princeton.edu/~appel/modern/java/CUP/"> 016 * http://www.cs.princeton.edu/~appel/modern/java/CUP/</A>) 017 * 018 * and 019 * 020 * JLex: A Lexical Analyzer Generator for Java 021 * (<A HREF="http://www.cs.princeton.edu/~appel/modern/java/JLex/"> 022 * http://www.cs.princeton.edu/~appel/modern/java/JLex/</A>). 023 * 024 * @version 025 * 1999-03-16 026 * @author 027 * <A HREF="http://www.alumni.caltech.edu/~croft/">David W. Croft</A> 028 *********************************************************************/ 029 030 public class Calc 031 ////////////////////////////////////////////////////////////////////// 032 ////////////////////////////////////////////////////////////////////// 033 { 034 035 public static final String INFO 036 = "=============================================\n" 037 + "Calc (C) Copyright 1999 David Wallace Croft\n" 038 + "\n" 039 + "Version 1999-03-16\n" 040 + "Source code available at http://www.orbs.com/\n" 041 + "\n" 042 + "Enter your calculations at the command line.\n" 043 + "Example: a := 2; b := 3; write ( a + b );\n" 044 + "=============================================\n" 045 + "\n"; 046 047 private static final boolean DO_DEBUG_PARSE = false; 048 049 private static final String [ ] TEST_DATA = { 050 051 "a := 2;" 052 + "write ( a );" // 2 053 + "write ( b );" // null 054 + "b := 3;" 055 + "write ( b );" // 3 056 + "c := a + b;" 057 + "write ( c );", // 5 058 059 "a := 2;" 060 + "b := 3;" 061 + "write ( a + b );" // 5 062 + "write ( a - b );" // -1 063 + "write ( a * b );" // 6 064 + "write ( a / b );" // 0 065 + "write ( a % b );" // 2 066 + "write ( a ^ b );" // 8 067 + "write ( a * b ^ a );", // 18, not 36 068 069 "bill_123 := 3;" 070 + "write ( bill_123 );", // 3 071 072 "write ( a := 1 + 2 );" // 3 073 + "write ( b := a + 3 );" // 6 074 + "write ( c := 1 + ( b := 2 ) );" // 3 075 + "write ( b );" // 2 076 + "write ( c );", // 3 077 078 "write ( a );" // null 079 + "b := 1;" 080 + "write ( b );" // 1 081 + "b := a;" 082 + "write ( b );", // null 083 084 "a := 2;" 085 + "b := 3;" 086 + "write ( -1 );" // -1 087 + "write ( 1 - -1 );" // 2 088 + "write ( -a );" // -2 089 + "write ( -a + -b );" // -5 090 + "write ( - ( a - -b ) + 1 );", // -4 091 092 // The following test is only partially successful due to error 093 // recovery with parentheses not being handled properly, I suspect. 094 095 "hello;" // syntax error 096 + "write ( 1 );" // 1 097 + "write ( 1 + ( 2 + );" // syntax error 098 + "write ( 2 );" // 2 099 + "write ( 1 + ( 2 + 1 );", // syntax error 100 101 "a := 2;" 102 + "write ( a + b );" // null operand, null operand 103 + "b := 3;" 104 + "write ( a + b );" // 5 105 106 }; 107 108 ////////////////////////////////////////////////////////////////////// 109 ////////////////////////////////////////////////////////////////////// 110 111 public static void main ( String [ ] args ) 112 ////////////////////////////////////////////////////////////////////// 113 { 114 System.out.println ( INFO ); 115 116 if ( args.length < 1 ) 117 { 118 parse ( System.in ); 119 } 120 else 121 { 122 test ( ); 123 } 124 } 125 126 public static boolean test ( ) 127 ////////////////////////////////////////////////////////////////////// 128 { 129 for ( int i = 0; i < TEST_DATA.length; i++ ) 130 { 131 System.out.println ( "--- Test " + i + " --- " ); 132 parse ( new StringReader ( TEST_DATA [ i ] ) ); 133 System.out.println ( "" ); 134 } 135 136 return true; 137 } 138 139 public static void parse ( InputStream inputStream ) 140 ////////////////////////////////////////////////////////////////////// 141 { 142 parse ( new CalcScanner ( inputStream ) ); 143 } 144 145 public static void parse ( Reader reader ) 146 ////////////////////////////////////////////////////////////////////// 147 { 148 parse ( new CalcScanner ( reader ) ); 149 } 150 151 public static void parse ( CalcScanner calcScanner ) 152 ////////////////////////////////////////////////////////////////////// 153 { 154 CalcParser parser = new CalcParser ( calcScanner ); 155 156 Symbol parseTree = null; 157 158 try 159 { 160 if ( DO_DEBUG_PARSE ) 161 { 162 parseTree = parser.debug_parse ( ); 163 } 164 else 165 { 166 parseTree = parser.parse ( ); 167 } 168 } 169 catch ( Exception ex ) 170 { 171 ex.printStackTrace ( ); 172 } 173 174 // System.out.println ( parseTree ); 175 } 176 177 ////////////////////////////////////////////////////////////////////// 178 ////////////////////////////////////////////////////////////////////// 179 }