/// <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; }
/// <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; }
public Symbol(TerminalSymbolType terminalSymbol) { IsTerminal = true; TerminalSymbol = terminalSymbol; }