2

我正在创建一个程序,使用户能够创建某种脚本。我在运行时编译他的脚本然后执行。我正在做类似的事情:https ://stackoverflow.com/a/4181855/637142

无论如何,为了让长话短说,基本上我必须替换所有以 $ 开头的变量。用于使脚本编译的东西。如果用户有以下行:

var x = ($MyArray[ 4 ].Size) + 3;

什么正则表达式可以让我选择$MyArray[ 4 ].Size

如果用户在哪里写:

var x = $SomeVar;

在那种情况下,很容易找到SomeVar。我无法找到以 $ 开头的变量

编辑

我想我已经接近找到解决方案了。现在我正在用这个词替换 $ ,Foo.换句话说,我替换了该行:

var x = ($MyArray[ 4 ].Size) + 3;

为了

dynamic Foo; // then
var x = (Foo.MyArray[ 4 ].Size) + 3;

现在它编译但我仍然需要找到Foo.MyArray[ 4 ].Size

编辑 2

我不是想创建一个编译器,我只需要替换一些变量(以 $ 开头的变量)而已;)

4

3 回答 3

2

听起来您正在尝试使用正则表达式将脚本语言转换为不同的语言。正确地执行此操作将需要比正则表达式所能管理的更多的东西。

我强烈建议使用现有的解析系统来为您管理脚本,因为他们会考虑许多此类外部性并创建一种成熟的语言来工作。例如,Lua 是一种常见的选择。

或者,您可能希望编写一个适当的解析器来处理将原始源代码转换为一棵树,然后可以遍历该树以生成结果代码。

于 2013-08-14T20:09:10.133 回答
1

我不确定我是否完全理解这个问题。

你正在尝试制作一个编译器?我的朋友,这并不容易。编译器一般会经历 5 个阶段:

  • 词法分析
  • 解析
  • 语义分析
  • 优化
  • 代码生成

在我看来,您正在尝试完成词法分析阶段。如果是这样,您可以使用许多程序来完成此任务。其中一种工具称为 C# LEX。它是生成分析代码和生成标记的程序的绝佳工具。

以下是 LEX 脚本的示例:

    %%

    ALPHABET = [a-zA-Z]*

    %%

    <YYINITIAL>{ALPHABET} { return ("STRING"); }

C# LEX 获取此 .lex 文件并对其进行解析。然后它会生成一个 C# 程序,该程序可以分析任何适合您的词法分析器指定的语言的脚本。

谢谢,

于 2013-08-14T20:11:58.680 回答
0

在花费大量时间后设法执行正则表达式。

所以如果我有代码:

if (0 == $Foo.Arr1[7 + Arr2_5[3-1] ].More[8].Yes-9) {
  // do something
} 

在那种情况下,我会想要匹配$Foo.Arr1[7 + Arr2_5[3-1] ].More[8].Yes

以下正则表达式将匹配:

(?xi)
(?>
      (?<Q> "      )    # quote
    | (?<C> //     )    # comment
    | (?<N> [^"\$] )    # nothing
    | (?<D> \$     )    # dollar sign
)
(?(Q) .+? (\r|\n|$|") ) # if a quote is match continue selecting until you find next quote
(?(C) .+? (\r|\n|$)   ) # if a comment // or /* is match continue selecting until end of line
(?(N) (?=(?!))        )
(?(D)                   # if dollar sign is matched then:
  (

    (?(B)(?<-B>)){15}  # make sure group has a count of 0

    (?<V> [a-z|_]     ) # variable must start with letter of under score
    (?>
            (?<B>   \[        )                   # match [
       |    (       [^\s\)\(+\-@\#$%\^&\*=`~,\\\|\[\]] )  # or anything that is not a space, +, @ etc..
    )*
    (?(B)                                         # if you match a bracket then:
        (
           (?>
                    [^\[\]]
                 |    \[ (?<numberP>)                # balance match until opening ( = closing )
                 |    \] (?<-numberP>)
            )*
            \]
            (?(numberP)(?!))
            \.? 
        )
    )  # basically if you match a bracket keep selecting until you find even number of closing ]
  )
  +   # repeat this as many times as you can
)
(?(Q)(?!))   # Make regex fail if any of the following cases
(?(C)(?!))
(?(N)(?!))
于 2013-08-14T20:53:11.520 回答