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 }