Пример #1
0
 /// <summary>
 /// Check if parse point reach end point or not.
 /// </summary>
 /// <param name="statement">input</param>
 /// <param name="data"></param>
 /// <returns>true:reach end point , false:not reach end point.</returns>
 private bool isExit(string statement , ParsedData data)
 {
     return statement.Length <= data.INDEX;
 }
Пример #2
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="statement">input expression's statement</param>
        /// <param name="data"></param>
        /// <returns></returns>
        private ParsedData factor(string statement, ParsedData data)
        {
            var token = statement.ElementAt(data.INDEX);
            if(token == Token.Parenthesis.BEGIN )
            {
                data.INDEX++;

                if(isExit(statement,data))
                {
                    throw new SyntaxException("'('と')'の対応が合いません。",data.INDEX);
                }

                var rExpr = expr(statement, data);
                if (isExit(statement, rExpr))
                {
                    throw new SyntaxException(")の対応が合わず、終端に到達しました。",data.INDEX);
                }
                if (statement.ElementAt(rExpr.INDEX) != Token.Parenthesis.END)
                {
                    throw new SyntaxException(")が合わない",data.INDEX);
                }
                rExpr.INDEX++;

                return rExpr;
            }
            else 
            {
                string strNumber = "";

                if (isMinusSign(token))
                {
                    data.INDEX = data.INDEX + 1;
                    token = statement.ElementAt(data.INDEX);

                    strNumber = Token.Num.MINUS.ToString();
                }

                // 数字が一文字以上連続している場合は、数字として認識する。
                if (!isNumber(token))
                    throw new SyntaxException("????",data.INDEX);

                strNumber += token.ToString();

                var idxBegin = data.INDEX;
                var idxEnd = idxBegin;

                for (int idx = idxBegin + 1; idx < statement.Length; idx++ )
                {
                    var numWrk = statement.ElementAt(idxEnd + 1);
                    if (!isNumber(numWrk))
                        break;
                    idxEnd++;
                    strNumber += numWrk.ToString();
                }

                try
                {
                    var number = long.Parse(strNumber);
                    idxEnd++;
                    return new ParsedData(number, idxEnd, data.MESSAGE);
                }
                catch(OverflowException ex)
                {
                    throw new ParseOverflowException(ex.Message, idxBegin, strNumber);
                }
            }
        }
Пример #3
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="statement">input expression's statement</param>
        /// <param name="data"></param>
        /// <returns></returns>
        private ParsedData expr(string statement , ParsedData data)
        {
            var rLeft = term(statement , data);
            if (isExit(statement, rLeft))
            {
                return rLeft;
            }

            while (true)
            {
                var tokenCurrent = statement.ElementAt(rLeft.INDEX);
                if (tokenCurrent == Token.Operator.ADD)
                {
                    var rRight = term(statement, new ParsedData(rLeft.NUMBER, rLeft.INDEX + 1, rLeft.MESSAGE));
                    rLeft.INDEX = rRight.INDEX;
                    rLeft.NUMBER = rLeft.NUMBER + rRight.NUMBER;
                }
                else if (tokenCurrent == Token.Operator.SUB)
                {
                    var rRight = term(statement, new ParsedData(rLeft.NUMBER, rLeft.INDEX + 1, rLeft.MESSAGE));
                    rLeft.INDEX = rRight.INDEX;
                    rLeft.NUMBER = rLeft.NUMBER - rRight.NUMBER;
                }
                else
                {
                    break;
                }
                if (isExit(statement, rLeft))
                    break;
            }
            return rLeft;
        }
Пример #4
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="statement">input expression's statement</param>
        /// <param name="data"></param>
        /// <returns></returns>
        private ParsedData term(string statement, ParsedData data)
        {
            var rLeft = factor(statement, data);

            if (isExit(statement, rLeft))
            {
                return rLeft;
            }
            while (true)
            {
                var token = statement.ElementAt(rLeft.INDEX);
                if (token == Token.Operator.MUL)
                {
                    var rRight = factor(statement, new ParsedData(rLeft.NUMBER, rLeft.INDEX + 1, rLeft.MESSAGE));
                    rLeft.INDEX = rRight.INDEX;
                    rLeft.NUMBER = rLeft.NUMBER * rRight.NUMBER;
                }
                else if (token == Token.Operator.DIV)
                {
                    var rRight = factor(statement, new ParsedData(rLeft.NUMBER, rLeft.INDEX + 1, rLeft.MESSAGE));
                    rLeft.INDEX = rRight.INDEX;
                    rLeft.NUMBER = rLeft.NUMBER / rRight.NUMBER;
                }
                else
                {
                    break;
                }
                if (isExit(statement, rLeft))
                    break;
            }
            return rLeft;
        }
Пример #5
0
        /// <summary>
        /// 計算機の入力式を解析する実行部
        /// </summary>
        /// <param name="statement"></param>
        /// <returns></returns>
        private ParserResult parse_exec( string statement)
        {
            var data = new ParsedData(0, 0, "");
            var result = expr(statement,data);

            // Check Syntax Accept Condition
            if (isExit(statement, result))
            {
                return new ParserResult(result.NUMBER, result.MESSAGE);
            }
            else
            {
                //statementの終端に達する前に解析終了しました。
                //文法エラーが発生しています。
                throw new SyntaxException(string.Format("{0}文字目近辺で異常終了しました。",result.INDEX),result.INDEX);
            }
        }