2

Ok, i have a need to store some simple programming code text in DB, & then my application will read these text & convert them into actual programming code.

A good example is sqlfiddle.com. This website allow you to put sql code into it website, u then click a button & u can see the table result of that sql code. Ofcourse sqlfiddle must store the Txt-based code that u input into its database.

Another example is w3schools.com. It allows user to submit html code & then users can see the result on the fly. Ex:http://www.w3schools.com/js/tryit.asp?filename=tryjs_events

In my case i just need to use some limited keywords such as (if, for, while, +, *, -, /...)

Ex, I have a table called OrderItem with 3 columns:

ItemID - Qantity -Cost
Item1 - 10 - 5 USD
Item2 - 12 - 2 USD
Item3 - 4 - 1 USD

I also have a table ProgrammingCode

ItemID - Code
Item1 - "if quantity > 2 then totalcost=10*5 USD else totalCost=10*4USD; return totalCost"
Item2 - "if time=9am then totalcost=12*2 USD else totalCost=12*1USD; return totalCost "

Note: since there are variety of calculating rules in the real world, the code should be able to depict the real world so If or loop & all arithmetic operators should be used.

This is my Pseudocodefunction but i don't think it works.

    public String covertCode(String textBasedCode){
        String[] eachWord=textBasedCode.split(" ");
        if(eachWord[0].equals("if")){
             //do a lot of checking. how to let the program to know this?
             if(eachWord[2]>2{
                 return 10*5;
             }
             else{
                 return 10*4;
              }
         }
      }

I used java in this example, but u can use C++, C# php or any programming language you want. I just want to know the logic.

So, How to convert Text-based programming code (stored in DB) into actual programming code?

4

5 回答 5

2

您可以创建自己的迷你解释器来解释代码。它不应该花费很长时间,因为您希望它受到限制。

但由于它所做的只是计算值,我认为您可以让他们存储数字,然后按照您的规则在代码中进行数学运算。大多数数据库都内置了很多函数,所以这也可以在数据库中完成。

我只是看不出“基于文本的编程代码”与“实际编程代码”有何不同。

因此,您可以为此使用解释器设计模式。可能还有其他方法,但这是我最好的猜测。如果那是你要找的,你将不会得到代码。

于 2013-08-15T08:25:45.443 回答
1

查看 Roslyn 项目。它使您有机会使用编译器作为服务来创建插件、代码分析器等。

http://msdn.microsoft.com/en-us/vstudio/hh500769.aspx

http://blog.filipekberg.se/2013/02/07/compilation-as-a-service-and-the-next-generation-plugins/

于 2013-08-15T08:32:08.297 回答
1

您可以使用Microsoft.CSharp.CSharpCodeProvider即时编译代码。特别是,检查CompileAssemblyFromFile

于 2013-08-15T08:18:37.430 回答
0

困难的方法是解释数据库中的代码,更简单的方法是存储 c# 代码并使用 CodeDOM 运行时编译它http://msdn.microsoft.com/en-us/library/y2k85ax6.aspx

或者看看 Iron Python。http://ironpython.net/

于 2013-08-15T08:09:33.507 回答
0

我想我根据 Touch 建议我的解释器模式的建议找到了一个优雅的解决方案。我以前不知道解释器模式,但在阅读了 15 分钟后,我可以想出一个很酷的解决方案。我以前从未获得过公认的答案,所以我希望我的答案能获得它。

逻辑很简单。我们必须使用“逆波兰表示法”,例如:

ab +
abc + -
ab + ca - -

&这就完成了。http://en.wikipedia.org/wiki/Interpreter_pattern

     interface Expression {
    public int interpret(Map<String,Expression> variables);
}

class Number implements Expression {
    private int number;
    public Number(int number)       { this.number = number; }
    public int interpret(Map<String,Expression> variables)  { return number; }
}

class Plus implements Expression {
    Expression leftOperand;
    Expression rightOperand;
    public Plus(Expression left, Expression right) { 
        leftOperand = left; 
        rightOperand = right;
    }

    public int interpret(Map<String,Expression> variables)  { 
        return leftOperand.interpret(variables) + rightOperand.interpret(variables);
    }
}

class Minus implements Expression {
    Expression leftOperand;
    Expression rightOperand;
    public Minus(Expression left, Expression right) { 
        leftOperand = left; 
        rightOperand = right;
    }

    public int interpret(Map<String,Expression> variables)  { 
        return leftOperand.interpret(variables) - rightOperand.interpret(variables);
    }
}
class Times implements Expression {
    Expression leftOperand;
    Expression rightOperand;
    public Times(Expression left, Expression right) { 
        leftOperand = left; 
        rightOperand = right;
    }

    public int interpret(Map<String,Expression> variables)  { 
        return leftOperand.interpret(variables) * rightOperand.interpret(variables);
    }
} 

class Division implements Expression {
    Expression leftOperand;
    Expression rightOperand;
    public Division(Expression left, Expression right) { 
        leftOperand = left; 
        rightOperand = right;
    }

    public int interpret(Map<String,Expression> variables)  { 
        return leftOperand.interpret(variables) / rightOperand.interpret(variables);
    }
}

class IfThen implements Expression {
    Expression leftOperand;
    Expression rightOperand;
    public IfThen(Expression left, Expression right) { 
        leftOperand = left; 
        rightOperand = right;
    }

    public int interpret(Map<String,Expression> variables)  { 
        return (leftOperand.interpret(variables)==1) ? rightOperand.interpret(variables) : 0;
    }
}

class GreaterThan implements Expression {
    Expression leftOperand;
    Expression rightOperand;
    public GreaterThan(Expression left, Expression right) { 
        leftOperand = left; 
        rightOperand = right;
    }

    public int interpret(Map<String,Expression> variables)  { 
        return (leftOperand.interpret(variables) > rightOperand.interpret(variables)) ? 1 : 0;
    }
}

class GreaterThanOrEqual implements Expression {
    Expression leftOperand;
    Expression rightOperand;
    public GreaterThanOrEqual(Expression left, Expression right) { 
        leftOperand = left; 
        rightOperand = right;
    }

    public int interpret(Map<String,Expression> variables)  { 
        return (leftOperand.interpret(variables) >= rightOperand.interpret(variables)) ? 1 : 0;
    }
}
class LessThan implements Expression {
    Expression leftOperand;
    Expression rightOperand;
    public LessThan(Expression left, Expression right) { 
        leftOperand = left; 
        rightOperand = right;
    }

    public int interpret(Map<String,Expression> variables)  { 
        return (leftOperand.interpret(variables) < rightOperand.interpret(variables)) ? 1 : 0;
    }
}

class LessThanOrEqual implements Expression {
    Expression leftOperand;
    Expression rightOperand;
    public LessThanOrEqual(Expression left, Expression right) { 
        leftOperand = left; 
        rightOperand = right;
    }

    public int interpret(Map<String,Expression> variables)  { 
        return (leftOperand.interpret(variables) <= rightOperand.interpret(variables)) ? 1 : 0;
    }
}

class Equal implements Expression {
    Expression leftOperand;
    Expression rightOperand;
    public Equal(Expression left, Expression right) { 
        leftOperand = left; 
        rightOperand = right;
    }

    public int interpret(Map<String,Expression> variables)  { 
        return (leftOperand.interpret(variables) == rightOperand.interpret(variables)) ? 1 : 0;
    }
}
class Variable implements Expression {
    private String name;
    public Variable(String name)       { this.name = name; }
    public int interpret(Map<String,Expression> variables)  { 
        if(null==variables.get(name)) return 0; //Either return new Number(0).
        return variables.get(name).interpret(variables); 
    }
}
class Evaluator implements Expression {
    private Expression syntaxTree;

    public Evaluator(String expression) {
        Stack<Expression> expressionStack = new Stack<Expression>();
        for (String token : expression.split(" ")) {
            if  (token.equals("+")) {
                Expression subExpression = new Plus(expressionStack.pop(), expressionStack.pop());
                expressionStack.push( subExpression );
            }
            else if (token.equals("-")) {
                // it's necessary remove first the right operand from the stack
                Expression right = expressionStack.pop();
                // ..and after the left one
                Expression left = expressionStack.pop();
                Expression subExpression = new Minus(left, right);
                expressionStack.push( subExpression );
            }
            else if  (token.equals("*")) {
                Expression subExpression = new Times(expressionStack.pop(), expressionStack.pop());
                expressionStack.push( subExpression );
            }
            else if  (token.equals("/")) {
                // it's necessary remove first the right operand from the stack
                Expression right = expressionStack.pop();
                // ..and after the left one
                Expression left = expressionStack.pop();
                Expression subExpression = new Division(left, right);
                expressionStack.push( subExpression );
            }
            else if  (token.equals("if-then")) {
                // it's necessary remove first the right operand from the stack
                Expression right = expressionStack.pop();
                // ..and after the left one
                Expression left = expressionStack.pop();
                Expression subExpression = new IfThen(left, right);
                expressionStack.push( subExpression );
            }
            else if  (token.equals(">")) {
                // it's necessary remove first the right operand from the stack
                Expression right = expressionStack.pop();
                // ..and after the left one
                Expression left = expressionStack.pop();
                Expression subExpression = new GreaterThan(left, right);
                expressionStack.push( subExpression );
            }
            else if  (token.equals(">=")) {
                // it's necessary remove first the right operand from the stack
                Expression right = expressionStack.pop();
                // ..and after the left one
                Expression left = expressionStack.pop();
                Expression subExpression = new GreaterThanOrEqual(left, right);
                expressionStack.push( subExpression );
            }
            else if  (token.equals("<")) {
                // it's necessary remove first the right operand from the stack
                Expression right = expressionStack.pop();
                // ..and after the left one
                Expression left = expressionStack.pop();
                Expression subExpression = new LessThan(left, right);
                expressionStack.push( subExpression );
            }
            else if  (token.equals("<=")) {
                // it's necessary remove first the right operand from the stack
                Expression right = expressionStack.pop();
                // ..and after the left one
                Expression left = expressionStack.pop();
                Expression subExpression = new LessThanOrEqual(left, right);
                expressionStack.push( subExpression );
            }
            else if  (token.equals("==")) {
                // it's necessary remove first the right operand from the stack
                Expression right = expressionStack.pop();
                // ..and after the left one
                Expression left = expressionStack.pop();
                Expression subExpression = new Equal(left, right);
                expressionStack.push( subExpression );
            }
            else                        
                expressionStack.push( new Variable(token) );
        }
        syntaxTree = expressionStack.pop();
    }

    public int interpret(Map<String,Expression> context) {
        return syntaxTree.interpret(context);
    }
}

& 而已。要调用转换方法,我们只需要这个。看这个简单的代码:

    String expression = "w x == z if-then";
                //String expression = "w x - z +";
                Evaluator sentence = new Evaluator(expression);
                Map<String,Expression> variables = new HashMap<String,Expression>();
                variables.put("w", new Number(10));
                variables.put("x", new Number(5));
                variables.put("z", new Number(42));
                int result = sentence.interpret(variables);
                System.out.println(result);

& 就完成了。但它有一个限制,它没有循环,但如果 then 对我来说已经足够了。

我做得对吗?

于 2013-08-15T11:35:24.360 回答