脚本:读取用单词写的条件并转换成C - 三元运算符

use*_*265 2 perl

我是perl脚本的新手.我正在编写脚本来读取excel文件并在C编程语法中输入文本文件.

所以我excel sheet我有如下字符串:

If ((Myvalue.xyz == 1) Or (Frmae_1.signal_1 == 1)) Then a = 1
else a = 0;
Run Code Online (Sandbox Code Playgroud)

我必须转换成:

a = (((Myvalue.xyz == 1) || (Frmae_1.signal_1 == 1))?1:0)
Run Code Online (Sandbox Code Playgroud)

如何在perl中处理这个问题?

amo*_*mon 8

我不认为在代码字符串中使用正则表达式会是一个特别好的主意.输入的语法看起来不太特别,所以我们可以用Marpa解析它,使用类似的语法

:default    ::= action => [values]
:start      ::= StatementList
:discard    ~   ws

StatementList ::= <Expression>+ separator => <op semicolon> bless => Block

Expression ::=
        ('(') Expression (')')  assoc => group action => ::first
    |   Number                  bless => Number
    ||   Ident                  bless => Var
    ||  Expression  ('==')  Expression  bless => Numeric_eq
    ||  Expression  ('=' )  Expression  bless => Assign
    ||  Expression  ('Or')  Expression  bless => Logical_or
    ||  Conditional

Conditional ::=
        ('If') Expression ('Then') Expression
            bless => Cond
    |   ('If') Expression ('Then') Expression ('Else') Expression
            bless => Cond

Ident   ~ ident
Number  ~ <number int> | <number rat>

word    ~ [\w]+
ident   ~ word | ident '.' word
<number int> ~ [\d]+
<number rat> ~ <number int> '.' <number int>
ws      ~ [\s]+
<op semicolon> ~ ';'
Run Code Online (Sandbox Code Playgroud)

然后:

use Marpa::R2;
my $grammar = Marpa::R2::Scanless::G->new({
    bless_package => 'Ast',
    source => \$the_grammar,
});
my $recce = Marpa::R2::Scanless::R->new({ grammar => $grammar });
$recce->read(\$the_string);
my $val = $recce->value // die "No parse found";
my $ast = $$val;
Run Code Online (Sandbox Code Playgroud)

只要我们有AST,将其编译为类似C的表示并不过分复杂.通过"优化"过程分解共同任务可以通过一些思考来完成.

然而,展示如何做到这一点是相当漫长的,所以我把所有深入的东西放到这篇博文中.然后我们可以定义一个通过树递归并发出类似C的代码的方法,例如

package Ast::Var;
...;
sub compile { my $self = shift; $self->name } # no modification needed

package Ast::Logical_Or;
...;
sub compile {
  my $self = shift;
  # C's "||" operator, plus parens to specify precedence
  "(" . $self->l->compile . "||" . $self->r->compile . ")";
}

package Ast::Cond;
...;
sub compile {
  my $self = shift;
  return sprintf '(%s ? %s : %s)',
      $self->cond->compile,
      $self->then->compile,
      $self->else->compile;
}
Run Code Online (Sandbox Code Playgroud)

等所有其他AST节点类型.