所以我在网上搜索一个,但我找到的只有几个类可以帮助你验证JavaScript,但是我需要一种方法来加载它,解析它然后再写回来。所以我想知道是否有人对如何做到这一点有任何想法。我假设它不需要太多代码,也不必是C#示例。如果你能用C ++甚至伪代码给我一些想法,那将会有很大的帮助。
谢谢,
弗拉基米尔
答案 0 :(得分:2)
手动创建递归下降解析器。这很有趣!
首先定义一个语法:
Expression -> SimpleExpression ExpressionTail
(Expression)
SimpleExpression -> Atom Inequality Atom
ExpressionTail -> && Expression |
|| Expression |
e
Atom -> Variable | Literal
Inequality -> == | != | > | >= | < | <=
(这个语法不处理运算符优先级,但很容易编写一个语法。)
接下来,创建一个词法分析器,它将读取输入字符串并创建标记,因此字符串“var1!= 4.0”将被转换为{Variable,!=,Literal}列表。这可能会被黑客攻击,或者如果你想获得幻想,你可以使用有限状态机来分析字符串。
现在创建一个递归下降解析器,将令牌列表解析为表达式树。
public class Parser {
public Parser() {
}
public Expression parse( LexicalAnalyzer lex) {
lex.advance();
return expression( lex);
}
private Expression expression( LexicalAnalyzer lex) {
switch( lex.current().type() ) {
case Token.OpenParen:
lex.advance();
Expression expression = expression( lex);
lex.eat( Token.CloseParen);
return expression;
case Token.Literal:
case Token.Variable:
return expressionTail( lex, simpleExpression(lex));
default:
throw new Exception( "ParseError: Expecting (, variable, or literal at character " +
lex.character());
}
}
private SimpleExpression simpleExpression( LexicalAnalyzer lex) {
Atom atom = atom( lex);
switch( lex.current().type() ) {
case Token.Equal:
lex.advance();
return new Equal( atom, atom(lex));
case Token.NotEqual:
lex.advance();
return new NotEqual( atom, atom(lex));
...
default:
throw new Exception( "ParseError: Expecting ==, !=, <, <=, >, >= at" +
lex.character());
}
}
private Expression expressionTail( LexicalAnalyzer lex, SimpleExpression expression) {
switch( lex.current().type() ) {
case Token.LogicalOr:
lex.advance();
return new OrExpression( expression, expression(lex) );
case Token.LogicalAnd:
lex.advance();
return new AndExpression( expression, exptression(lex) );
default:
return expression;
}
}
private Atom atom( LexicalAnalyzer lex) {
switch( lex.current().type() ) {
case Token.Literal:
Literal literal = new Literal( lex.current() );
lex.advance();
return literal;
case Token.Variable:
Variable var = new Variable( lex.current() );
lex.advance();
return var;
default:
throw new Exception("ParseError: ...");
}
}
}
public interface Expression {
boolean evaluate( VariableValues values);
}
public interface SimpleExpression implements Expression {
}
public class Equal implements SimpleExpression {
private final Atom left, right;
public Equal( Atom left, Atom right) {
this.left = left;
this.right = right;
}
public boolean evaluate( VariableValues values) {
return left.evaluate(values) == right.evaluate(values);
}
}
public class NotEqual implements SimpleExpression {
private final Atom left, right;
public NotEqual( Atom left, Atom right) {
this.left = left;
this.right = right;
}
public boolean evaluate( VariableValues values) {
return left.evaluate(values) != right.evaluate(values);
}
}
public class OrExpression implements Expression {
private final Expression left, right;
public OrExpression( Expression left, Expression right) {
this.left = left;
this.right = right;
}
public boolean evaluate( VariableValues values) {
return left.evaluate(values) || right.evaluate(values);
}
}
public class AndExpression implements Expression {
private final Expression left, right;
public AndExpression( Expression left, Expression right) {
this.left = left;
this.right = right;
}
public boolean evaluate( VariableValues values) {
return left.evaluate(values) && right.evaluate(values);
}
}
public interface Atom {
double evaluate( VariableValues values);
}
public class Literal implements Atom {
private final double value;
public Literal( double value) {
this.value = value;
}
public double evaluate( VariableValues values) {
return value;
}
}
public class Variable implements Atom {
private final String name;
public Variable( String name) {
this.name = name;
}
public double evaluate( VariableValues values) {
return values.getValue( name);
}
}
答案 1 :(得分:1)
以下是用JavaScript编写的:http://silentmatt.com/parser3.js(来自:Javascript parser for simple expression)。移植会很痛苦,但这是一个开始。
答案 2 :(得分:1)
C#here at CodeProject中提供了一个JavaScript子集的实现。
答案 3 :(得分:0)
我在flash / actionscrpt中做过类似的事情。我认为它在Silverlight中几乎相同。快速谷歌搜索后,我看到RegisterScriptableObject类似于ActionScript的ExternalInterface。无论如何,这是我的example。
This Silverlight示例非常接近于做同样的事情。