📄 expression.java
字号:
//////////////////////////////////////////////////////////////////// public String toString( ) { switch ( type ) { case NUMBER: return Double.toString( number ); case VARIABLE: return VARIABLE_STR; case KEYWORD: return ( (keyword == null) ? INVALID_KEYWORD_STR : keyword.getKey( ) ); case SYMBOL: return ( (symbol == null) ? INVALID_SYMBOL_STR : Character.toString( symbol.getKey( ) ) ); case EOF: return END_STR; } return null; } //-------------------------------------------------------------- //////////////////////////////////////////////////////////////////// // Instance variables //////////////////////////////////////////////////////////////////// private Type type; private double number; private Keyword keyword; private Symbol symbol; private int pos; } //================================================================== // NODE CLASS private static class Node { //////////////////////////////////////////////////////////////////// // Constants //////////////////////////////////////////////////////////////////// private enum Type { NONE, CONSTANT, VARIABLE, UNARY_OP, BINARY_OP } //////////////////////////////////////////////////////////////////// // Constructors //////////////////////////////////////////////////////////////////// private Node( ) { type = Type.NONE; } //-------------------------------------------------------------- private Node( Node parent, Type type ) { this.parent = parent; this.type = type; } //-------------------------------------------------------------- private Node( Node parent, Type type, double constValue ) { this( parent, type ); this.constValue = constValue; } //-------------------------------------------------------------- private Node( Node parent, UnaryOp unaryOp ) { this( parent, Type.UNARY_OP ); this.unaryOp = unaryOp; } //-------------------------------------------------------------- private Node( Node parent, BinaryOp binaryOp ) { this( parent, Type.BINARY_OP ); this.binaryOp = binaryOp; } //-------------------------------------------------------------- //////////////////////////////////////////////////////////////////// // Instance methods //////////////////////////////////////////////////////////////////// public boolean isEmpty( ) { return ( (lChild == null) && (rChild == null) ); } //-------------------------------------------------------------- public boolean isTerminal( ) { return ( (type == Type.CONSTANT) || (type == Type.VARIABLE) ); } //-------------------------------------------------------------- public boolean isOperator( ) { return ( (type == Type.UNARY_OP) || (type == Type.BINARY_OP) ); } //-------------------------------------------------------------- public boolean equals( Node node ) { if ( (node == null) || (type != node.type) ) return false; switch ( type ) { case CONSTANT: if ( constValue != node.constValue ) return false; break; case UNARY_OP: if ( unaryOp != node.unaryOp ) return false; break; case BINARY_OP: if ( binaryOp != node.binaryOp ) return false; break; } if ( lChild == null ) { if ( node.lChild != null ) return false; } else { if ( !lChild.equals( node.lChild ) ) return false; } if ( rChild == null ) { if ( node.rChild != null ) return false; } else { if ( !rChild.equals( node.rChild ) ) return false; } return true; } //-------------------------------------------------------------- public boolean append( Node node ) { if ( lChild == null ) { lChild = node; return true; } if ( rChild == null ) { rChild = node; return true; } return false; } //-------------------------------------------------------------- public void removeNullNodes( ) { if ( lChild != null ) lChild.removeNullNodes( ); if ( rChild != null ) rChild.removeNullNodes( ); if ( type == Type.NONE ) { if ( lChild != null ) lChild.parent = parent; if ( parent != null ) { if ( parent.lChild == this ) parent.lChild = lChild; if ( parent.rChild == this ) parent.rChild = lChild; } } } //-------------------------------------------------------------- public double evaluate( ) { switch ( type ) { case NONE: if ( lChild != null ) return ( lChild.evaluate( ) ); break; case CONSTANT: return constValue; case VARIABLE: return x; case UNARY_OP: return unaryOp.evaluate( lChild.evaluate( ) ); case BINARY_OP: return binaryOp.evaluate( lChild.evaluate( ), rChild.evaluate( ) ); } return Double.NaN; } //-------------------------------------------------------------- //////////////////////////////////////////////////////////////////// // Class variables //////////////////////////////////////////////////////////////////// private static double x; //////////////////////////////////////////////////////////////////// // Instance variables //////////////////////////////////////////////////////////////////// private Node parent; private Node lChild; private Node rChild; private Type type; private double constValue; private UnaryOp unaryOp; private BinaryOp binaryOp; } //================================================================== // SYNTAX ERROR CLASS private static class SyntaxError extends Expression.Exception { //////////////////////////////////////////////////////////////////// // Constants //////////////////////////////////////////////////////////////////// private static final String SYNTAX_ERROR_STR = "Syntax error"; //////////////////////////////////////////////////////////////////// // Constructors //////////////////////////////////////////////////////////////////// private SyntaxError( ErrorId id, int pos ) { super( SYNTAX_ERROR_STR + ": " + AppException.getString( id ), pos ); } //-------------------------------------------------------------- } //================================================================== // PARSER ERROR CLASS // A parser error indicates a problem with the parser: if the parser performs // correctly, a parser error should never be thrown. private static class ParserError extends Expression.Exception { //////////////////////////////////////////////////////////////////// // Constants //////////////////////////////////////////////////////////////////// private static final String PARSER_ERROR_STR = "Parser error"; //////////////////////////////////////////////////////////////////// // Constructors //////////////////////////////////////////////////////////////////// private ParserError( int errorNum, int pos ) { super( PARSER_ERROR_STR + ' ' + errorNum, pos ); } //-------------------------------------------------------------- } //==================================================================////////////////////////////////////////////////////////////////////////// Constructors//////////////////////////////////////////////////////////////////////// public Expression( String str ) throws Expression.Exception { this.str = str; parse( str ); } //------------------------------------------------------------------////////////////////////////////////////////////////////////////////////// Class methods//////////////////////////////////////////////////////////////////////// private static boolean isWhitespace( char ch ) { final String WHITESPACE_CHARS = " \t\n\r"; return ( WHITESPACE_CHARS.indexOf( ch ) >= 0 ); } //------------------------------------------------------------------ private static boolean isNumeric( char ch ) { return ( ((ch >= '0') && (ch <= '9')) || (ch == '.') ); } //------------------------------------------------------------------ private static boolean isAlpha( char ch ) { return ( (ch >= 'a') && (ch <= 'z') ); } //------------------------------------------------------------------ private static boolean isSymbol( char ch ) { return ( Symbol.get( ch ) != null ); } //------------------------------------------------------------------ private static LexState getLexState( char ch ) { if ( ch == 0 ) return LexState.EOL; if ( isWhitespace( ch ) ) return LexState.WHITESPACE; if ( isNumeric( ch ) ) return LexState.NUMERIC; if ( isAlpha( ch ) ) return LexState.ALPHA; if ( isSymbol( ch ) ) return LexState.SYMBOL; return LexState.INVALID; } //------------------------------------------------------------------ private static Token numberToToken( String str, int pos ) throws Expression.Exception { try { return new Token( Token.Type.NUMBER, pos, Double.parseDouble( str ) ); } catch ( NumberFormatException e ) { throw new Expression.Exception( ErrorId.INVALID_NUMBER, str, pos ); } } //------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -