Пример #1
0
        /// <summary>
        /// ハイフン「-」が負数演算子として使うか、減算演算子として使うかを判定する。
        /// </summary>
        /// <param name="prevTerminalSymbolType">ハイフンのひとつ前の終端記号のタイプ</param>
        /// <returns>ハイフンの終端記号タイプ。ひとつ前の終端記号タイプが論理値の場合、Noneを返却する。</returns>
        private static TerminalSymbolType getHyphenTerminalSymbolType(TerminalSymbolType prevTerminalSymbolType)
        {
            switch (prevTerminalSymbolType)
            {
            case TerminalSymbolType.Integer:
            case TerminalSymbolType.Decimal:
            case TerminalSymbolType.Variable:
            case TerminalSymbolType.RightP:
                return(TerminalSymbolType.OpDiff);

            case TerminalSymbolType.None:
            case TerminalSymbolType.OpAdd:
            case TerminalSymbolType.OpDiff:
            case TerminalSymbolType.OpProd:
            case TerminalSymbolType.OpDivide:
            case TerminalSymbolType.OpMod:
            case TerminalSymbolType.OpPow:
            case TerminalSymbolType.OpNeg:
            case TerminalSymbolType.OpLt:
            case TerminalSymbolType.OpLtEq:
            case TerminalSymbolType.OpGt:
            case TerminalSymbolType.OpGtEq:
            case TerminalSymbolType.OpEq:
            case TerminalSymbolType.OpNotEq:
            case TerminalSymbolType.OpNot:
            case TerminalSymbolType.OpAnd:
            case TerminalSymbolType.OpOr:
            case TerminalSymbolType.Function:
            case TerminalSymbolType.Comma:
            case TerminalSymbolType.LeftP:
                return(TerminalSymbolType.OpNeg);

            case TerminalSymbolType.LogicTrue:
            case TerminalSymbolType.LogicFalse:
            default:
                return(TerminalSymbolType.None);
            }
        }
 public TerminalSymbol(string value, TerminalSymbolType type)
 {
     this.value = value;
     this.type  = type;
 }
Пример #3
0
        /// <summary>
        /// 文字列に終端記号を割り当てる。
        /// </summary>
        /// <param name="prevExpr">評価対象の前の終端記号。</param>
        /// <param name="expr">評価対象の文字列。</param>
        /// <param name="nextExpr">評価対象の次の文字列。
        /// <param name="terminalSymbol">結果を保存する変数。
        /// exprに終端記号を割り当てて返却する。</param>
        /// 評価対象の文字列が式の最後の場合は、nullを指定する。</param>
        /// <returns>終端記号割り当てに成功した場合、trueを返却する。</returns>
        private static bool assignTerminalSymbol(TerminalSymbol prevExpr, string expr, string nextExpr, out TerminalSymbol terminalSymbol)
        {
            terminalSymbol = new TerminalSymbol(null, TerminalSymbolType.None);
            if (expr.Length == 0)
            {
                return(false);
            }

            switch (expr)
            {
            case "+":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.OpAdd);
                return(true);

            case "-":
                TerminalSymbolType hyphenTerminalSymbolType = getHyphenTerminalSymbolType(prevExpr.type);
                if (hyphenTerminalSymbolType == TerminalSymbolType.None)
                {
                    return(false);
                }
                terminalSymbol = new TerminalSymbol(expr, hyphenTerminalSymbolType);
                return(true);

            case "*":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.OpProd);
                return(true);

            case "/":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.OpDivide);
                return(true);

            case "%":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.OpMod);
                return(true);

            case "^":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.OpPow);
                return(true);

            case "<":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.OpLt);
                return(true);

            case "<=":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.OpLtEq);
                return(true);

            case ">":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.OpGt);
                return(true);

            case ">=":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.OpGtEq);
                return(true);

            case "==":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.OpEq);
                return(true);

            case "!=":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.OpNotEq);
                return(true);

            case "!":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.OpNot);
                return(true);

            case "&&":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.OpAnd);
                return(true);

            case "||":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.OpOr);
                return(true);

            case ",":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.Comma);
                return(true);

            case "(":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.LeftP);
                return(true);

            case ")":
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.RightP);
                return(true);
            }
            if (expr == "true")
            {
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.LogicTrue);
                return(true);
            }
            else if (expr == "false")
            {
                terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.LogicFalse);
                return(true);
            }
            else if (checkDigit(expr[0]))
            {
                // 数値であることを判定する。
                int countDot = 0;
                for (int i = 1; i < expr.Length; i++)
                {
                    if (expr[i] == '.')
                    {
                        countDot++;
                    }
                    else if (!checkDigit(expr[i]))
                    {
                        return(false);
                    }
                }
                if (countDot == 0)
                {
                    terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.Integer);
                    return(true);
                }
                else if (countDot == 1)
                {
                    terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.Decimal);
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
            else if (Char.IsLetter(expr[0]))
            {
                // 全ての文字が関数・変数で利用可能であることを確認する。
                for (int i = 1; i < expr.Length; i++)
                {
                    if (!checkVarNameChar(expr[i]))
                    {
                        return(false);
                    }
                }
                // 次のexprの種類によって関数又は変数が決まる。
                // funcになるパターンは、次の終端記号が整数、小数、変数、関数、左括弧のどれかの場合。
                // true/falseが続く場合は文法エラーなので除外すると、以下の条件式で識別できる。
                if (nextExpr == null)
                {
                    terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.Variable);
                    return(true);
                }
                else
                {
                    if (nextExpr.Length == 0)
                    {
                        return(false);
                    }
                    if (checkVarNameChar(nextExpr[0]) || nextExpr == "(")
                    {
                        terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.Function);
                        return(true);
                    }
                    else
                    {
                        terminalSymbol = new TerminalSymbol(expr, TerminalSymbolType.Variable);
                        return(true);
                    }
                }
            }
            return(false);
        }
 public TerminalSymbol(TerminalSymbolType type)
     : this(type, 0, "")
 {
 }
 public TerminalSymbol(TerminalSymbolType type, int column, string value)
 {
     Type = type;
     Column = column;
     Value = value;
 }
Пример #6
0
 public Symbol(TerminalSymbolType terminalSymbol)
 {
     IsTerminal = true;
     TerminalSymbol = terminalSymbol;
 }