(La) Разбор текстовой математики для C / C ++ - PullRequest
12 голосов
/ 27 января 2011

Я хотел бы преобразовать математические выражения parse (la) tex и преобразовать их в (любой вид!) Выражения языка сценариев, чтобы я мог оценить выражения.Какие библиотеки вы рекомендуете?

Ответы [ 4 ]

1 голос
/ 28 января 2011

Возможно, это поможет - взгляните на TeXmacs , особенно на то, как он взаимодействует с системами компьютерной алгебры.

1 голос
/ 27 января 2011

Возможно использование boost::spirit для токенизации выражения. Вам нужно будет определить огромную грамматику!

0 голосов
/ 29 января 2011

Вот набор возможных вариантов из аналогичного вопроса.https://tex.stackexchange.com/questions/4223/what-parsers-for-latex-mathematics-exist-outside-of-the-tex-engines

Я думаю, что Perl сделал бы хороший выбор для чего-то подобного, действие над текстом - это одна из его сильных сторон.

Вот некоторая информация о том, как сделать эксклюзивный флип-Флоп-тест (чтобы найти контекст между \ begin {} и \ end {} без сохранения этих строк), http://www.effectiveperlprogramming.com/2010/11/make-exclusive-flip-flop-operators/

РЕДАКТИРОВАТЬ: Таким образом, эта проблема начала меня.Вот первая попытка создать что-то здесь, это мой "math.pl", который принимает файл .tex в качестве аргумента (то есть $./math.pl test.tex).

#!/usr/bin/env perl

use strict;
use warnings;

use Text::Balanced qw/extract_multiple extract_bracketed/;

my $re_num = qr/[+\-\dE\.]/;

my $file = shift;

open( my $fh, '<', $file);

#parsing this out for more than just the equation environment might be easier using Text::Balanced too.
my @equations;
my $current_equation = '';
while(<$fh>) {
  my $test;
  next unless ($test = /\\begin\{equation\}/ .. /\\end\{equation\}/);

  if ($test !~ /(^1|E0)$/ ) {
    chomp;
    $current_equation .= $_;
  } elsif ($test =~ /E0$/) {
    #print $current_equation . "\n";
    push @equations, {eq => $current_equation};
    $current_equation = '';
  }
}

foreach my $eq (@equations) {
  print "Full Equation: " . $eq->{'eq'} . "\n";
  solve($eq);
  print "Result: " . $eq->{'value'} . "\n\n";
}

sub solve {
  my $eq = shift;

  print $eq->{'eq'} . "\n";

  parse($eq);
  compute($eq);

  print "intermediate result: " . $eq->{'value'} . "\n";
}

sub parse {
  my $eq = shift;

  my ($command,@fields) = extract_multiple(
    $eq->{'eq'}, [ sub { extract_bracketed(shift,'{}') } ]
  );

  $command =~ s/^\\//;
  print "command: " . $command . "\n";

  @fields = map { s/^\{\ *//; s/\ *\}$//; print "arg: $_\n"; {value => $_}; } @fields;


  ($eq->{'command'}, @{ $eq->{'args'} }) = ($command, @fields);
}

sub compute {
  my ($eq) = @_;

  #check arguements ...
  foreach my $arg (@{$eq->{'args'}}) {
    #if arguement is a number, continue
    if ($arg->{'value'} =~ /^$re_num$/) {
      next;

    #if the arguement is a simple mathematical operation, do it and continue
    } elsif ($arg->{'value'} =~ /^($re_num)\ *(?:\ |\*|\\times)?\ *($re_num)$/) {
      $arg->{'value'} = $1 * $2;
    } elsif ($arg->{'value'} =~ /^($re_num)\ *(?:\+)?\ *($re_num)$/) {
      $arg->{'value'} = $1 + $2;
    } elsif ($arg->{'value'} =~ /^($re_num)\ *(?:\-)?\ *($re_num)$/) {
      $arg->{'value'} = $1 - $2;
    } elsif ($arg->{'value'} =~ /^($re_num)\ *(?:\/)?\ *($re_num)$/) {
      $arg->{'value'} = $1 / $2;
    } else {
      #parse it and calc it as if it were its own equation.
      $arg->{'eq'} = $arg->{'value'};
      solve($arg);
    }
  }

  my @args = @{$eq->{'args'}};

  ## add command processing here
  # frac
  if ($eq->{'command'} eq 'frac') {
    $eq->{'value'} = $args[0]->{'value'} / $args[1]->{'value'};
    return;
  }

}

и вот пример test.tex:

\documentclass{article}

\begin{document}

Hello World!

\begin{equation}
\frac{\frac{1}{3}}{2}
\end{equation}

\end{document}
0 голосов
/ 28 января 2011

Используйте генератор парсера для создания соответствующего парсера.Попробуйте ANTLR для этого, так как он включает IDE для грамматики, что очень полезно.Используя правила перезаписи дерева, вы можете затем преобразовать дерево разбора в абстрактное синтаксическое дерево.

Начните, возможно, с оценщика выражений из руководства ANTLR.Я думаю, что это достаточно близко.

...