Die Copyrighthinweise zu folgendem Code befinden sich als Kommentare an den Dateiköpfen.

Datei reference.php:

<html>
<head>
<title>Parser-Referenz</title>
<link rel="stylesheet" type="text/css" href="units/style.css">
</head>
<body>
<?php

   
####################################################################################
   # Dies ist die Datei 'reference.php'                                               #
   #                                                                                  #
   # Sie enth"alt Funktions- und "ahnliche Definitionen des Parser/Plotter-Projekts   #
   #                                                                                  #
   # Diese Datei darf frei als Ganzes oder in Teilen f"ur jegliche nicht-             #
   # kommerzielle Zwecke verwandt werden, solange folgede Bedingungen erf"ullt        #
   # werden:                                                                          #
   #    - Dieser Blockkommentar mit den Nutzungsbedingungen muss unver"andert         #
   #      in allen Nachfolgedateien / -ver"offentlichungen am Datei- / Textkopf       #
   #      verwandt werden                                                             #
   #    - Der Quellcode des muss jedem Benutzer von allen Programmen, die ihn         #
   #      verwenden, einsehbar gemacht werden                                         #
   #                                                                                  #
   # Sollten Sie diesen Code, in Teilen oder als Ganzes, auch portiert in             #
   # andere Programmiersprachen oder unter blo"ser Verwendung des Algorithmus         #
   # oder von Teilen von verwandten Algorithmen, f"ur kommerzielle Zwecke nutzen      #
   # wollen, so kontaktieren Sie mich bitte.                                          #
   #                                                                                  #
   # Ich habe den vorliegenden Code von Grund auf selbst programmiert und mich        #
   # dabei auf keine anderen als Standardalgorithmen gest"utzt. Insbesondere den      #
   # Tokenizer, der Parser und die Schrittweitensteurerung habe ich von Grund         #
   # auf und ohne Zuhilfenahme anderer Quellen selbst programmiert. Sollte ich        #
   # mit dem vorliegenden Code bestehende Copyrights oder Patente verletzen oder      #
   # den Urheber geistigen Eigentums vorenthalten, so geschieht dies                  #
   # unabsichtlich. Bitte kontaktieren Sie mich mittels untenstehender E-Mail-        #
   # Adresse oder "uber den Sysadmin.                                                 #
   #                                                                                  #
   # Der Autor "ubernimmt keine Haftung f"ur eventuelle durch die Nutzung dieses      #
   # entstehende oder entstandene mittelbare oder unmittelbare Sch"aden jedweder Art. #
   # Nutzung auf eigene Gefahr.                                                       #
   #                                                                                  #
   # Bitte schicken Sie mir keine E-Mails mit Bitte um die Erkl"arung der             #
   # Funktionsweise des Codes oder von Teilen des Codes; ich habe mich bem"uht,       #
   # den Code so gut wie m"oglich zu kommentieren und habe leider nicht genug         #
   # Zeit, um E-Mails "uber technische Details zu beantworten.                        #
   #                                                                                  #
   # (c) Jan Olligs, 2004                                                             #
   # Alle Rechte vorbehalten                                                          #
   #                                                                                  #
   # Jan.Olligs@gmx.net                                                               #
   ####################################################################################

   
include("units/mathdef.php");

   function 
table_row($array$item$title) {
      if (
array_key_exists($item$array) and (!is_array($array[$item]) or != count($array[$item]))) {
         print 
"   <tr>\n";
         print 
"      <td><b>$title:</b></td>\n";
         if (
is_array($array[$item])) {
            print 
"      <td>" implode(', 'array_map('htmlspecialchars'$array[$item])) . "</td>\n";
         } else {
            print 
"      <td>" htmlspecialchars($array[$item]) . "</td>\n";
         }
         print 
"   </tr>\n";
      }
   }
?>
Die folgenden <i><b>Funktionen (un&auml;re Operatoren)</b></i> werden unterst&uuml;tzt:<br>
<?php
   
foreach ($global_unary_operators as $name => $properties) {
      if (!
is_array($properties)) {
         continue; 
# ACHTUNG: Das w"are ein Implementierungsfehler
      
}
      print 
"<table>\n";
      print 
"   <tr>\n";
      print 
"      <td><b>Funktion:</b></td>\n";
      print 
"      <td><i>" htmlspecialchars($name) . "</i></td>\n";
      print 
"   </tr>\n";
      
table_row($properties'name',    'Name');
      
table_row($properties'others',  'Varianten');
      
table_row($properties'info',    'Information');
      
table_row($properties'example''Beispiel(e)');
      print 
"</table>\n";
      print 
"<br>\n\n";
   }
?>
<br>
Die folgenden <i><b>Operatoren (bin&auml;re Operatoren)</b></i> werden unterst&uuml;tzt:<br>
<?php
   $i 
0;
   foreach (
$global_binary_operators as $prec) {
      ++
$i;
      print 
"<u>Pr&auml;zedenz $i</u>:\n";
      foreach (
$prec as $name => $properties) {
         if (!
is_array($properties)) {
            continue; 
# ACHTUNG: Das w"are ein Implementierungsfehler
         
}
         print 
"<table>\n";
         print 
"   <tr>\n";
         print 
"      <td><b>Operator:</b></td>\n";
         print 
"      <td><i>" htmlspecialchars($name) . "</i></td>\n";
         print 
"   </tr>\n";
         
table_row($properties'name',    'Name');
         
table_row($properties'info',    'Information');
         
table_row($properties'example''Beispiel(e)');
         print 
"</table>\n";
         print 
"<br>\n\n";
      }
   }
?>
<br><br>
Die folgenden <i><b>Konstanten</i></b> sind definiert:<br>
<?php
   
foreach ($global_constants as $const => $value) {
      print 
"$const = $value<br>\n";
   }
?>
<br><br>
Au&szlig;erdem sind folgende <i><b>Klammern</i></b> verf&uuml;gbar:<br>
<?php
   
foreach ($global_parens as $pair) {
      print 
"&ouml;ffnet als '$pair[0]', schlie&szlig;t als '$pair[1]'<br>\n";
   }
?>
<br><br><br>
<a href="source.php">&copy; Jan Olligs, 2004</a>
</body>
</html>

Datei source.php:

<html>
<head>
<title>Funktionsparser Quellcode</title>
</head>
<body>
Die Copyrighthinweise zu folgendem Code befinden sich als Kommentare an den
Dateik&ouml;pfen.
<?php

   
####################################################################################
   # Dies ist die Datei 'source.php'                                                  #
   #                                                                                  #
   # Sie enth"alt Funktions- und "ahnliche Definitionen des Parser/Plotter-Projekts   #
   #                                                                                  #
   # Diese Datei darf frei als Ganzes oder in Teilen f"ur jegliche nicht-             #
   # kommerzielle Zwecke verwandt werden, solange folgede Bedingungen erf"ullt        #
   # werden:                                                                          #
   #    - Dieser Blockkommentar mit den Nutzungsbedingungen muss unver"andert         #
   #      in allen Nachfolgedateien / -ver"offentlichungen am Datei- / Textkopf       #
   #      verwandt werden                                                             #
   #    - Der Quellcode des muss jedem Benutzer von allen Programmen, die ihn         #
   #      verwenden, einsehbar gemacht werden                                         #
   #                                                                                  #
   # Sollten Sie diesen Code, in Teilen oder als Ganzes, auch portiert in             #
   # andere Programmiersprachen oder unter blo"ser Verwendung des Algorithmus         #
   # oder von Teilen von verwandten Algorithmen, f"ur kommerzielle Zwecke nutzen      #
   # wollen, so kontaktieren Sie mich bitte.                                          #
   #                                                                                  #
   # Ich habe den vorliegenden Code von Grund auf selbst programmiert und mich        #
   # dabei auf keine anderen als Standardalgorithmen gest"utzt. Insbesondere den      #
   # Tokenizer, der Parser und die Schrittweitensteurerung habe ich von Grund         #
   # auf und ohne Zuhilfenahme anderer Quellen selbst programmiert. Sollte ich        #
   # mit dem vorliegenden Code bestehende Copyrights oder Patente verletzen oder      #
   # den Urheber geistigen Eigentums vorenthalten, so geschieht dies                  #
   # unabsichtlich. Bitte kontaktieren Sie mich mittels untenstehender E-Mail-        #
   # Adresse oder "uber den Sysadmin.                                                 #
   #                                                                                  #
   # Der Autor "ubernimmt keine Haftung f"ur eventuelle durch die Nutzung dieses      #
   # entstehende oder entstandene mittelbare oder unmittelbare Sch"aden jedweder Art. #
   # Nutzung auf eigene Gefahr.                                                       #
   #                                                                                  #
   # Bitte schicken Sie mir keine E-Mails mit Bitte um die Erkl"arung der             #
   # Funktionsweise des Codes oder von Teilen des Codes; ich habe mich bem"uht,       #
   # den Code so gut wie m"oglich zu kommentieren und habe leider nicht genug         #
   # Zeit, um E-Mails "uber technische Details zu beantworten.                        #
   #                                                                                  #
   # (c) Jan Olligs, 2004                                                             #
   # Alle Rechte vorbehalten                                                          #
   #                                                                                  #
   # Jan.Olligs@gmx.net                                                               #
   ####################################################################################

   
$files = array(
      
'reference.php',
      
'source.php',
      
'graph.php',
      
'plotter.php',
      
'tabs/error.php',
      
'tabs/functions.php',
      
'tabs/general.php',
      
'tabs/graph.php',
      
'units/mathdef.php',
      
'units/parser.php',
      
'units/graphics.php',
      
'units/plotter_constants.php',
      
'units/various.php'
   
);

   foreach (
$files as $name) {
      print 
"<h1>Datei <i>" htmlspecialchars($name) . "</i>:</h1>\n";
      
show_source($name);
   }

?>
</body>
</html>

Datei graph.php:

<?php

   
####################################################################################
   # Dies ist die Datei 'graph.php'                                                   #
   #                                                                                  #
   # Sie enth"alt den eigentlichen Plotter des Parser/Plotter-Projekts                #
   #                                                                                  #
   # Diese Datei darf frei als Ganzes oder in Teilen f"ur jegliche nicht-             #
   # kommerzielle Zwecke verwandt werden, solange folgede Bedingungen erf"ullt        #
   # werden:                                                                          #
   #    - Dieser Blockkommentar mit den Nutzungsbedingungen muss unver"andert         #
   #      in allen Nachfolgedateien / -ver"offentlichungen am Datei- / Textkopf       #
   #      verwandt werden                                                             #
   #    - Der Quellcode des muss jedem Benutzer von allen Programmen, die ihn         #
   #      verwenden, einsehbar gemacht werden                                         #
   #                                                                                  #
   # Sollten Sie diesen Code, in Teilen oder als Ganzes, auch portiert in             #
   # andere Programmiersprachen oder unter blo"ser Verwendung des Algorithmus         #
   # oder von Teilen von verwandten Algorithmen, f"ur kommerzielle Zwecke nutzen      #
   # wollen, so kontaktieren Sie mich bitte.                                          #
   #                                                                                  #
   # Ich habe den vorliegenden Code von Grund auf selbst programmiert und mich        #
   # dabei auf keine anderen als Standardalgorithmen gest"utzt. Insbesondere den      #
   # Tokenizer, der Parser und die Schrittweitensteurerung habe ich von Grund         #
   # auf und ohne Zuhilfenahme anderer Quellen selbst programmiert. Sollte ich        #
   # mit dem vorliegenden Code bestehende Copyrights oder Patente verletzen oder      #
   # den Urheber geistigen Eigentums vorenthalten, so geschieht dies                  #
   # unabsichtlich. Bitte kontaktieren Sie mich mittels untenstehender E-Mail-        #
   # Adresse oder "uber den Sysadmin.                                                 #
   #                                                                                  #
   # Der Autor "ubernimmt keine Haftung f"ur eventuelle durch die Nutzung dieses      #
   # entstehende oder entstandene mittelbare oder unmittelbare Sch"aden jedweder Art. #
   # Nutzung auf eigene Gefahr.                                                       #
   #                                                                                  #
   # Bitte schicken Sie mir keine E-Mails mit Bitte um die Erkl"arung der             #
   # Funktionsweise des Codes oder von Teilen des Codes; ich habe mich bem"uht,       #
   # den Code so gut wie m"oglich zu kommentieren und habe leider nicht genug         #
   # Zeit, um E-Mails "uber technische Details zu beantworten.                        #
   #                                                                                  #
   # (c) Jan Olligs, 2004                                                             #
   # Alle Rechte vorbehalten                                                          #
   #                                                                                  #
   # Jan.Olligs@gmx.net                                                               #
   ####################################################################################

   
include("units/mathdef.php");
   include(
"units/parser.php");
   include(
"units/graphics.php");
   include(
"units/plotter_constants.php");
   include(
"units/various.php");

   
####################################################################################
   # Inhalte des $_REQUEST-Arrays, die f"ur den Plotter relevant sind:                #
   #    'img_type'              - Ausgabeformat, siehe 'plotter_constants.php'        #
   #    'const'                 - Konstanten in der Form "[name]=[term]\n[name]..."   #
   #    'function_[\d]_[...]'   - Funktionen, siehe 'plotter_constants.php'           #
   #    'asymptote_[\d]_[...]'  - Asymptoten, siehe 'plotter_constants.php'           #
   #    'x_min'                 - kleinster dargestellter x-Wert                      #
   #    'x_max'                 - gr"o"ster dargestellter x-Wert                      #
   #    'x_grid'                - x-Gitterweite                                       #
   #    'y_min'                 - kleinster dargestellter y-Wert                      #
   #    'y_max'                 - gr"o"ster dargestellter y-Wert                      #
   #    'y_grid'                - y-Gitterweite                                       #
   #    'width'                 - Bildbreite in Pixel                                 #
   #    'height'                - Bildh"ohe in Pixel                                  #
   #    'step'                  - Schrittweite der Punkte (delta_x)                   #
   #    'auto_step'             - automatische Schrittweitensteuerung an ('true')     #
   #                              oder aus ('false')                                  #
   #    'bg_col'                - Hintergrundfarbe, siehe 'plotter_constants.php'     #
   #    'pl_col'                - Standardfunktionsfarbe, s. 'plotter_constants.php'  #
   #    'ax_col'                - Achsenfarbe, siehe 'plotter_constants.php'          #
   #    'gr_col'                - Gitterfarbe, siehe 'plotter_constants.php'          #
   #    's_min'                 - kleinster schattierter x-Wert                       #
   #    's_max'                 - gr"o"ster schattierter x-Wert                       #
   #    'sh_col'                - Schattenfarbe, siehe 'plotter_constants.php'        #
   #    's_trans'               - Schattentransparenz in Prozent                      #
   #    's_f1'                  - den Schatten einschlie"sende Funktion 1             #
   #    's_f2'                  - den Schatten einschlie"sende Funktion 2             #
   #    'sf_col'                - Farbe der einschlie"senden Funktionen, s. ...       #
   #    'do_shade'              - Schattieren an oder aus (s.o.)                      #
   ####################################################################################

   # F"ur aufwendige Graphen deaktivieren wir l"astige Zeitbegrenzungen ...

   
set_time_limit(0);

   
# F"ur das Einf"ugen von Malzeichen

   
$poss_for_mult array_merge(range('a''z'), range('A''Z'));
   foreach (
$global_parens as $pair) {
      
array_push($poss_for_mult$pair[0]);
   }

   
# Fehlercheck f"angt hier an

   
$image_type $_REQUEST['img_type'];
   if (!(
imagetypes() & $plotter_standards{'img_types'}[1][$image_type][1])) {
      
$image_type 0;
   }
   while (!(
imagetypes() & $plotter_standards{'img_types'}[1][$image_type][1])) {
      if (
$image_type >= count($plotter_standards{'img_types'})) {
         die;
      }
      ++
$image_type;
   }

   
# Zuerst parsen wir die Konstanten, da sie bei allen Termen ben"otigt werden

   
$constants = array();
   
$temp preg_split('/\n/'$_REQUEST['const']);
   foreach (
$temp as $t) {
      
$t preg_split('/=/'$t);
      if (!
is_array($t) or count ($t) != 2) {
         continue;
      }
      
$t[0] = ltrim(rtrim($t[0]));
      
$t[1] = ltrim(rtrim($t[1]));

      if (
check_parens($value$global_parens) > -1) {
         continue;
      }
      
$t[1] = check_minus($t[1], $global_parens);
      if (
$t[1][1] != $global_error_names['NOERROR']) {
         continue;
      }
      
$t[1] = $t[1][0];
      
$t[1] = add_times($t[1], $poss_for_mult'*');
      if (
$t[1][1] != $global_error_names['NOERROR']) {
         continue;
      }
      
$t[1] = $t[1][0];
      
$t[1] = tokenize($t[1], $global_parens$global_unary_operators,
                       
$global_binary_operators);
      if (
$t[1][1] != $global_error_names['NOERROR']) {
         continue;
      }
      
$t[1] = $t[1][0];
      
$t[1] = substitute($t[1], $global_constants);
      if (
$t[1][1] != $global_error_names['NOERROR']) {
         continue;
      }
      
$t[1] = $t[1][0];
      
$t[1] = build_tree($t[1], $global_parens$global_unary_operators$global_binary_operators);
      if (
$t[1][1] != $global_error_names['NOERROR']) {
         continue;
      }
      
$t[1] = $t[1][0][0];
      
$t[1] = build_stack($t[1]);
      if (
$t[1][1] != $global_error_names['NOERROR']) {
         continue;
      }
      
$t[1] = $t[1][0];
      
$t[1] = process_stack($t[1], $global_unary_operators$global_binary_operators);
      if (
$t[1][1] != $global_error_names['NOERROR']) {
         continue;
      }

      
$constants[$t[0]] = $t[1][0]; # Wenn bis hier noch kein Fehler aufgetreten
   
}                                # ist, speichern wir die Konstante

   
$constants array_merge($constants$global_constants);
      
# und f"uhren sie mit den Standardkonstanten zusammen

   # Jetzt holen wir uns die Funktionen und parsen die Terme in die Stacks

   
$functions unpack_function_terms($_REQUEST);

   foreach (
$functions as $key => $values) {
      if (
check_parens($values['term'], $global_parens) > -1) {
         unset(
$functions[$key]);
         continue;
      }
      
$values['stack'] = check_minus($values['term'], $global_parens);
      if (
$values['stack'][1] != $global_error_names['NOERROR']) {
         unset(
$functions[$key]);
         continue;
      }
      
$values['stack'] = $values['stack'][0];
      
$values['stack'] = add_times($values['stack'], $poss_for_mult'*');
      if (
$values['stack'][1] != $global_error_names['NOERROR']) {
         unset(
$functions[$key]);
         continue;
      }
      
$values['stack'] = $values['stack'][0];
      
$values['stack'] = tokenize($values['stack'], $global_parens$global_unary_operators,
                       
$global_binary_operators);
      if (
$values['stack'][1] != $global_error_names['NOERROR']) {
         unset(
$functions[$key]);
         continue;
      }
      
$values['stack'] = $values['stack'][0];
      
$values['stack'] = substitute($values['stack'], $constants);
      if (
$values['stack'][1] != $global_error_names['NOERROR']) {
         unset(
$functions[$key]);
         continue;
      }
      
$values['stack'] = $values['stack'][0];
      
$values['stack'] = build_tree($values['stack'], $global_parens$global_unary_operators$global_binary_operators);
      if (
$values['stack'][1] != $global_error_names['NOERROR']) {
         unset(
$functions[$key]);
         continue;
      }
      
$values['stack'] = $values['stack'][0][0];
      
$values['stack'] = build_stack($values['stack']);
      if (
$values['stack'][1] != $global_error_names['NOERROR']) {
         unset(
$functions[$key]);
         continue;
      }
      
$values['stack'] = $values['stack'][0];

      
$functions[$key] = $values;
      
$functions[$key]['param']['from'] = check_error($values['param']['from'], 'e'false'0');
      
$functions[$key]['param']['to'] = check_error($values['param']['to'], 'e'false'0');
      
$functions[$key]['param']['step'] = check_error($values['param']['step'], 'e'false'0');

      if (
$functions[$key]['param']['from'] > $functions[$key]['param']['to']) {
         
$temp                             $functions[$key]['param']['from'];
         
$functions[$key]['param']['from'] = $functions[$key]['param']['to'];
         
$functions[$key]['param']['to']   = $temp;
      }
   }

   
# Wir wollen mindestens eine Funktion haben, also ...

   
if (count($functions) == 0) {
      
array_push($functions, array(
         
'term'  => $plotter_standards{'func'}[1],
         
'color' => $plotter_standards{'PL_color'}[1],
         
'param' => array(
            
'name' => 'NOPARAM',
            
'from' => 0,
            
'to'   => 0,
            
'step' => 1
         
)
      ));
      
$key 0;
      
$values $functions[0];
         if (
check_parens($values['term'], $global_parens) > -1) {
            unset(
$functions[$key]);
            break;
         }
         
$values['stack'] = check_minus($values['term'], $global_parens);
         if (
$values['stack'][1] != $global_error_names['NOERROR']) {
            unset(
$functions[$key]);
            break;
         }
         
$values['stack'] = $values['stack'][0];
         
$values['stack'] = add_times($values['stack'], $poss_for_mult'*');
         if (
$values['stack'][1] != $global_error_names['NOERROR']) {
            unset(
$functions[$key]);
            break;
         }
         
$values['stack'] = $values['stack'][0];
         
$values['stack'] = tokenize($values['stack'], $global_parens$global_unary_operators,
                          
$global_binary_operators);
         if (
$values['stack'][1] != $global_error_names['NOERROR']) {
            unset(
$functions[$key]);
            break;
         }
         
$values['stack'] = $values['stack'][0];
         
$values['stack'] = substitute($values['stack'], $constants);
         if (
$values['stack'][1] != $global_error_names['NOERROR']) {
            unset(
$functions[$key]);
            break;
         }
         
$values['stack'] = $values['stack'][0];
         
$values['stack'] = build_tree($values['stack'], $global_parens$global_unary_operators$global_binary_operators);
         if (
$values['stack'][1] != $global_error_names['NOERROR']) {
            unset(
$functions[$key]);
            break;
         }
         
$values['stack'] = $values['stack'][0][0];
         
$values['stack'] = build_stack($values['stack']);
         if (
$values['stack'][1] != $global_error_names['NOERROR']) {
            unset(
$functions[$key]);
            break;
         }
         
$values['stack'] = $values['stack'][0];

      
$functions[$key] = $values;
      
$functions[$key]['param']['from'] = check_error($values['param']['from'], 'e'false'0');
      
$functions[$key]['param']['to'] = check_error($values['param']['to'], 'e'false'0');
      
$functions[$key]['param']['step'] = check_error($values['param']['step'], 'e'false'0');
   }

   
# Das gleiche Procedere f"ur die Asymptoten, aber ohne Stacks ...

   
$asymptotes unpack_asymptote_terms($_REQUEST);
   foreach (
$asymptotes as $key => $values) {
      
$asymptotes[$key]['p1_x']   = check_error($values['p1_x'],   'e'false$plotter_standards{'asym_px1'}[1], $constants);
      
$asymptotes[$key]['p1_y']   = check_error($values['p1_y'],   'e'false$plotter_standards{'asym_py1'}[1], $constants);
      
$asymptotes[$key]['p2_x']   = check_error($values['p2_x'],   'e'false$plotter_standards{'asym_px2'}[1], $constants);
      
$asymptotes[$key]['p2_y']   = check_error($values['p2_y'],   'e'false$plotter_standards{'asym_py2'}[1], $constants);
      
$asymptotes[$key]['color']  = check_error($values['color'],  'c'false$plotter_standards{'AS_color'}[1], $constants);
      
$asymptotes[$key]['dashed'] = check_error($values['dashed'], 'b'false$plotter_standards{'asym_dash'}[1], $constants);
   }

   
# Der Rest der Werte

   
$x_min  check_error($_REQUEST['x_min'],  'e'false$plotter_standards{'x_min'}[1], $constants);
   
$x_max  check_error($_REQUEST['x_max'],  'e'false$plotter_standards{'x_max'}[1], $constants);
   
$x_grid check_error($_REQUEST['x_grid'], 'e'false$plotter_standards{'x_grid'}[1], $constants);

   
$y_min  check_error($_REQUEST['y_min'],  'e'false$plotter_standards{'y_min'}[1], $constants);
   
$y_max  check_error($_REQUEST['y_max'],  'e'false$plotter_standards{'y_max'}[1], $constants);
   
$y_grid check_error($_REQUEST['y_grid'], 'e'false$plotter_standards{'y_grid'}[1], $constants);

   
$width  check_error($_REQUEST['width'],  'n'false$plotter_standards{'img_width'}[1]);
   
$height check_error($_REQUEST['height'], 'n'false$plotter_standards{'img_height'}[1]);

   
$step   check_error($_REQUEST['step'], 'e'false$plotter_standards{'step'}[1], $constants);
   
$auto_step check_error($_REQUEST['auto_step'], 'b'false,
                            
$plotter_standards{'auto_step'}[1]);

   
$bg_color check_error($_REQUEST['bg_col'], 'c'false$plotter_standards{'BG_color'}[1]);
   
$pl_color check_error($_REQUEST['pl_col'], 'c'false$plotter_standards{'PL_color'}[1]);
   
$ax_color check_error($_REQUEST['ax_col'], 'c'false$plotter_standards{'AX_color'}[1]);
   
$gr_color check_error($_REQUEST['gr_col'], 'c'false$plotter_standards{'GR_color'}[1]);

   
$s_min  check_error($_REQUEST['s_min'], 'e'false$plotter_standards{'shading_min'}[1], $constants);
   
$s_max  check_error($_REQUEST['s_max'], 'e'false$plotter_standards{'shading_max'}[1], $constants);
   
$sh_color check_error($_REQUEST['sh_col'], 'c'false$plotter_standards{'SH_color'}[1]);
   
$s_trans  check_error($_REQUEST['s_trans'], 'p'false$plotter_standards{'shading_trans'}[1]);
   
$s_f1   check_error($_REQUEST['s_f1'], 't'false$plotter_standards{'shading_f1'}[1], $constants);
   
$s_f2   check_error($_REQUEST['s_f2'], 't'false$plotter_standards{'shading_f2'}[1], $constants);
   
$sf_color check_error($_REQUEST['sf_col'], 'c'false$plotter_standards{'SF_color'}[1]);
   
$do_shade check_error($_REQUEST['do_shade'], 'b'false$plotter_standards{'auto_step'}[1]);

   
# Umschichtung der Min-/Max-Werte

   
if ($x_min $x_max) {
      
$temp  $x_min;
      
$x_min $x_max;
      
$x_max $temp;
   }

   if (
$x_grid 0) {
      
$x_grid = -$x_grid;
   }

   if (
$x_max == $x_min) {
      ++
$x_max;
   }

   if (
$y_min $y_max) {
      
$temp  $y_min;
      
$y_min $y_max;
      
$y_max $temp;
   }

   if (
$y_max == $y_min) {
      ++
$y_max;
   }

   if (
$y_grid 0) {
      
$y_grid = -$y_grid;
   }

   if (
$step 0) {
      
$step = -$step;
   }

   if (
$s_min $s_max) {
      
$temp  $s_min;
      
$s_min $s_max;
      
$s_max $temp;
   }

   if (
$x_max == $x_min) {
      ++
$x_max;
   }

   
# Berechnen der Aufl"osung

   
$res_x $width  / ($x_max $x_min);
   
$res_y $height / ($y_max $y_min);

   
# Jetzt geht's los

   
$plot = @ImageCreate($width$height) or die; # erstellt ein Image-Objekt

   # Farbdefinitionen

   
$color_res = array();
   foreach (
$global_colors as $num => $content) {
      
$color_res[$num] = ImageColorAllocate($plot$content[1], $content[2], $content[3]);
   }

   
# Plot vorbereiten
   
$plot init_plot(
      
$plot,
      
$width,
      
$height,
      
$x_min,
      
$x_max,
      
$x_grid,
      
$y_min,
      
$y_max,
      
$y_grid,
      
$color_res[$bg_color],
      
$color_res[$ax_color],
      
$color_res[$gr_color]
   );

   
# Jetzt k"ummern wir uns um den schattierten Bereich

   
if ($do_shade == 'true') {

      
# Funktion 1 in Stack umwandeln

      
if (check_parens($s_f1$global_parens) > -1) {
         
$do_shade 'false';
      }
      
$s_f1 check_minus($s_f1$global_parens);
      if (
$s_f1[1] != $global_error_names['NOERROR']) {
         
$do_shade 'false';
      }
      
$s_f1 $s_f1[0];
      
$s_f1 add_times($s_f1$poss_for_mult'*');
      if (
$s_f1[1] != $global_error_names['NOERROR']) {
         
$do_shade 'false';
      }
      
$s_f1 $s_f1[0];
      
$s_f1 tokenize($s_f1$global_parens$global_unary_operators,
                       
$global_binary_operators);
      if (
$s_f1[1] != $global_error_names['NOERROR']) {
         
$do_shade 'false';
      }
      
$s_f1 $s_f1[0];
      
$s_f1 substitute($s_f1$constants);
      if (
$s_f1[1] != $global_error_names['NOERROR']) {
         
$do_shade 'false';
      }
      
$s_f1 $s_f1[0];
      
$s_f1 build_tree($s_f1$global_parens$global_unary_operators$global_binary_operators);
      if (
$s_f1[1] != $global_error_names['NOERROR']) {
         
$do_shade 'false';
      }
      
$s_f1 $s_f1[0][0];
      
$s_f1 build_stack($s_f1);
      if (
$s_f1[1] != $global_error_names['NOERROR']) {
         
$do_shade 'false';
      }
      
$s_f1 $s_f1[0];

      
# Funktion 2 in Stack umwandeln

      
if (check_parens($s_f2$global_parens) > -1) {
         
$do_shade 'false';
      }
      
$s_f2 check_minus($s_f2$global_parens);
      if (
$s_f2[1] != $global_error_names['NOERROR']) {
         
$do_shade 'false';
      }
      
$s_f2 $s_f2[0];
      
$s_f2 add_times($s_f2$poss_for_mult'*');
      if (
$s_f2[1] != $global_error_names['NOERROR']) {
         
$do_shade 'false';
      }
      
$s_f2 $s_f2[0];
      
$s_f2 tokenize($s_f2$global_parens$global_unary_operators,
                       
$global_binary_operators);
      if (
$s_f2[1] != $global_error_names['NOERROR']) {
         
$do_shade 'false';
      }
      
$s_f2 $s_f2[0];
      
$s_f2 substitute($s_f2$constants);
      if (
$s_f2[1] != $global_error_names['NOERROR']) {
         
$do_shade 'false';
      }
      
$s_f2 $s_f2[0];
      
$s_f2 build_tree($s_f2$global_parens$global_unary_operators$global_binary_operators);
      if (
$s_f2[1] != $global_error_names['NOERROR']) {
         
$do_shade 'false';
      }
      
$s_f2 $s_f2[0][0];
      
$s_f2 build_stack($s_f2);
      if (
$s_f2[1] != $global_error_names['NOERROR']) {
         
$do_shade 'false';
      }
      
$s_f2 $s_f2[0];
   }
   
   
# Wenn die Funktionen korrekt geparst wurden, fahren wir fort

   
if ($do_shade == 'true') {

      
# Zuerst generieren wir die Punkte

      
if ($auto_step == 'true') {
         
$points_sh_1 auto_step(
                           
$s_f1,
                           
$s_min,
                           
$s_max,
                           
$y_min,
                           
$y_max,
                           
$res_x,
                           
$res_y,
                           
$constants
                        
);
         if (
count($points_sh_1) <= 1) {
            
$do_shade 'false';
         }
         
$points_sh_2 auto_step(
                           
$s_f2,
                           
$s_min,
                           
$s_max,
                           
$y_min,
                           
$y_max,
                           
$res_x,
                           
$res_y,
                           
$constants
                        
);
         if (
count($points_sh_2) <= 1) {
            
$do_shade 'false';
         }
         
         
# Hier m"ussen wir aufpassen, dass wir f"ur jeden x-Wert beide y-Werte haben

         
$all_sh_x get_joined_indices($points_sh_1$points_sh_2);
         
$points_sh_1 array_merge(
                           
$points_sh_1,
                           
generate_points(
                              
$s_f1,
                              
get_missing_indices($all_sh_x$points_sh_1),
                              array()
                           )
                        );
         
$points_sh_2 array_merge(
                           
$points_sh_2,
                           
generate_points(
                              
$s_f2,
                              
get_missing_indices($all_sh_x$points_sh_2),
                              array()
                           )
                        );
      } else {
         
$points_sh_1 fixed_step(
                           
$s_f1,
                           
$s_min,
                           
$s_max,
                           
$step,
                           
$constants
                        
);
         if (
count($points_sh_1) <= 1) {
            
$do_shade 'false';
         }
         
$points_sh_2 fixed_step(
                           
$s_f2,
                           
$s_min,
                           
$s_max,
                           
$step,
                           
$constants
                        
);
         if (
count($points_sh_2) <= 1) {
            
$do_shade 'false';
         }
      }

      
# Wenn bis jetzt noch alles in Ordnung ist, k"onnen wir zeichnen

      
if ($do_shade == 'true') {
         
$tempimg = @ImageCreate($width$height)
            or die;
         
$tempimg init_plot(
            
$tempimg,
            
$width,
            
$height,
            
$x_min,
            
$x_max,
            
$x_grid,
            
$y_min,
            
$y_max,
            
$y_grid,
            
ImageColorAllocate(
               
$tempimg,
               
$global_colors[$bg_color][1],
               
$global_colors[$bg_color][2],
               
$global_colors[$bg_color][3]
            ),
            
ImageColorAllocate(
               
$tempimg,
               
$global_colors[$ax_color][1],
               
$global_colors[$ax_color][2],
               
$global_colors[$ax_color][3]
            ),
            
ImageColorAllocate(
               
$tempimg,
               
$global_colors[$gr_color][1],
               
$global_colors[$gr_color][2],
               
$global_colors[$gr_color][3]
            )
         );

         
# Alle Punkte in die richtige Reihenfolge bringen

         
ksort($points_sh_1);
         
reset($points_sh_1);
         
ksort($points_sh_2);
         
reset($points_sh_2);

         
$sh_color_res $global_colors{$sh_color};
         
$sh_color_res ImageColorAllocate($tempimg$sh_color_res[1], $sh_color_res[2], $sh_color_res[3]);
         
$sf_color_res $global_colors{$sf_color};
         
$sf_color_res ImageColorAllocate($tempimg$sf_color_res[1], $sf_color_res[2], $sf_color_res[3]);

         
$undef true;
         
# Punkte: 0, 1 - alte 1; 2, 3 - neue 1; 4, 5 - neue 2; 6, 7 - alte 2
         
$points = array(00000000); # Ecken des zu zeichnenden Vierecks

         
foreach ($points_sh_1 as $x => $y1) {
            
$y2 $points_sh_2{$x};
            if (
$y1[1] == $global_error_names['NOERROR'] and $y2[1] == $global_error_names['NOERROR']) {
               if (
$undef) {
                  
$undef false;
                  
$points[2] = ($x $x_min)     * ($width 1)  / ($x_max $x_min);
                  
$points[3] = ($y_max $y1[0]) * ($height 1) / ($y_max $y_min);
                  
$points[4] = ($x $x_min)     * ($width 1)  / ($x_max $x_min);
                  
$points[5] = ($y_max $y2[0]) * ($height 1) / ($y_max $y_min);
               } else {
                  
# Die alten Punkte werden zu den linken Ecken ...
                  
$points[0] = $points[2];
                  
$points[1] = $points[3];
                  
$points[6] = $points[4];
                  
$points[7] = $points[5];
                  
# ... und die neuen zu den rechten
                  
$points[2] = ($x $x_min)     * ($width 1)  / ($x_max $x_min);
                  
$points[3] = ($y_max $y1[0]) * ($height 1) / ($y_max $y_min);
                  
$points[4] = ($x $x_min)     * ($width 1)  / ($x_max $x_min);
                  
$points[5] = ($y_max $y2[0]) * ($height 1) / ($y_max $y_min);
                  
ImageFilledPolygon(
                     
$tempimg,
                     
$points,
                     
4,
                     
$sh_color_res
                  
);
               }
            } else {
               
$undef true;
            }
         }
         
         
# Jetzt m"ussen wir noch die Randfunktionen zeichnen

         
$tempimg plot_graph(
                       
$tempimg,
                       
$width,
                       
$height,
                       
$x_min,
                       
$x_max,
                       
$y_min,
                       
$y_max,
                       
$points_sh_1,
                       
$sf_color_res
                    
);

         
$tempimg plot_graph(
                       
$tempimg,
                       
$width,
                       
$height,
                       
$x_min,
                       
$x_max,
                       
$y_min,
                       
$y_max,
                       
$points_sh_2,
                       
$sf_color_res
                    
);
                    
         
# Und f"ugen das neue Bild in das alte ein, so dass sich die gew"unschte
         # Transparenz ergibt -- nur m"oglich bevor irgend etwas anderes
         # gezeichnet ist

         
ImageCopyMerge($plot$tempimg0000$width$height$s_trans);

         
ImageDestroy($tempimg);
      }
   }

   
# Danach die Asymptoten

   
foreach ($asymptotes as $values) {

      
$x1 $values['p1_x'];
      
$y1 $values['p1_y'];
      
$x2 $values['p2_x'];
      
$y2 $values['p2_y'];

      
$dx $x2 $x1;
      
$dy $y2 $y1;

      
# Wenn die beiden Punkte indentisch sind, ist nichts zu machen

      
if ($dx == and $dy == 0) {
         continue;
      }

      
# Wir dehnen dir Strecke bis zu den R"andern des Bildbereiches aus ...

      
if ($dx != 0) {
         
$tx $x1;
         
$ty $y1;
         
$x1 $x_min;
         
$y1 $ty $dy * ($x1 $tx) / $dx;
         
$x2 $x_max;
         
$y2 $ty $dy * ($x2 $tx) / $dx;
      } else {
         
$y1 $y_min;
         
$y2 $y_max;
      }

      
# ... und zeichen die Asymptote

      
if ($values['dashed'] == 'true') {
         
ImageDashedLine(
            
$plot,
            (
$x1 $x_min) * ($width 1)  / ($x_max $x_min),
            (
$y_max $y1) * ($height 1) / ($y_max $y_min),
            (
$x2 $x_min) * ($width 1)  / ($x_max $x_min),
            (
$y_max $y2) * ($height 1) / ($y_max $y_min),
            
$color_res[$values['color']]
         );
      } else {
         
ImageLine(
            
$plot,
            (
$x1 $x_min) * ($width 1)  / ($x_max $x_min),
            (
$y_max $y1) * ($height 1) / ($y_max $y_min),
            (
$x2 $x_min) * ($width 1)  / ($x_max $x_min),
            (
$y_max $y2) * ($height 1) / ($y_max $y_min),
            
$color_res[$values['color']]
         );
      }
   }

   
# Und zu guter Letzt die Funktionen

   
foreach ($functions as $key => $values) {
      if (
in_array($values['param']['name'], $values['stack'])) {
         for (
$param $values['param']['from']; $param <= $values['param']['to']; $param += $values['param']['step']) {
            if (
$auto_step == 'true') {
               
$points auto_step(
                            
$values['stack'],
                            
$x_min,
                            
$x_max,
                            
$y_min,
                            
$y_max,
                            
$res_x,
                            
$res_y,
                            
array_merge(
                               
$constants,
                               array(
$values['param']['name'] => $param)
                            )
                         );
               if (
count($points) <= 1) {
                  continue;
               }
            } else {
               
$points fixed_step(
                            
$values['stack'],
                            
$x_min,
                            
$x_max,
                            
$step,
                            
array_merge(
                               
$constants,
                               array(
$values['param']['name'] => $param)
                            )
                         );
               if (
count($points) <= 1) {
                  continue;
               }
            }
            
$plot plot_graph(
                       
$plot,
                       
$width,
                       
$height,
                       
$x_min,
                       
$x_max,
                       
$y_min,
                       
$y_max,
                       
$points,
                       
$color_res[$values['color']]
                    );
         }
      } else {
         if (
$auto_step == 'true') {
            
$points auto_step(
                         
$values['stack'],
                         
$x_min,
                         
$x_max,
                         
$y_min,
                         
$y_max,
                         
$res_x,
                         
$res_y,
                         
$constants
                      
);
            if (
count($points) <= 1) {
               continue;
            }
         } else {
            
$points fixed_step(
                         
$values['stack'],
                         
$x_min,
                         
$x_max,
                         
$step,
                         
$constants
                      
);
            if (
count($points) <= 1) {
               continue;
            }
         }
         
$plot plot_graph(
                    
$plot,
                    
$width,
                    
$height,
                    
$x_min,
                    
$x_max,
                    
$y_min,
                    
$y_max,
                    
$points,
                    
$color_res[$values['color']]
                 );
      }
   }

   
# Wir geben das Bild aus

   
header($plotter_standards{'img_types'}[1][$image_type][2]);

   switch (
$plotter_standards{'img_types'}[1][$image_type][1]) {
      case (
IMG_GIF):
         print 
imagegif($plot);
         break;
      case (
IMG_JPG):
         print 
imagejpg($plot);
         break;
      case (
IMG_PNG):
         print 
imagepng($plot);
         break;
      case (
IMG_WBMP):
         print 
imagewbmp($plot);
         break;
      default:
         die;
   }

   
ImageDestroy($plot); # ... und um nett zu sein, den Speicher freigeben

?>

Datei plotter.php:

<html>
<head>
<title>Funktionsplotter</title>
<link rel="stylesheet" type="text/css" href="units/style.css">
</head>
<body>
<?php

   
####################################################################################
   # Dies ist die Datei 'plotter.php'                                                 #
   #                                                                                  #
   # Sie enth"alt das Plotterformular des Parser/Plotter-Projekts                     #
   #                                                                                  #
   # Diese Datei darf frei als Ganzes oder in Teilen f"ur jegliche nicht-             #
   # kommerzielle Zwecke verwandt werden, solange folgede Bedingungen erf"ullt        #
   # werden:                                                                          #
   #    - Dieser Blockkommentar mit den Nutzungsbedingungen muss unver"andert         #
   #      in allen Nachfolgedateien / -ver"offentlichungen am Datei- / Textkopf       #
   #      verwandt werden                                                             #
   #    - Der Quellcode des muss jedem Benutzer von allen Programmen, die ihn         #
   #      verwenden, einsehbar gemacht werden                                         #
   #                                                                                  #
   # Sollten Sie diesen Code, in Teilen oder als Ganzes, auch portiert in             #
   # andere Programmiersprachen oder unter blo"ser Verwendung des Algorithmus         #
   # oder von Teilen von verwandten Algorithmen, f"ur kommerzielle Zwecke nutzen      #
   # wollen, so kontaktieren Sie mich bitte.                                          #
   #                                                                                  #
   # Ich habe den vorliegenden Code von Grund auf selbst programmiert und mich        #
   # dabei auf keine anderen als Standardalgorithmen gest"utzt. Insbesondere den      #
   # Tokenizer, der Parser und die Schrittweitensteurerung habe ich von Grund         #
   # auf und ohne Zuhilfenahme anderer Quellen selbst programmiert. Sollte ich        #
   # mit dem vorliegenden Code bestehende Copyrights oder Patente verletzen oder      #
   # den Urheber geistigen Eigentums vorenthalten, so geschieht dies                  #
   # unabsichtlich. Bitte kontaktieren Sie mich mittels untenstehender E-Mail-        #
   # Adresse oder "uber den Sysadmin.                                                 #
   #                                                                                  #
   # Der Autor "ubernimmt keine Haftung f"ur eventuelle durch die Nutzung dieses      #
   # entstehende oder entstandene mittelbare oder unmittelbare Sch"aden jedweder Art. #
   # Nutzung auf eigene Gefahr.                                                       #
   #                                                                                  #
   # Bitte schicken Sie mir keine E-Mails mit Bitte um die Erkl"arung der             #
   # Funktionsweise des Codes oder von Teilen des Codes; ich habe mich bem"uht,       #
   # den Code so gut wie m"oglich zu kommentieren und habe leider nicht genug         #
   # Zeit, um E-Mails "uber technische Details zu beantworten.                        #
   #                                                                                  #
   # (c) Jan Olligs, 2004                                                             #
   # Alle Rechte vorbehalten                                                          #
   #                                                                                  #
   # Jan.Olligs@gmx.net                                                               #
   ####################################################################################

   
include('units/mathdef.php');
   include(
'units/parser.php');
   include(
'units/plotter_constants.php');
   include(
'units/various.php');


   
####################################################################################
   # $_REQUEST['tab'] bestimmt die angeseigte Seite:                                  #
   #    'general'   - Generelle Einstellungen / Konstanten                            #
   #    'functions' - Funktionen / Asymptoten (Eingabe)                               #
   #    'error'     - Fehlerausgabe                                                   #
   #    'graph'     - Plot                                                            #
   #                                                                                  #
   # Parameter, die auf den Seiten eingestellt werden:                                #
   #    'general':                                                                    #
   #       'img_type', 'width', 'height'                                              #
   #       'x_min', 'x_max', 'x_grid', 'y_min', 'y_max', 'y_grid'                     #
   #       'step', 'auto_step'                                                        #
   #       'bg_col', 'ax_col', 'gr_col', 'pl_col'                                     #
   #       'const'                                                                    #
   #    'functions':                                                                  #
   #       's_min', 's_max', 'sh_col', 's_trans', 's_f1', 's_f2', 'sf_col', 'do_shade'#
   #       'function_[\d]_[...]', 'num_new_func'                                      #
   #       'asymptote_[\d]_[...]', 'num_new_asym'                                     #
   #    'error', 'graph':                                                             #
   #       Nur Ausgabe                                                                #
   ####################################################################################

   
$tab $_REQUEST['tab'];
   switch (
strtolower($tab)) {
      case (
'general'):
      case (
'functions'):
      case (
'error'):
      case (
'graph'):
         
$tab strtolower($tab);
         break;
      default:
         
$tab 'general';
         break;
   }

   
# Wenn Werte noch nicht existieren, dann schaffen wir sie jetzt

   
$_REQUEST populate_request(
      
$_REQUEST,
      array(
         
'width'      => 'img_width',
         
'height'     => 'img_height',
         
'x_min'      => 'x_min',
         
'x_max'      => 'x_max',
         
'x_grid'     => 'x_grid',
         
'y_min'      => 'y_min',
         
'y_max'      => 'y_max',
         
'y_grid'     => 'y_grid',
         
'step'       => 'step',
         
'auto_step'  => 'auto_step',
         
'bg_col'     => 'BG_color',
         
'ax_col'     => 'AX_color',
         
'gr_col'     => 'GR_color',
         
'pl_col'     => 'PL_color',
         
's_min'      => 'shading_min',
         
's_max'      => 'shading_max',
         
'sh_col'     => 'SH_color',
         
's_trans'    => 'shading_trans',
         
's_f1'       => 'shading_f1',
         
's_f2'       => 'shading_f2',
         
'sf_col'     => 'SF_color',
         
'do_shade'   => 'do_shade'
      
),
      
$plotter_standards
   
);

   if (
is_null($_REQUEST['img_type']) or $_REQUEST['img_type'] == '') {
      
$_REQUEST['img_type'] = 0;
   }


   
# Jetzt m"ussen wir uns um gel"oschte und neu generierte Funktionen und
   # Asymptoten k"ummern

   
$oldfunc unpack_function_terms($_REQUEST);
   
$num_new $_REQUEST['num_new_func'];
   if (
is_null($num_new) or $num_new == '' or !is_numeric($num_new) or !is_int($num_new 0) or $num_new 0) {
      
$num_new 0;
      
$_REQUEST['num_new_func'] = $num_new;
   }
   if (
count($oldfunc) == 0) {
      
array_push(
         
$oldfunc,
         array(
            
'term'  => $plotter_standards{'func'}[1],
            
'color' => $plotter_standards{'PL_color'}[1],
            
'param' => array(
               
'name' => 'NOPARAM',
               
'from' => 0,
               
'to'   => 0,
               
'step' => 1
            
)
         )
      );
   }
   
$functions = array();
   
ksort($oldfunc);
   foreach (
$oldfunc as $values) {
      if (
$values{'delete'} != 'true') {
         
array_push($functions$values);
      }
   }
   for (
$i 0$i $num_new; ++$i) {
      
array_push(
         
$functions,
         array(
            
'term'   => $plotter_standards{'func'}[1],
            
'color'  => $plotter_standards{'PL_color'}[1],
            
'delete' => '',
            
'param'  => array(
               
'name' => 'NOPARAM',
               
'from' => 0,
               
'to'   => 0,
               
'step' => 1
            
)
         )
      );
   }
   foreach (
array_keys($_REQUEST) as $key) {
      if (
preg_match('/^function_/i'$key)) {
         unset(
$_REQUEST[$key]);
      }
   }
   
$_REQUEST array_merge($_REQUESTpack_function_terms($functions));
   unset(
$oldfunc);

   
$oldasym unpack_asymptote_terms($_REQUEST);
   
$num_new $_REQUEST['num_new_asym'];
   if (
is_null($num_new) or $num_new == '' or !is_numeric($num_new) or !is_int($num_new 0) or $num_new 0) {
      
$num_new 0;
      
$_REQUEST['num_new_asym'] = $num_new;
   }
   
$asymptotes = array();
   
ksort($oldasym);
   foreach (
$oldasym as $values) {
      if (
$values{'delete'} != 'true') {
         
array_push($asymptotes$values);
      }
   }
   for (
$i 0$i $num_new; ++$i) {
      
array_push(
         
$asymptotes,
         array(
            
'p1_x'   => $plotter_standards{'asym_px1'}[1],
            
'p1_y'   => $plotter_standards{'asym_py1'}[1],
            
'p2_x'   => $plotter_standards{'asym_px2'}[1],
            
'p2_y'   => $plotter_standards{'asym_py2'}[1],
            
'color'  => $plotter_standards{'AS_color'}[1],
            
'dashed' => $plotter_standards{'asym_dashed'}[1],
            
'delete' => ''
         
)
      );
   }
   foreach (
array_keys($_REQUEST) as $key) {
      if (
preg_match('/^asymptote_/i'$key)) {
         unset(
$_REQUEST[$key]);
      }
   }
   
$_REQUEST array_merge($_REQUESTpack_asymptote_terms($asymptotes));
   unset(
$oldasym);

?>
   <table border="0" width="100%">
      <tr>
         <td align="center" class="version1" size="20%">
            <a href="index.htm">Startseite</a>
         </td>

         <td align="center" class="<?php print ($tab == 'general' 'current' 'version2'?>" size="20%">
            <a href="plotter.php?<?php
               
print http_build_query(
                  
array_merge(
                     
$_REQUEST,
                     array(
                        
'tab'          => 'general',
                        
'num_new_func' => 0,
                        
'num_new_asym' => 0
                     
)
                  )
               );
            
?>">Einstellungen</a>
         </td>
         <td align="center" class="<?php print ($tab == 'functions' 'current' 'version1'?>" size="20%">
            <a href="plotter.php?<?php
               
print http_build_query(
                  
array_merge(
                     
$_REQUEST,
                     array(
                        
'tab'          => 'functions',
                        
'num_new_func' => 0,
                        
'num_new_asym' => 0
                     
)
                  )
               );
            
?>">Funktionen</a>
         </td>
         <td align="center" class="<?php print ($tab == 'error' 'current' 'version2'?>" size="20%">
            <a href="plotter.php?<?php
               
print http_build_query(
                  
array_merge(
                     
$_REQUEST,
                     array(
                        
'tab'          => 'error',
                        
'num_new_func' => 0,
                        
'num_new_asym' => 0
                     
)
                  )
               );
            
?>">Fehlermeldungen</a>
         </td>
         <td align="center" class="<?php print ($tab == 'graph' 'current' 'version1'?>" size="20%">
            <a href="plotter.php?<?php
               
print http_build_query(
                  
array_merge(
                     
$_REQUEST,
                     array(
                        
'tab'          => 'graph',
                        
'num_new_func' => 0,
                        
'num_new_asym' => 0
                     
)
                  )
               );
            
?>">Funktionsgraph</a>
         </td>
      </tr>
      <tr>
         <td class="body" colspan="5">
            <form action="plotter.php" method="post">
<?php
   
# Hier binden wir die Tabs ein
   
switch ($tab) {
      case (
'general'):
         include(
'tabs/general.php');
         break;
      case (
'functions'):
         include(
'tabs/functions.php');
         break;
      case (
'error'):
         include(
'tabs/error.php');
         break;
      case (
'graph'):
         include(
'tabs/graph.php');
         break;
      default:
         print 
"Autsch, das tut weh. Wahrscheinlich ein Programmierfehler.\n";
         break;
   }
?>
            </form>
         </td>
      </tr>
   </table>

   <p><a href="index.htm">&copy; Jan Olligs, 2004</a></p>
</body>
</html>

Datei tabs/error.php:

<?php

   
####################################################################################
   # Dies ist die Datei 'error.php'                                                   #
   #                                                                                  #
   # Sie enth"alt ein Tab des Plotterformulars des Parser/Plotter-Projekts;           #
   # es dient zur Fehlerausgabe                                                       #
   #                                                                                  #
   # Diese Datei darf frei als Ganzes oder in Teilen f"ur jegliche nicht-             #
   # kommerzielle Zwecke verwandt werden, solange folgede Bedingungen erf"ullt        #
   # werden:                                                                          #
   #    - Dieser Blockkommentar mit den Nutzungsbedingungen muss unver"andert         #
   #      in allen Nachfolgedateien / -ver"offentlichungen am Datei- / Textkopf       #
   #      verwandt werden                                                             #
   #    - Der Quellcode des muss jedem Benutzer von allen Programmen, die ihn         #
   #      verwenden, einsehbar gemacht werden                                         #
   #                                                                                  #
   # Sollten Sie diesen Code, in Teilen oder als Ganzes, auch portiert in             #
   # andere Programmiersprachen oder unter blo"ser Verwendung des Algorithmus         #
   # oder von Teilen von verwandten Algorithmen, f"ur kommerzielle Zwecke nutzen      #
   # wollen, so kontaktieren Sie mich bitte.                                          #
   #                                                                                  #
   # Ich habe den vorliegenden Code von Grund auf selbst programmiert und mich        #
   # dabei auf keine anderen als Standardalgorithmen gest"utzt. Insbesondere den      #
   # Tokenizer, der Parser und die Schrittweitensteurerung habe ich von Grund         #
   # auf und ohne Zuhilfenahme anderer Quellen selbst programmiert. Sollte ich        #
   # mit dem vorliegenden Code bestehende Copyrights oder Patente verletzen oder      #
   # den Urheber geistigen Eigentums vorenthalten, so geschieht dies                  #
   # unabsichtlich. Bitte kontaktieren Sie mich mittels untenstehender E-Mail-        #
   # Adresse oder "uber den Sysadmin.                                                 #
   #                                                                                  #
   # Der Autor "ubernimmt keine Haftung f"ur eventuelle durch die Nutzung dieses      #
   # entstehende oder entstandene mittelbare oder unmittelbare Sch"aden jedweder Art. #
   # Nutzung auf eigene Gefahr.                                                       #
   #                                                                                  #
   # Bitte schicken Sie mir keine E-Mails mit Bitte um die Erkl"arung der             #
   # Funktionsweise des Codes oder von Teilen des Codes; ich habe mich bem"uht,       #
   # den Code so gut wie m"oglich zu kommentieren und habe leider nicht genug         #
   # Zeit, um E-Mails "uber technische Details zu beantworten.                        #
   #                                                                                  #
   # (c) Jan Olligs, 2004                                                             #
   # Alle Rechte vorbehalten                                                          #
   #                                                                                  #
   # Jan.Olligs@gmx.net                                                               #
   ####################################################################################

?>

<h2>Fehler im Tab &quot;Einstellungen&quot;</h2>

<?php
   $noerr 
true;

   
# Bildeinstellungen "uberpr"ufen

   
$error check_error($_REQUEST['width'], 'n');
   if (
$error != '') {
      
$noerr false;
      print 
"<p><b>Bild:</b> Fehler mit der Bildbreite: $error</p>\n";
   }

   
$error check_error($_REQUEST['height'], 'n');
   if (
$error != '') {
      
$noerr false;
      print 
"<p><b>Bild:</b> Fehler mit der Bildh&ouml;he: $error</p>\n";
   }

   
# Konstanten parsen und "uberpr"ufen

   
$constants = array();
   
$temp preg_split('/\n/'$_REQUEST['const']);
   foreach (
$temp as $eqn) {
      
$t preg_split('/=/'$eqn);
      if (!
is_array($t) or count ($t) != 2) {
         continue;
      }
      
$t[0] = ltrim(rtrim($t[0]));
      
$t[1] = ltrim(rtrim($t[1]));

      
$error check_error($t[1], 'e'true0$global_constants);
      if (
$error != '') {
         
$noerr false;
         print 
"<p><b>Konstanten:</b> Fehler mit der Definition &quot;$eqn&quot;: $error</p>\n";
      } else {
         
$constants[$t[0]] = check_error($t[1], 'e'false0$global_constants);
      }
   }
   
$constants array_merge($constants$global_constants);

   
# Bildbereich parsen und "uberpr"ufen

   
$value $_REQUEST['x_min'];
   
$error check_error($value'e'true0$constants);
   if (
$error != '') {
      
$noerr false;
      print 
"<p><b>Bildbereich:</b> Fehler mit der Definition des kleinsten x-Wertes: $error</p>\n";
   }

   
$value $_REQUEST['x_max'];
   
$error check_error($value'e'true0$constants);
   if (
$error != '') {
      
$noerr false;
      print 
"<p><b>Bildbereich:</b> Fehler mit der Definition des gr&ouml;&szlig;ten x-Wertes: $error</p>\n";
   }

   
$value $_REQUEST['x_grid'];
   
$error check_error($value'e'true0$constants);
   if (
$error != '') {
      
$noerr false;
      print 
"<p><b>Bildbereich:</b> Fehler mit der Definition der x-Gitterweite: $error</p>\n";
   }

   
$value $_REQUEST['y_min'];
   
$error check_error($value'e'true0$constants);
   if (
$error != '') {
      
$noerr false;
      print 
"<p><b>Bildbereich:</b> Fehler mit der Definition des kleinsten y-Wertes: $error</p>\n";
   }

   
$value $_REQUEST['y_max'];
   
$error check_error($value'e'true0$constants);
   if (
$error != '') {
      
$noerr false;
      print 
"<p><b>Bildbereich:</b> Fehler mit der Definition des gr&ouml;&szlig;ten y-Wertes: $error</p>\n";
   }

   
$value $_REQUEST['y_grid'];
   
$error check_error($value'e'true0$constants);
   if (
$error != '') {
      
$noerr false;
      print 
"<p><b>Bildbereich:</b> Fehler mit der Definition der y-Gitterweite: $error</p>\n";
   }

   
# Zeicheneinstellungen "uberpr"ufen

   
$value $_REQUEST['auto_step'];
   
$error check_error($value'b');
   if (
$error != '') {
      
$noerr false;
      print 
"<p><b>Zeicheneinstellungen:</b> Fehler mit dem An- / Abschalten der automatischen Schrittweitensteuerung: $error</p>\n";
   }

   
$value $_REQUEST['step'];
   
$error check_error($value'e'true0$constants);
   if (
$error != '') {
      
$noerr false;
      print 
"<p><b>Zeicheneinstellungen:</b> Fehler mit der Definition der Schrittweite: $error</p>\n";
   }

   if (
$noerr) {
      print 
"<p>Keine Fehler</p>\n";
   }

?>

<h2>Fehler im Tab &quot;Funktionen&quot;</h2>

<?php

   $noerr 
true;

   foreach (
$functions as $num => $values) {
      
$error check_error(
         
$values['term'], 
         
't'
         
true
         
0
         
array_merge(
            
$constants,
            array(
$values['param']['name'] => 0
               
# Auf den Wert brauchen wir nicht zu achten, da nur der Term "uberpr"uft wird
         
)
      );
      if (
$error != '') {
         
$noerr false;
         print 
"<p><b>Funktion " . ($num 1) . ":</b> Fehler mit der Definition des Funktionsterms: $error</p>\n";
      }

      
$error check_error($values['param']['from'], 'e'true0$constants);
      if (
$error != '') {
         
$noerr false;
         print 
"<p><b>Funktion " . ($num 1) . ":</b> Fehler mit der Definition des Paramteranfangs: $error</p>\n";
      }

      
$error check_error($values['param']['to'], 'e'true0$constants);
      if (
$error != '') {
         
$noerr false;
         print 
"<p><b>Funktion " . ($num 1) . ":</b> Fehler mit der Definition des Paramterendes: $error</p>\n";
      }

      
$error check_error($values['param']['step'], 'e'true0$constants);
      if (
$error != '') {
         
$noerr false;
         print 
"<p><b>Funktion " . ($num 1) . ":</b> Fehler mit der Definition der Paramterschrittweite: $error</p>\n";
      }
   }

   foreach (
$asymptotes as $num => $values) {
      
$error check_error($values['p1_x'], 'e'true0$constants);
      if (
$error != '') {
         
$noerr false;
         print 
"<p><b>Asymptote " . ($num 1) . ":</b> Fehler mit der Definition des x-Wertes von Punkt 1: $error</p>\n";
      }

      
$error check_error($values['p1_y'], 'e'true0$constants);
      if (
$error != '') {
         
$noerr false;
         print 
"<p><b>Asymptote " . ($num 1) . ":</b> Fehler mit der Definition des y-Wertes von Punkt 1: $error</p>\n";
      }

      
$error check_error($values['p2_x'], 'e'true0$constants);
      if (
$error != '') {
         
$noerr false;
         print 
"<p><b>Asymptote " . ($num 1) . ":</b> Fehler mit der Definition des x-Wertes von Punkt 2: $error</p>\n";
      }

      
$error check_error($values['p2_y'], 'e'true0$constants);
      if (
$error != '') {
         
$noerr false;
         print 
"<p><b>Asymptote " . ($num 1) . ":</b> Fehler mit der Definition des y-Wertes von Punkt 2: $error</p>\n";
      }

      
$error check_error($values['dashed'], 't');
      if (
$error != '') {
         
$noerr false;
         print 
"<p><b>Asymptote " . ($num 1) . ":</b> Fehler bei der Einstellung gestrichelt / nicht gestrichelt: $error</p>\n";
      }
   }

   
# s-Parameter

   
$error check_error($_REQUEST['s_min'], 'e'true0$constants);
   if (
$error != '') {
      
$noerr false;
      print 
"<p><b>Schattierter Bereich:</b> Fehler mit der Definition des kleinsten x-Wertes: $error</p>\n";
   }

   
$error check_error($_REQUEST['s_max'], 'e'true0$constants);
   if (
$error != '') {
      
$noerr false;
      print 
"<p><b>Schattierter Bereich:</b> Fehler mit der Definition des gr&ouml;&szlig;ten x-Wertes: $error</p>\n";
   }

   
$error check_error($_REQUEST['s_f1'], 't'true0$constants);
   if (
$error != '') {
      
$noerr false;
      print 
"<p><b>Schattierter Bereich:</b> Fehler mit der Definition von Grenzfunktion 1: $error</p>\n";
   }

   
$error check_error($_REQUEST['s_f2'], 't'true0$constants);
   if (
$error != '') {
      
$noerr false;
      print 
"<p><b>Schattierter Bereich:</b> Fehler mit der Definition von Grenzfunktion 2: $error</p>\n";
   }

   
$error check_error($_REQUEST['do_shade'], 'b');
   if (
$error != '') {
      
$noerr false;
      print 
"<p><b>Schattierter Bereich:</b> Fehler bei der Einstellung an / aus: $error</p>\n";
   }

   if (
$noerr) {
      print 
"<p>Keine Fehler</p>\n";
   }

?>

Datei tabs/functions.php:

<?php

   
####################################################################################
   # Dies ist die Datei 'functions.php'                                               #
   #                                                                                  #
   # Sie enth"alt ein Tab des Plotterformulars des Parser/Plotter-Projekts;           #
   # es enth"alt Einstellungen f"ur Funktionen und Aymptoten                          #
   #                                                                                  #
   # Diese Datei darf frei als Ganzes oder in Teilen f"ur jegliche nicht-             #
   # kommerzielle Zwecke verwandt werden, solange folgede Bedingungen erf"ullt        #
   # werden:                                                                          #
   #    - Dieser Blockkommentar mit den Nutzungsbedingungen muss unver"andert         #
   #      in allen Nachfolgedateien / -ver"offentlichungen am Datei- / Textkopf       #
   #      verwandt werden                                                             #
   #    - Der Quellcode des muss jedem Benutzer von allen Programmen, die ihn         #
   #      verwenden, einsehbar gemacht werden                                         #
   #                                                                                  #
   # Sollten Sie diesen Code, in Teilen oder als Ganzes, auch portiert in             #
   # andere Programmiersprachen oder unter blo"ser Verwendung des Algorithmus         #
   # oder von Teilen von verwandten Algorithmen, f"ur kommerzielle Zwecke nutzen      #
   # wollen, so kontaktieren Sie mich bitte.                                          #
   #                                                                                  #
   # Ich habe den vorliegenden Code von Grund auf selbst programmiert und mich        #
   # dabei auf keine anderen als Standardalgorithmen gest"utzt. Insbesondere den      #
   # Tokenizer, der Parser und die Schrittweitensteurerung habe ich von Grund         #
   # auf und ohne Zuhilfenahme anderer Quellen selbst programmiert. Sollte ich        #
   # mit dem vorliegenden Code bestehende Copyrights oder Patente verletzen oder      #
   # den Urheber geistigen Eigentums vorenthalten, so geschieht dies                  #
   # unabsichtlich. Bitte kontaktieren Sie mich mittels untenstehender E-Mail-        #
   # Adresse oder "uber den Sysadmin.                                                 #
   #                                                                                  #
   # Der Autor "ubernimmt keine Haftung f"ur eventuelle durch die Nutzung dieses      #
   # entstehende oder entstandene mittelbare oder unmittelbare Sch"aden jedweder Art. #
   # Nutzung auf eigene Gefahr.                                                       #
   #                                                                                  #
   # Bitte schicken Sie mir keine E-Mails mit Bitte um die Erkl"arung der             #
   # Funktionsweise des Codes oder von Teilen des Codes; ich habe mich bem"uht,       #
   # den Code so gut wie m"oglich zu kommentieren und habe leider nicht genug         #
   # Zeit, um E-Mails "uber technische Details zu beantworten.                        #
   #                                                                                  #
   # (c) Jan Olligs, 2004                                                             #
   # Alle Rechte vorbehalten                                                          #
   #                                                                                  #
   # Jan.Olligs@gmx.net                                                               #
   ####################################################################################

   ####################################################################################
   # Parameter, die auf dieser Seite eingestellt werden:                              #
   #   's_min', 's_max', 'sh_col', 's_trans', 's_f1', 's_f2', 'sf_col', 'do_shade'    #
   #    'function_[\d]_[...]', 'num_new_func'                                         #
   #    'asymptote_[\d]_[...]', 'num_new_asym'                                        #
   ####################################################################################

?>

<fieldset>
   <legend>Funktionen</legend>
<?php
   
foreach ($functions as $num => $values) {
      print 
'<fieldset>' "\n";
      print 
'   <legend>Funktion ' . ($num 1) . '</legend>' "\n";
      print 
'   <table border="0">' "\n";

      print 
'      <tr>' "\n";
      print 
'         <td align="left">Funktion:&nbsp;</td>' "\n";
      print 
'         <td align="right"><i>f(x)</i>&nbsp;=&nbsp;'
          
form_text($_REQUEST"function_${num}_term"30100) . '</td>' "\n";
      print 
'      </tr>' "\n";

      print 
'      <tr>' "\n";
      print 
'         <td align="left">Parametername:&nbsp;</td>' "\n";
      print 
'         <td align="right">'
          
form_text($_REQUEST"function_${num}_param_name"105) . '</td>' "\n";
      print 
'      </tr>' "\n";

      print 
'      <tr>' "\n";
      print 
'         <td align="left">Parameter von:&nbsp;</td>' "\n";
      print 
'         <td align="right">'
          
form_text($_REQUEST"function_${num}_param_from"1040) . '</td>' "\n";
      print 
'      </tr>' "\n";

      print 
'      <tr>' "\n";
      print 
'         <td align="left">Parameter bis:&nbsp;</td>' "\n";
      print 
'         <td align="right">'
          
form_text($_REQUEST"function_${num}_param_to"1040) . '</td>' "\n";
      print 
'      </tr>' "\n";

      print 
'      <tr>' "\n";
      print 
'         <td align="left">Parameter Schritte:&nbsp;</td>' "\n";
      print 
'         <td align="right">'
          
form_text($_REQUEST"function_${num}_param_step"1040) . '</td>' "\n";
      print 
'      </tr>' "\n";

      print 
'      <tr>' "\n";
      print 
'         <td align="left">Plotfarbe:&nbsp;</td>' "\n";
      print 
'         <td align="right">' "\n";
      print 
form_color_select($_REQUEST"function_${num}_color"$global_colors12);
      print 
'         </td>' "\n";
      print 
'      </tr>' "\n";

      print 
'      <tr>' "\n";
      print 
'         <td align="right">'
          
'<input type="checkbox" name="function_' $num '_delete" value="true">'
          
'</td>' "\n";
      print 
'         <td align="left">Funktion l&ouml;schen</td>' "\n";
      print 
'      </tr>' "\n";

      print 
'   </table>' "\n";
      print 
'</fieldset>' "\n";
   }
?>
   <p>Neue Funktionen: <input type="text" size="10" maxlength="5" name="num_new_func" value="0"></p>
</fieldset>

<fieldset>
   <legend>Asymptoten</legend>
<?php
   
foreach ($asymptotes as $num => $values) {
      print 
'<fieldset>' "\n";
      print 
'   <legend>Asymptote ' . ($num 1) . '</legend>' "\n";
      print 
'   <table border="0">' "\n";

      print 
'      <tr>' "\n";
      print 
'         <td align="left">x-Koordinate Punkt 1:&nbsp;</td>' "\n";
      print 
'         <td align="right">'
          
form_text($_REQUEST"asymptote_${num}_p1_x"1040) . '</td>' "\n";
      print 
'      </tr>' "\n";

      print 
'      <tr>' "\n";
      print 
'         <td align="left">y-Koordinate Punkt 1:&nbsp;</td>' "\n";
      print 
'         <td align="right">'
          
form_text($_REQUEST"asymptote_${num}_p1_y"1040) . '</td>' "\n";
      print 
'      </tr>' "\n";

      print 
'      <tr>' "\n";
      print 
'         <td align="left">x-Koordinate Punkt 2:&nbsp;</td>' "\n";
      print 
'         <td align="right">'
          
form_text($_REQUEST"asymptote_${num}_p2_x"1040) . '</td>' "\n";
      print 
'      </tr>' "\n";

      print 
'      <tr>' "\n";
      print 
'         <td align="left">y-Koordinate Punkt 2:&nbsp;</td>' "\n";
      print 
'         <td align="right">'
          
form_text($_REQUEST"asymptote_${num}_p2_y"1040) . '</td>' "\n";
      print 
'      </tr>' "\n";

      print 
'      <tr>' "\n";
      print 
'         <td align="left">Farbe:&nbsp;</td>' "\n";
      print 
'         <td align="right">' "\n";
      print 
form_color_select($_REQUEST"asymptote_${num}_color"$global_colors12);
      print 
'         </td>' "\n";
      print 
'      </tr>' "\n";

      print 
'      <tr>' "\n";
      print 
'         <td align="right">'
          
'<input type="checkbox" name="asymptote_' $num '_dashed"'
          
. ($_REQUEST["asymptote_${num}_dashed"] == 'true' ' checked' '')
          . 
' value="true"></td>' "\n";
      print 
'         <td align="left">Gestrichelt zeichnen</td>' "\n";
      print 
'      </tr>' "\n";

      print 
'      <tr>' "\n";
      print 
'         <td align="right">'
          
'<input type="checkbox" name="asymptote_' $num '_delete" value="true">'
          
'</td>' "\n";
      print 
'         <td align="left">Asymptote l&ouml;schen</td>' "\n";
      print 
'      </tr>' "\n";

      print 
'   </table>' "\n";
      print 
'</fieldset>' "\n";
   }
?>
   <p>Neue Asymptoten: <input type="text" size="10" maxlength="5" name="num_new_asym" value="0"></p>
</fieldset>

<fieldset>
   <legend>Schattieren</legend>
   <table border="0">
      <tr>
         <td align="left">Unterer x-Wert:&nbsp;</td>
         <td align="right"><?php print form_text($_REQUEST's_min'1040?></td>
      </tr>
      <tr>
         <td align="left">Oberer x-Wert:&nbsp;</td>
         <td align="right"><?php print form_text($_REQUEST's_max'1040?></td>
      </tr>
      <tr>
         <td align="left">Schattenfarbe:&nbsp;</td>
         <td align="right">
<?php print form_color_select($_REQUEST"sh_col"$global_colors12?>
         </td>
      </tr>
      <tr>
         <td align="left">Transparenz:&nbsp;</td>
         <td align="right"><?php print form_text($_REQUEST's_trans'1040?>&nbsp;%</td>
      </tr>
      <tr>
         <td align="left">Grenzfunktion 1:&nbsp;</td>
         <td align="right"><i>g<sub>1</sub>(x)</i>&nbsp;=&nbsp;<?php print form_text($_REQUEST's_f1'30100?></td>
      </tr>
      <tr>
         <td align="left">Grenzfunktion 2:&nbsp;</td>
         <td align="right"><i>g<sub>2</sub>(x)</i>&nbsp;=&nbsp;<?php print form_text($_REQUEST's_f2'30100?></td>
      </tr>
      <tr>
         <td align="left">Begrenzungsfarbe:&nbsp;</td>
         <td align="right">
<?php print form_color_select($_REQUEST"sf_col"$global_colors12?>
         </td>
      </tr>
      <tr>
         <td align="left"><input type="checkbox" name="do_shade"<?php print ($_REQUEST["do_shade"] == 'true' ' checked' ''?> value="true">&nbsp;Schattieren</td>
         <td align="right">&nbsp;</td>
      </tr>
   </table>
</fieldset>

<?php
   
print form_add_hidden_fields(
      
$_REQUEST,
      array(
         
'/^s_min$/'
         
'/^s_max$/'
         
'/^sh_col$/'
         
'/^s_trans$/'
         
'/^s_f1$/'
         
'/^s_f2$/'
         
'/^sf_col$/'
         
'/^do_shade$/',
         
'/^function_/',
         
'/^num_new_func$/',
         
'/^asymptote_/',
         
'/^num_new_asym$/'
      
),
      
0
   
)
?>

<table align="center">
   <tr>
      <td align="right"><input type="submit" value=" &Uuml;bernehmen "></td>
      <td align="left"><input type="reset" value=" Zur&uuml;cksetzen "></td>
   </tr>
</table>

Datei tabs/general.php:

<?php

   
####################################################################################
   # Dies ist die Datei 'general.php'                                                 #
   #                                                                                  #
   # Sie enth"alt ein Tab des Plotterformulars des Parser/Plotter-Projekts;           #
   # es enth"alt generelle Einstellungen                                              #
   #                                                                                  #
   # Diese Datei darf frei als Ganzes oder in Teilen f"ur jegliche nicht-             #
   # kommerzielle Zwecke verwandt werden, solange folgede Bedingungen erf"ullt        #
   # werden:                                                                          #
   #    - Dieser Blockkommentar mit den Nutzungsbedingungen muss unver"andert         #
   #      in allen Nachfolgedateien / -ver"offentlichungen am Datei- / Textkopf       #
   #      verwandt werden                                                             #
   #    - Der Quellcode des muss jedem Benutzer von allen Programmen, die ihn         #
   #      verwenden, einsehbar gemacht werden                                         #
   #                                                                                  #
   # Sollten Sie diesen Code, in Teilen oder als Ganzes, auch portiert in             #
   # andere Programmiersprachen oder unter blo"ser Verwendung des Algorithmus         #
   # oder von Teilen von verwandten Algorithmen, f"ur kommerzielle Zwecke nutzen      #
   # wollen, so kontaktieren Sie mich bitte.                                          #
   #                                                                                  #
   # Ich habe den vorliegenden Code von Grund auf selbst programmiert und mich        #
   # dabei auf keine anderen als Standardalgorithmen gest"utzt. Insbesondere den      #
   # Tokenizer, der Parser und die Schrittweitensteurerung habe ich von Grund         #
   # auf und ohne Zuhilfenahme anderer Quellen selbst programmiert. Sollte ich        #
   # mit dem vorliegenden Code bestehende Copyrights oder Patente verletzen oder      #
   # den Urheber geistigen Eigentums vorenthalten, so geschieht dies                  #
   # unabsichtlich. Bitte kontaktieren Sie mich mittels untenstehender E-Mail-        #
   # Adresse oder "uber den Sysadmin.                                                 #
   #                                                                                  #
   # Der Autor "ubernimmt keine Haftung f"ur eventuelle durch die Nutzung dieses      #
   # entstehende oder entstandene mittelbare oder unmittelbare Sch"aden jedweder Art. #
   # Nutzung auf eigene Gefahr.                                                       #
   #                                                                                  #
   # Bitte schicken Sie mir keine E-Mails mit Bitte um die Erkl"arung der             #
   # Funktionsweise des Codes oder von Teilen des Codes; ich habe mich bem"uht,       #
   # den Code so gut wie m"oglich zu kommentieren und habe leider nicht genug         #
   # Zeit, um E-Mails "uber technische Details zu beantworten.                        #
   #                                                                                  #
   # (c) Jan Olligs, 2004                                                             #
   # Alle Rechte vorbehalten                                                          #
   #                                                                                  #
   # Jan.Olligs@gmx.net                                                               #
   ####################################################################################

   ####################################################################################
   # Parameter, die auf dieser Seite eingestellt werden:                              #
   #    'img_type', 'width', 'height'                                                 #
   #    'x_min', 'x_max', 'x_grid', 'y_min', 'y_max', 'y_grid'                        #
   #    'step', 'auto_step'                                                           #
   #    'bg_col', 'ax_col', 'gr_col', 'pl_col'                                        #
   #    'const'                                                                       #
   ####################################################################################

?>

<fieldset>
   <legend>Bildeinstellungen</legend>
   <table border="0" width="100%">
      <tr>
         <td align="right"><?php print form_text($_REQUEST'width'1040?></td>
         <td align="center">&nbsp;&times;&nbsp;</td>
         <td align="left"><?php print form_text($_REQUEST'height'1040?></td>
      </tr>
      <tr>
         <td align="right">Breite</td>
         <td align="center">&nbsp;&times;&nbsp;</td>
         <td align="left">H&ouml;he</td>
      </tr>
      </table>
      <table>
      <tr>
         <td align="right">Format:</td>
         <td align="center">&nbsp;</td>
         <td align="left">
<?php print form_img_type($_REQUEST'img_type'$plotter_standards12?>
         </td>
      </tr>
   </table>
</fieldset>

<fieldset>
   <legend>Dargestellter Bereich</legend>
   <table border="0" width="100%">
      <tr>
         <td width="50%">
            <fieldset>
               <legend>X<i>-Koordinate</i></legend>
               <table border="0" width="100%">
                  <tr>
                     <td>X-Untergrenze:&nbsp;</td>
                     <td align="right"><?php print form_text($_REQUEST'x_min'1040?></td>
                  </tr>
                  <tr>
                     <td>X-Obergrenze:&nbsp;</td>
                     <td align="right"><?php print form_text($_REQUEST'x_max'1040?></td>
                  </tr>
                  <tr>
                     <td>Abstand der X-Gitterlinien:</td>
                     <td align="right"><?php print form_text($_REQUEST'x_grid'1040?></td>
                  </tr>
               </table>
            </fieldset>
         </td>
         <td width="50%">
            <fieldset>
               <legend>Y<i>-Koordinate</i></legend>
               <table border="0" width="100%">
                  <tr>
                     <td>Y-Untergrenze:&nbsp;</td>
                     <td align="right"><?php print form_text($_REQUEST'y_min'1040?></td>
                  </tr>
                  <tr>
                     <td>Y-Obergrenze:&nbsp;</td>
                     <td align="right"><?php print form_text($_REQUEST'y_max'1040?></td>
                  </tr>
                  <tr>
                     <td>Abstand der Y-Gitterlinien:</td>
                     <td align="right"><?php print form_text($_REQUEST'y_grid'1040?></td>
                  </tr>
               </table>
            </fieldset>
         </td>
      </tr>
   </table>
</fieldset>

<fieldset>
   <legend>Zeicheneinstellungen</legend>
   <table border="0" width="100%">
      <tr>
         <td><input name="auto_step" type="radio" value="false"<?php if ($_REQUEST['auto_step'] == 'false') { print ' checked'; } ?>>&nbsp;Schrittweite:&nbsp;</td>
         <td align="right"><?php print form_text($_REQUEST'step'1040?></td>
      </tr>
      <tr>
         <td><input name="auto_step" type="radio" value="true"<?php if ($_REQUEST['auto_step'] == 'true') { print ' checked'; } ?>>&nbsp;Automatische Schrittweitensteuerung</td>
         <td>&nbsp;</td>
      </tr>
   </table>
</fieldset>

<fieldset>
   <legend>Zeichenfarben</legend>
   <table border="0" width="100%">
      <tr>
         <td>Hintergrund:&nbsp;</td>
         <td>
<?php print form_color_select($_REQUEST'bg_col'$global_colors12?>
         </td>
      </tr>
      <tr>
         <td>Graph (Standard):&nbsp;</td>
         <td>
<?php print form_color_select($_REQUEST'pl_col'$global_colors12?>
         </td>
      </tr>
      <tr>
         <td>Achsen:&nbsp;</td>
         <td>
<?php print form_color_select($_REQUEST'ax_col'$global_colors12?>
         </td>
      </tr>
      <tr>
         <td>Gitterlinien:&nbsp;</td>
         <td>
<?php print form_color_select($_REQUEST'gr_col'$global_colors12?>
         </td>
      </tr>
   </table>
</fieldset>

<fieldset>
   <legend>Konstanten</legend>
   <p>Eingaben in der Form [name]=[Term], eine Zeile pro Konstante.</p>
   <textarea name="const" cols="50" rows="10"><?php
      
print htmlspecialchars($_REQUEST['const']);

 
?></textarea>
</fieldset>

<?php 
   
print form_add_hidden_fields(
      
$_REQUEST
      array(
         
'/^img_type$/'
         
'/^width$/'
         
'/^height$/',
         
'/^x_min$/'
         
'/^x_max$/'
         
'/^x_grid$/'
         
'/^y_min$/'
         
'/^y_max$/'
         
'/^y_grid$/',
         
'/^step$/',
         
'/^auto_step$/',
         
'/^bg_col$/'
         
'/^ax_col$/'
         
'/^gr_col$/'
         
'/^pl_col$/',
         
'/^const$/'
      
),
      
0
   
)
?>

<table align="center">
   <tr>
      <td align="right"><input type="submit" value=" &Uuml;bernehmen "></td>
      <td align="left"><input type="reset" value=" Zur&uuml;cksetzen "></td>
   </tr>
</table>

Datei tabs/graph.php:

<?php

   
####################################################################################
   # Dies ist die Datei 'graph.php'                                                   #
   #                                                                                  #
   # Sie enth"alt ein Tab des Plotterformulars des Parser/Plotter-Projekts;           #
   # es dient zur Ausgabe des Graphs                                                  #
   #                                                                                  #
   # Diese Datei darf frei als Ganzes oder in Teilen f"ur jegliche nicht-             #
   # kommerzielle Zwecke verwandt werden, solange folgede Bedingungen erf"ullt        #
   # werden:                                                                          #
   #    - Dieser Blockkommentar mit den Nutzungsbedingungen muss unver"andert         #
   #      in allen Nachfolgedateien / -ver"offentlichungen am Datei- / Textkopf       #
   #      verwandt werden                                                             #
   #    - Der Quellcode des muss jedem Benutzer von allen Programmen, die ihn         #
   #      verwenden, einsehbar gemacht werden                                         #
   #                                                                                  #
   # Sollten Sie diesen Code, in Teilen oder als Ganzes, auch portiert in             #
   # andere Programmiersprachen oder unter blo"ser Verwendung des Algorithmus         #
   # oder von Teilen von verwandten Algorithmen, f"ur kommerzielle Zwecke nutzen      #
   # wollen, so kontaktieren Sie mich bitte.                                          #
   #                                                                                  #
   # Ich habe den vorliegenden Code von Grund auf selbst programmiert und mich        #
   # dabei auf keine anderen als Standardalgorithmen gest"utzt. Insbesondere den      #
   # Tokenizer, der Parser und die Schrittweitensteurerung habe ich von Grund         #
   # auf und ohne Zuhilfenahme anderer Quellen selbst programmiert. Sollte ich        #
   # mit dem vorliegenden Code bestehende Copyrights oder Patente verletzen oder      #
   # den Urheber geistigen Eigentums vorenthalten, so geschieht dies                  #
   # unabsichtlich. Bitte kontaktieren Sie mich mittels untenstehender E-Mail-        #
   # Adresse oder "uber den Sysadmin.                                                 #
   #                                                                                  #
   # Der Autor "ubernimmt keine Haftung f"ur eventuelle durch die Nutzung dieses      #
   # entstehende oder entstandene mittelbare oder unmittelbare Sch"aden jedweder Art. #
   # Nutzung auf eigene Gefahr.                                                       #
   #                                                                                  #
   # Bitte schicken Sie mir keine E-Mails mit Bitte um die Erkl"arung der             #
   # Funktionsweise des Codes oder von Teilen des Codes; ich habe mich bem"uht,       #
   # den Code so gut wie m"oglich zu kommentieren und habe leider nicht genug         #
   # Zeit, um E-Mails "uber technische Details zu beantworten.                        #
   #                                                                                  #
   # (c) Jan Olligs, 2004                                                             #
   # Alle Rechte vorbehalten                                                          #
   #                                                                                  #
   # Jan.Olligs@gmx.net                                                               #
   ####################################################################################

   
$width  check_error($_REQUEST['width'],  'n'false$plotter_standards{'img_width'}[1]);
   
$height check_error($_REQUEST['height'], 'n'false$plotter_standards{'img_height'}[1]);

?>
<div align="center"><img src="graph.php?<?php 
   
print http_build_query($_REQUEST
       . 
'" width="' $width 
       
'" height="' $height;
?>"></div>

Datei units/mathdef.php:

<?php

   
####################################################################################
   # Dies ist die Datei 'mathdef.php'                                                 #
   #                                                                                  #
   # Sie enth"alt Funktions- und "ahnliche Definitionen des Parser/Plotter-Projekts   #
   #                                                                                  #
   # Diese Datei darf frei als Ganzes oder in Teilen f"ur jegliche nicht-             #
   # kommerzielle Zwecke verwandt werden, solange folgede Bedingungen erf"ullt        #
   # werden:                                                                          #
   #    - Dieser Blockkommentar mit den Nutzungsbedingungen muss unver"andert         #
   #      in allen Nachfolgedateien / -ver"offentlichungen am Datei- / Textkopf       #
   #      verwandt werden                                                             #
   #    - Der Quellcode des muss jedem Benutzer von allen Programmen, die ihn         #
   #      verwenden, einsehbar gemacht werden                                         #
   #                                                                                  #
   # Sollten Sie diesen Code, in Teilen oder als Ganzes, auch portiert in             #
   # andere Programmiersprachen oder unter blo"ser Verwendung des Algorithmus         #
   # oder von Teilen von verwandten Algorithmen, f"ur kommerzielle Zwecke nutzen      #
   # wollen, so kontaktieren Sie mich bitte.                                          #
   #                                                                                  #
   # Ich habe den vorliegenden Code von Grund auf selbst programmiert und mich        #
   # dabei auf keine anderen als Standardalgorithmen gest"utzt. Insbesondere den      #
   # Tokenizer, der Parser und die Schrittweitensteurerung habe ich von Grund         #
   # auf und ohne Zuhilfenahme anderer Quellen selbst programmiert. Sollte ich        #
   # mit dem vorliegenden Code bestehende Copyrights oder Patente verletzen oder      #
   # den Urheber geistigen Eigentums vorenthalten, so geschieht dies                  #
   # unabsichtlich. Bitte kontaktieren Sie mich mittels untenstehender E-Mail-        #
   # Adresse oder "uber den Sysadmin.                                                 #
   #                                                                                  #
   # Der Autor "ubernimmt keine Haftung f"ur eventuelle durch die Nutzung dieses      #
   # entstehende oder entstandene mittelbare oder unmittelbare Sch"aden jedweder Art. #
   # Nutzung auf eigene Gefahr.                                                       #
   #                                                                                  #
   # Bitte schicken Sie mir keine E-Mails mit Bitte um die Erkl"arung der             #
   # Funktionsweise des Codes oder von Teilen des Codes; ich habe mich bem"uht,       #
   # den Code so gut wie m"oglich zu kommentieren und habe leider nicht genug         #
   # Zeit, um E-Mails "uber technische Details zu beantworten.                        #
   #                                                                                  #
   # (c) Jan Olligs, 2004                                                             #
   # Alle Rechte vorbehalten                                                          #
   #                                                                                  #
   # Jan.Olligs@gmx.net                                                               #
   ####################################################################################

   # Interne PHP-Begrenzungen

   
define("MAXSIZE",  100);       # Maximale Anzahl von Flie"skommastellen

   # Variablen und Differentiale

   
define(  "FIRST_VAR",   "x");
   
define("D_FIRST_VAR",  "dx");
   
define(  "SECOND_VAR",  "y");
   
define("D_SECOND_VAR""dy");

   
# Konstanten

   
$global_constants = array(
           
'pi' => M_PI,
           
'e'  => M_E
   
);

   
# Klammern im Format (("offnend, schlie"send), ("offnend, schlie"send), ...)

   
$global_parens = array(
           array(
'('')'),
           array(
'['']'),
           array(
'{''}')
   );


   
####################################################################################
   # Form f"ur Operatordefinitionen (un"ar):                                          #
   #    [Symbol] => array(                                                            #
   #                'others'  => array([andere Symbole]),                             #
   #                'deriv'   => [Ableitung als parse tree],                          #
   #                'name'    => [Name der Funktion],                                 #
   #                'info'    => [Informationen, Erkl"arungen],                       #
   #                'example' => [Beispiel(e)],                                       #
   #                'eval'    => [Funktion zur Berechnung]                            #
   #                   )                                                              #
   #                                                                                  #
   #    Parse tree Syntax:                                                            #
   #       <tree> = <node> ODER                                                       #
   #                ('u', [un"arer Operator], <tree>) ODER                            #
   #                ('b', [bin"arer Operator], <tree>, <tree>)                        #
   #       <node> = Wert (Zahl) ODER String mit Variable / Konstante                  #
   #                                                                                  #
   #    Zur Ableitung:                                                                #
   #       Un"are Funktionen f(u) werden nach der Kettenregel abgeleitet; das         #
   #       argument ist die Konstante FIRST_VAR, seine Ableitung die Konstante        #
   #       D_FIRST_VAR. Die Ableitung von ln(FIRST_VAR) ist also u' / u =             #
   #       D_FIRST_VAR / FIRST_VAR. Bin"are Operatoren werden als Funktion von zwei   #
   #       von x abh"angigen Argumenten angesehen: f(u, v) = f(u(x), v(x)). Dabei     #
   #       wird gesetzt: FIRST_VAR = u, D_FIRST_VAR = u', SECOND_VAR = v,             #
   #       D_SECOND_VAR = v'. u ist das erste, v das zweite Argument des Operators    #
   #       bei seiner Auswertung.                                                     #
   #       Zur Entwicklung einer Differenzierungfunktion ist nur zu sagen, dass sie   #
   #       lediglich drei Regeln beherrschen muss: Die Ableitung einer Konstante ist  #
   #       Null, die Ableitung der Variablen, nach der abgeleitet wird, eins, und     #
   #       wenn der parse tree einer Funktion (b, op, links, rechts) lautet, m"ussen  #
   #       zwei neue parse trees, u' = Ableitung(links) und v' = Ableitug(rechts),    #
   #       bestimmt werden; au"serdem werden u = links und v = rechts gespeichert und #
   #       im Differential der Funktion dann FIRST_VAR durch u, D_FIRST_VAR durch u', #
   #       etc. ersetzt. Damit sind s"amtliche Ableitungsregeln schon in den Ablei-   #
   #       tungen der Operatoren enthalten.                                           #
   #                                                                                  #
   #    Beispiel f"ur eval-Funktion:                                                  #
   #       'eval'    => create_function('$value, &$error',                            #
   #                      '$error = $global_error_names{'NOERROR'};                   #
   #                       return -$value;'                                           #
   #                    )                                                             #
   #    $error wird also als Referenz "ubergeben                                      #
   #    Dei globale Variable $global_error_names aus parser.php kann verwandt werden  #
   ####################################################################################

   # Operatoren

   
$global_unary_operators  = array(
      
'neg'   => array(
         
'others'  => array('minus''inv'),
         
'deriv'   => '-1',
         
'name'    => 'Inverses',
         
'info'    => "Das Inverse von x bezüglich der Addition.",
         
'example' => "neg(3) = -3",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'
                         $error = $global_error_names{\'NOERROR\'};
                         return -$value;'
                      
)
      ),
      
'abs'   => array(
         
'others'  => array('betr'),
         
'deriv'   => array('b''/''1', array('u''sgn'FIRST_VAR)),
         
'name'    => 'Betrag',
         
'info'    => "Der Wert von x ohne Vorzeichen; abs(x) = x wenn x >= 0, sonst -x.",
         
'example' => "abs(-2) = abs(2) = 2",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'
                         $error = $global_error_names{\'NOERROR\'};
                         return abs($value);'
                      
)
      ),
      
'sgn'   => array(
         
'others'  => array('sig''sg''sn'),
         
'deriv'   => array('b''/''0', array('u''sgn'FIRST_VAR)),
         
'name'    => 'Vorzeichen (Signum)',
         
'info'    => "Das Vorzeichen von x; sgn(x) = 1 wenn x > 0, 0 wenn x = 0, sonst -1.",
         
'example' => "sgn(-3) = -1; sgn(2) = 1; sgn(0) = 0",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'
                         $error = $global_error_names{\'NOERROR\'};
                         if ($value == 0) {
                            return 0;
                         } else if ($value > 0) {
                            return 1;
                         }
                         return -1;'
                      
)
      ),
      
'sqrt'  => array(
         
'others'  => array('sroot''srt''qw'),
         
'deriv'   => array('b''/''1', array('b''*''2', array('u''sqrt'FIRST_VAR))),
         
'name'    => 'Quadratwurzel',
         
'info'    => "Das nichtnegative Inverse der Quadratfunktion.",
         
'example' => "sqrt(9) = 3",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'if ($value < 0) {
                            $error = $global_error_names{\'OUTOFRANGE\'};
                            return;
                         }
                         $error = $global_error_names{\'NOERROR\'};
                         return sqrt($value);'
                      
)
      ),
      
'exp'   => array(
         
'others'  => array(),
         
'deriv'   => array('u''exp'FIRST_VAR),
         
'name'    => 'Exponentialfunktion',
         
'info'    => "e^x, wobei e für die Eulersche Zahl (ungefähr 2.71828) steht.",
         
'example' => "exp(0) = 1; exp(2) = 7.38906",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'if ($value > MAXSIZE * log(10)) {
                            $error = $global_error_names{\'OUTOFRANGE\'};
                            return;
                         }
                         $error = $global_error_names{\'NOERROR\'};
                         return exp($value);'
                      
)
      ),
      
'ln'    => array(
         
'others'  => array('logn'),
         
'deriv'   => array('b''/''1'FIRST_VAR),
         
'name'    => 'Natürlicher Logarithmus',
         
'info'    => "Logarithmus zur Basis e, wobei e für die Eulersche Zahl (ungefähr 2.71828) steht.",
         
'example' => "ln(1) = 0; ln(5) = 1.60944",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'if ($value <= 0) {
                            $error = $global_error_names{\'OUTOFRANGE\'};
                            return;
                         }
                         $error = $global_error_names{\'NOERROR\'};
                         return log($value);'
                     
)
      ),
      
'lg'    => array(
         
'others'  => array('logdec'),
         
'deriv'   => array('b''/''1', array('b''*', array('u''ln''10'), FIRST_VAR)),
         
'name'    => 'Dekadischer Logarithmus',
         
'info'    => "Logarithmus zur Basis 10.",
         
'example' => "lg(1) = 0; ln(5) = 0.69897",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'if ($value <= 0) {
                            $error = $global_error_names{\'OUTOFRANGE\'};
                            return;
                         }
                         $error = $global_error_names{\'NOERROR\'};
                         return log10($value);'
                      
)
      ),
      
'ld'    => array(
         
'others'  => array('logdual''lb''logbin'),
         
'deriv'   => array('b''/''1', array('b''*', array('u''lg''2'), FIRST_VAR)),
         
'name'    => 'Binärer Logarithmus (Logarithmus Dualis)',
         
'info'    => "Logarithmus zur Basis 2.",
         
'example' => "lg(1) = 0; ln(5) = 2.321928",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'if ($value <= 0) {
                            $error = $global_error_names{\'OUTOFRANGE\'};
                            return;
                         }
                         $error = $global_error_names{\'NOERROR\'};
                         return log($value) / M_LN2;'
                      
)
      ),
      
'sin'   => array(
         
'others'  => array(),
         
'deriv'   => array('u''cos'FIRST_VAR),
         
'name'    => 'Sinus',
         
'info'    => "Im rechtwinkligen Dreieck: Gegenkathete durch Hypothenuse.",
         
'example' => "sin(3) = 0.14112",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'
                         $error = $global_error_names{\'NOERROR\'};
                         return sin($value);'
                      
)
      ),
      
'cos'   => array(
         
'others'  => array(),
         
'deriv'   => array('u''neg', array('u''sin'FIRST_VAR)),
         
'name'    => 'Cosinus',
         
'info'    => "Im rechtwinkligen Dreieck: Ankathete durch Hypothenuse.",
         
'example' => "cos(3) = -0.98999",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'
                         $error = $global_error_names{\'NOERROR\'};
                         return cos($value);'
                      
)
      ),
      
'sec'   => array(
         
'others'  => array('secans'),
         
'deriv'   => array('b''/', array('u''neg', array('u''sin'FIRST_VAR)), array('b''^', array('u''cos'FIRST_VAR), '2')),
         
'name'    => 'Secans',
         
'info'    => "sec(x) = 1 / cos(x)",
         
'example' => "sec(3) = -1.01011",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'$value = cos($value);
                         if ($value == 0) {
                            $error = $global_error_names{\'DIVBYZERO\'};
                            return;
                         }
                         $error = $global_error_names{\'NOERROR\'};
                         return 1 / $value;'
                      
)
      ),
      
'csc'   => array(
         
'others'  => array('cosec''cosecans'),
         
'deriv'   => array('b''/', array('u''cos'FIRST_VAR), array('b''^', array('u''sin'FIRST_VAR), '2')),
         
'name'    => 'Cosecans',
         
'info'    => "csc(x) = 1 / sin(x)",
         
'example' => "csc(3) = 7.08617",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'$value = sin($value);
                         if ($value == 0) {
                            $error = $global_error_names{\'DIVBYZERO\'};
                            return;
                         }
                         $error = $global_error_names{\'NOERROR\'};
                         return 1 / $value;'
                      
)
      ),
      
'tan'   => array(
         
'others'  => array('tangens'),
         
'deriv'   => array('b''1', array('b''^', array('u''cos'FIRST_VAR), '2')),
         
'name'    => 'Tangens',
         
'info'    => "tan(x) = sin(x) / cos(x)",
         
'example' => "tan(3) = -0.14255",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'if (cos($value) == 0) {
                            $error = $global_error_names{\'DIVBYZERO\'};
                            return;
                         }
                         $error = $global_error_names{\'NOERROR\'};
                         return tan($value);'
                      
)
      ),
      
'cot'   => array(
         
'others'  => array('cotan''cotangens'),
         
'deriv'   => array('b''/''-1', array('b''^', array('u''sin'FIRST_VAR), '2')),
         
'name'    => 'Cotangens',
         
'info'    => "cot(x) = cos(x) / sin(x)",
         
'example' => "cot(3) = -7.01525",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'if (sin($value) == 0) {
                            $error = $global_error_names{\'DIVBYZERO\'};
                            return;
                         }
                         $error = $global_error_names{\'NOERROR\'};
                         return 1 / tan($value);'
                      
)
      ),
      
'asin'  => array(
         
'others'  => array('arcsin'),
         
'deriv'   => array('b''/''1', array('u''sqrt', array('b''-''1', array('b''^'FIRST_VAR'2')))),
         
'name'    => 'Arcus sinus',
         
'info'    => "Umkehrfunktion des Sinus.",
         
'example' => "asin(0.5) = 0.52360",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'if (abs($value) > 1) {
                            $error = $global_error_names{\'DIVBYZERO\'};
                            return;
                         }
                         $error = $global_error_names{\'NOERROR\'};
                         return asin($value);'
                      
)
      ),
      
'acos'  => array(
         
'others'  => array('arccos'),
         
'deriv'   => array('b''/''-1', array('u''sqrt', array('b''-''1', array('^'FIRST_VAR'2')))),
         
'name'    => 'Arcus cosinus',
         
'info'    => "Umkehrfunktion des Cosinus.",
         
'example' => "acos(0.5) = 1.04720",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'if (abs($value) > 1) {
                            $error = $global_error_names{\'DIVBYZERO\'};
                            return;
                         }
                         $error = $global_error_names{\'NOERROR\'};
                         return acos($value);'
                      
)
      ),
      
'asec'  => array(
         
'others'  => array('asecans''arcsec''arcsecans'),
         
'deriv'   => array('b' '/''1', array('b''*', array('b''^'FIRST_VAR'2'), array('u''sqrt', array('b''-''1', array('b''^'FIRST_VAR'2'))))),
         
'name'    => 'Arcus secans',
         
'info'    => "Umkehrfunktion des Secans.",
         
'example' => "asec(3) = 1.23096",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'if ($value == 0) {
                            $error = $global_error_names{\'DIVBYZERO\'};
                            return;
                         }
                         if (abs($value) < 1) {
                            $error = $global_error_names{\'OUTOFRANGE\'};
                            return;
                         }
                         $error = $global_error_names{\'NOERROR\'};
                         return acos(1 / $value);'
                      
)
      ),
      
'acsc'  => array(
         
'others'  => array('acosecans''arccsc''arccosecans'),
         
'deriv'   => array('b''/''-1', array('b''*', array('b''^'FIRST_VAR'2'), array('u''sqrt', array('b''-''1', array('b''^'FIRST_VAR'2'))))),
         
'name'    => 'Arcus cosecans',
         
'info'    => "Umkehrfunktion des Cosecans.",
         
'example' => "asec(3) = 0.33984",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'if ($value == 0) {
                            $error = $global_error_names{\'DIVBYZERO\'};
                            return;
                         }
                         if (abs($value) < 1) {
                            $error = $global_error_names{\'OUTOFRANGE\'};
                            return;
                         }
                         $error = $global_error_names{\'NOERROR\'};
                         return asin(1 / $value);'
                      
)
      ),
      
'atan'  => array(
         
'others'  => array('atangens''arctan''arctangens'),
         
'deriv'   => array('b''/''1', array('b''+''1', array('b''^'FIRST_VAR'2'))),
         
'name'    => 'Arcus tangens',
         
'info'    => "Umkehrfunktion des Tangens.",
         
'example' => "atan(3) = 1.249046",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'
                         $error = $global_error_names{\'NOERROR\'};
                         return atan($value);'
                      
)
      ),
      
'acot'  => array(
         
'others'  => array('acotangent''arccot''arccotangent'),
         
'deriv'   => array('b''/''-1', array('b''+''1', array('b''^'FIRST_VAR'2'))),
         
'name'    => 'Arcus cotangens',
         
'info'    => "Umkehrfunktion des Tangens.",
         
'example' => "acot(3) = 0.32175",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'
                         $error = $global_error_names{\'NOERROR\'};
                         if ($value == 0) {
                            return M_PI_2;
                         }
                         return atan(1 / $value);'
                      
)
      ),
      
'sinh'   => array(
         
'others'  => array(),
         
'deriv'   => array('u''cosh'FIRST_VAR),
         
'name'    => 'Sinus hyperbolicus',
         
'info'    => "sinh(x) = (e^x - e^(-x)) / 2",
         
'example' => "sinh(3) = 10.01787",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'
                         $error = $global_error_names{\'NOERROR\'};
                         return sinh($value);'
                      
)
      ),
      
'cosh'   => array(
         
'others'  => array(),
         
'deriv'   => array('u''sinh'FIRST_VAR),
         
'name'    => 'Cosinus hyperbolicus',
         
'info'    => "cosh(x) = (e^x + e^(-x)) / 2",
         
'example' => "cosh(3) = 10.06766",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'
                         $error = $global_error_names{\'NOERROR\'};
                         return cosh($value);'
                      
)
      ),
      
'sech'  => array(
         
'others'  => array(),
         
'deriv'   => array('u''neg', array('b''/', array('u''sinh'FIRST_VAR), array('b''^', array('u''cosh'FIRST_VAR), '2'))),
         
'name'    => 'Secans hyperbolicus',
         
'info'    => "sech(x) = 1 / cosh(x)",
         
'example' => "sech(3) = 0.09933",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'$value = cosh($value);
                         if ($value == 0) {
                            $error = $global_error_names{\'DIVBYZERO\'};
                            return;
                         }
                         $error = $global_error_names{\'NOERROR\'};
                         return 1 / $value;'
                      
)
      ),
      
'csch'  => array(
         
'others'  => array(),
         
'deriv'   => array('u''neg', array('b''/', array('u''cosh'FIRST_VAR), array('b''^', array('u''sinh'FIRST_VAR), '2'))),
         
'name'    => 'Hyperbolic cosecant',
         
'info'    => "csch(x) = 1 / sinh(x)",
         
'example' => "csch(3) = 0.099822",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'$value = sinh($value);
                         if ($value == 0) {
                            $error = $global_error_names{\'DIVBYZERO\'};
                            return;
                         }
                         $error = $global_error_names{\'NOERROR\'};
                         return 1 / $value;'
                      
)
      ),
      
'tanh'  => array(
         
'others'  => array(),
         
'deriv'   => array('b''/''1', array('b''^', array('u''cosh'FIRST_VAR), '2')),
         
'name'    => 'Tangens hyperbolicus',
         
'info'    => "tanh(x) = sinh(x) / cosh(x)",
         
'example' => "tanh(3) = 0.995055",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'if (cosh($value) == 0) {
                            $error = $global_error_names{\'DIVBYZERO\'};
                            return;
                         }
                         $error = $global_error_names{\'NOERROR\'};
                         return tanh($value);'
                      
)
      ),
      
'coth'  => array(
         
'others'  => array(),
         
'deriv'   => array('b''/''-1', array('b''^', array('u''sinh'FIRST_VAR), '2')),
         
'name'    => 'Cotangens hyperbolicus',
         
'info'    => "coth(x) = cosh(x) / sinh(x)",
         
'example' => "coth(3) = 1.004970",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'if (sinh($value) == 0) {
                            $error = $global_error_names{\'DIVBYZERO\'};
                            return;
                         }
                         $error = $global_error_names{\'NOERROR\'};
                         return 1 / tanh($value);'
                      
)
      ),
      
'asinh' => array(
         
'others'  => array('arsinh''areasinh'),
         
'deriv'   => array('b''/''1', array('u''sqrt', array('b''+''1', array('b''^'FIRST_VAR'2')))),
         
'name'    => 'Area sinus hyperbolicus',
         
'info'    => "Umkehrfunktion des Sinus hyperbolicus.",
         
'example' => "asinh(3) = 1.818446",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'
                         $error = $global_error_names{\'NOERROR\'};
                         return asinh($value);'
                      
)
      ),
      
'acosh' => array(
         
'others'  => array('arcosh''areacosh'),
         
'deriv'   => array('b''/''1', array('u''sqrt', array('b''-', array('b''^'FIRST_VAR'2'), '1'))),
         
'name'    => 'Area cosinus hyperbolicus',
         
'info'    => "Umkehrfunktion des Cosinus hyperbolicus.",
         
'example' => "acosh(3) = 1.762747",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'if ($value < 1) {
                            $error = $global_error_names{\'OUTOFRANGE\'};
                            return;
                         }
                         $error = $global_error_names{\'NOERROR\'};
                         return acosh($value);'
                      
)
      ),
      
'floor'  => array(
         
'others'  => array('rounddown''abrunden'),
         
'deriv'   => array('b''/''0', array('b''-'FIRST_VAR, array('u''floor'FIRST_VAR))),
         
'name'    => 'Floor',
         
'info'    => "Die größte ganze Zahl, die kleiner oder gleich dem Argment ist.",
         
'example' => "floor(-4.35) = -5; floor(4.35) = 4; floor(-4) = -4",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'
                         $error = $global_error_names{\'NOERROR\'};
                         return floor($value);'
                      
)
      ),
      
'ceil'  => array(
         
'others'  => array('roundup''aufrunden'),
         
'deriv'   => array('b''/''0', array('b''-'FIRST_VAR, array('u''floor'FIRST_VAR))),
         
'name'    => 'Ceiling',
         
'info'    => "Die kleinste ganze Zahl, die größer oder gleich dem Argument ist.",
         
'example' => "floor(-4.35) = -4; floor(4.35) = 5; floor(-4) = -4",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'
                         $error = $global_error_names{\'NOERROR\'};
                         return ceil($value);'
                      
)
      ),
      
'round' => array(
         
'others'  => array('runden'),
         
'deriv'   => array('b''/''0', array('b''-', array('b''+'FIRST_VAR'0.5'), array('u''floor', array('b''+'FIRST_VAR'0.5')))),
         
'name'    => 'Runden',
         
'info'    => "Rundet das Argument auf die nächste ganze Zahl.",
         
'example' => "round(-4.35) = -4; round(4.75) = 5; round(-4) = -4",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'
                         $error = $global_error_names{\'NOERROR\'};
                         return round($value);'
                      
)
      ),
      
'frac'  => array(
         
'others'  => array('fractional'),
         
'deriv'   => array('b''/', array('b''-'FIRST_VAR, array('u''int'FIRST_VAR)), array('b''-'FIRST_VAR, array('u''int'FIRST_VAR))),
         
'name'    => 'Nachkommaanteil',
         
'info'    => "Gibt den Nachkommanteil des Arguments zurück.",
         
'example' => "frac(-4.35) = -0.35; frac(4.35) = 0.35; frac(-4) = 0",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'
                         $error = $global_error_names{\'NOERROR\'};
                         return abs($value) - floor(abs($value));'
                      
)
      ),
      
'int'   => array(
         
'others'  => array('integral''trunc'),
         
'deriv'   => array('b''/''0', array('b''^', array('b''-'FIRST_VAR, array('u''floor'FIRST_VAR)), FIRST_VAR)),
         
'name'    => 'Ganzer Anteil',
         
'info'    => "Schneidet den Nachkommanteil des Arguments ab.",
         
'example' => "int(-4.35) = -4; int(4.35) = 4; int(-4) = -4",
         
'eval'    => create_function('$value, &$error',
                        
'global $global_error_names;' "\n" .
                        
'
                         $error = $global_error_names{\'NOERROR\'};
                         if ($value > 0) {
                            return floor($value);
                         } else {
                            return ceil($value);
                         }'
                      
)
         )
   );

   
####################################################################################
   # Form f"ur Operatordefinitionen (bin"ar):                                         #
   #    [Symbol] => array(                                                            #
   #                'deriv'   => [Ableitung als parse tree],                          #
   #                'name'    => [Name der Funktion],                                 #
   #                'info'    => [Informationen, Erkl"arungen],                       #
   #                'example' => [Beispiel(e)],                                       #
   #                'eval'    => [Funktion zur Berechnung]                            #
   #                   )                                                              #
   #                                                                                  #
   #    Zur Ableitung:                                                                #
   #       Un"are Funktionen f(u) werden nach der Kettenregel abgeleitet; das         #
   #       argument ist die Konstante FIRST_VAR, seine Ableitung die Konstante        #
   #       D_FIRST_VAR. Die Ableitung von ln(FIRST_VAR) ist also u' / u =             #
   #       D_FIRST_VAR / FIRST_VAR. Bin"are Operatoren werden als Funktion von zwei   #
   #       von x abh"angigen Argumenten angesehen: f(u, v) = f(u(x), v(x)). Dabei     #
   #       wird gesetzt: FIRST_VAR = u, D_FIRST_VAR = u', SECOND_VAR = v,             #
   #       D_SECOND_VAR = v'. u ist das erste, v das zweite Argument des Operators    #
   #       bei seiner Auswertung.                                                     #
   #       Zur Entwicklung einer Differenzierungfunktion ist nur zu sagen, dass sie   #
   #       lediglich drei Regeln beherrschen muss: Die Ableitung einer Konstante ist  #
   #       Null, die Ableitung der Variablen, nach der abgeleitet wird, eins, und     #
   #       wenn der parse tree einer Funktion (b, op, links, rechts) lautet, m"ussen  #
   #       zwei neue parse trees, u' = Ableitung(links) und v' = Ableitug(rechts),    #
   #       bestimmt werden; au"serdem werden u = links und v = rechts gespeichert und #
   #       im Differential der Funktion dann FIRST_VAR durch u, D_FIRST_VAR durch u', #
   #       etc. ersetzt. Damit sind s"amtliche Ableitungsregeln schon in den Ablei-   #
   #       tungen der Operatoren enthalten.                                           #
   #                                                                                  #
   #    Parse tree Syntax:                                                            #
   #       <tree> = <node> ODER                                                       #
   #                ('u', [un"arer Operator], <tree>) ODER                            #
   #                ('b', [bin"arer Operator], <tree>, <tree>)                        #
   #       <node> = Wert (Zahl) ODER String mit Variable / Konstante                  #
   #                                                                                  #
   #    Beispiel f"ur eval-Funktion:                                                  #
   #       'eval'    => create_function('$value, &$error',                            #
   #                      '$error = $global_error_names{'NOERROR'};                   #
   #                       return -$value;'                                           #
   #                    )                                                             #
   #    $error wird also als Referenz "ubergeben                                      #
   #    Dei globale Variable $global_error_names aus parser.php kann verwandt werden  #
   ####################################################################################

   
$global_binary_operators = array(
      array( 
# Pr"azedenz 1 => h"ochste
         
'^'    => array(
            
'deriv'   => array('b''*', array('b''^'FIRST_VARSECOND_VAR), array('b''+', array('b''*', array('b''/'D_FIRST_VARFIRST_VAR), SECOND_VAR), array('b''*', array('u''ln'FIRST_VAR), D_SECOND_VAR))),
            
'name'    => 'Potenz',
            
'info'    => "keine Information vorhanden",
            
'example' => "3^0 = 1; 3^1 = 1; 3^2 = 9",
            
'eval'    => create_function('$value1, $value2, &$error',
                           
'global $global_error_names;' "\n" .
                           
'if (log10(abs($value1)) * $value2 > MAXSIZE) {
                               $error = $global_error_names{\'OUTOFRANGE\'};
                               return;
                            } else if ($value1 < 0 && $value2 != round($value2)) {
                               $error = $global_error_names{\'OUTOFRANGE\'};
                               return;
                            } else {
                               if ($value2 < 0 && $value1 == 0) {
                                  $error = $global_error_names{\'DIVBYZERO\'};
                                  return;
                               }
                               $error = $global_error_names{\'NOERROR\'};
                               return pow($value1, $value2);
                            }'
                         
)
         ),
         
'root' => array(
            
'deriv'   => array('b''*', array('b''root'FIRST_VARSECOND_VAR), array('b''/', array('b''-', array('b''*', array('b''/'D_SECOND_VARSECOND_VAR), FIRST_VAR), array('b''*', array('u''ln'SECOND_VAR), D_FIRST_VAR)), array('b''^'FIRST_VAR2))),
            
'name'    => 'Wurzel',
            
'info'    => "a root b steht für die a-te Wurzel von b, per Definition gleich b^(1/a)",
            
'example' => "3^0 = 1; 3^1 = 1; 3^2 = 9",
            
'eval'    => create_function('$value1, $value2, &$error',
                           
'global $global_error_names;' "\n" .
                           
'if ($value1 == 0) {
                               $error = $global_error_names{\'DIVBYZERO\'};
                               break;
                            }
                            $value = $value2;
                            $value2 = 1 / $value1;
                            $value1 = $value;
                            if (log10(abs($value1)) * $value2 > MAXSIZE) {
                               $error = $global_error_names{\'OUTOFRANGE\'};
                               return;
                            } else if ($value1 < 0) {
                               $error = $global_error_names{\'OUTOFRANGE\'};
                               return;
                            } else {
                               if ($value2 < 0 && $value1 == 0) {
                                  $error = $global_error_names{\'DIVBYZERO\'};
                                  return;
                               }
                               $error = $global_error_names{\'NOERROR\'};
                               return pow($value1, $value2);
                            }'
                        
)
         ),
         
'log'  => array(
            
'deriv'   => array('b''/', array('b''-', array('b''*', array('b''/'D_SECOND_VARSECOND_VAR), array('u''ln'FIRST_VAR)), array('b''*', array('u''ln'SECOND_VAR), array('b''/'D_FIRST_VARFIRST_VAR))), array('b''^', array('u''ln'FIRST_VAR), '^')),
            
'name'    => 'Logarithmus',
            
'info'    => "a log b steht für den Logarithmus von b zur Basis a.",
            
'example' => "3 log 5 = 1.4649735",
            
'eval'    => create_function('$value1, $value2, &$error',
                           
'global $global_error_names;' "\n" .
                           
'if ($value1 <= 0 or log($value1) == 0) {
                               $error = $global_error_names{\'OUTOFRANGE\'};
                               return;
                            }
                            if ($value2 <= 0) {
                               $error = $global_error_names{\'OUTOFRANGE\'};
                               return;
                            }
                            $error = $global_error_names{\'NOERROR\'};
                            return log($value2) / log($value1);'
                         
)
         )
      ),
      array( 
# Pr"azedenz 2
         
'%'    => array(
            
'deriv'   => array(), # schwierig, da st"uckweise stetig
            
'name'    => 'Modulus',
            
'info'    => "a % b = r ist das eindeutig bestimmte r mit 0 <= abs(r) < abs(b), sgn(r) = sgn(b) oder r = 0 und (a - r) teilbar durch b",
            
'example' => "5 % 3 = 2",
            
'eval'    => create_function('$value1, $value2, &$error',
                           
'global $global_error_names;' "\n" .
                           
'if ($value2 == 0) {
                               $error = $global_error_names{\'DIVBYZERO\'};
                               return;
                            } else if ($value2 < 0) {
                               $error = $global_error_names{\'OUTOFRANGE\'};
                               return;
                            } else {
                               $error = $global_error_names{\'NOERROR\'};
                               return fmod($value1, $value2);
                            }'
                         
)
         ),
         
'mod'  => array(
            
'deriv'   => array(), # schwierig, da st"uckweise stetig
            
'name'    => 'Modulus',
            
'info'    => "a mod b = r ist das eindeutig bestimmte r mit 0 <= abs(r) < abs(b), sgn(r) = sgn(b) oder r = 0 und (a - r) teilbar durch b",
            
'example' => "5 mod 3 = 2",
            
'eval'    => create_function('$value1, $value2, &$error',
                           
'global $global_error_names;' "\n" .
                           
'if ($value2 == 0) {
                               $error = $global_error_names{\'DIVBYZERO\'};
                               return;
                            } else if ($value2 < 0) {
                               $error = $global_error_names{\'OUTOFRANGE\'};
                               return;
                            } else {
                               $error = $global_error_names{\'NOERROR\'};
                               return fmod($value1, $value2);
                            }'
                         
)
         ),
         
'div'  => array(
            
'deriv'   => array(), # schwierig, da st"uckweise stetig (Ableitung von int(FIST_VAR / SECOND_VAR); Kettenregel; s.o.)
            
'name'    => 'Ganzzahliger Anteil bei Division',
            
'info'    => "a div b ist der ganzzahlige Anteil des Quotients dieser beiden Zahlen",
            
'example' => "5 div 3 = 1",
            
'eval'    => create_function('$value1, $value2, &$error',
                           
'global $global_error_names;' "\n" .
                           
'if ($value2 == 0) {
                               $error = $global_error_names{\'DIVBYZERO\'};
                               return;
                            } else {
                               $i = 0;
                               if ($value1 / $value2 < 0) {
                                  while (abs($value1) > abs($value2)) { $value1 += $value2; --$i;}
                               } else {
                                  while (abs($value1) > abs($value2)) { $value1 -= $value2; ++$i;}
                               }
                               $error = $global_error_names{\'NOERROR\'};
                               return $i;
                            }'
                         
)
         ),
      ),
      array( 
# Pr"azedenz 3
         
'*'    => array(
            
'deriv'   => array('b''+', array('b''*'D_FIRST_VARSECOND_VAR), array('b''*'FIRST_VARD_SECOND_VAR)),
            
'name'    => 'Multiplikation',
            
'info'    => "keine Information vorhanden",
            
'example' => "5 * 3 = 15",
            
'eval'    => create_function('$value1, $value2, &$error',
                           
'global $global_error_names;' "\n" .
                           
'if (!($value1 == 0 || $value2 == 0)) {
                               if (log10(abs($value1)) + log10(abs($value2)) > MAXSIZE) {
                                  $error = $global_error_names{\'OUTOFRANGE\'};
                                  return;
                               }
                            }
                            $error = $global_error_names{\'NOERROR\'};
                            return $value1 * $value2;'
                         
)
         ),
         
'/'    => array(
            
'deriv'   => array('b''/', array('b''-', array('b''*'D_FIRST_VARSECOND_VAR), array('b''*'FIRST_VARD_SECOND_VAR)), array('b''^'SECOND_VAR2)),
            
'name'    => 'Division',
            
'info'    => "keine Information vorhanden",
            
'example' => "5 / 3 = 1.66667",
            
'eval'    => create_function('$value1, $value2, &$error',
                           
'global $global_error_names;' "\n" .
                           
'if ($value2 == 0) {
                               $error = $global_error_names{\'DIVBYZERO\'};
                               return;
                            }
                            $value2 = 1 / $value2;
                            if (!($value1 == 0 || $value2 == 0)) {
                               if (log10(abs($value1)) + log10(abs($value2)) > MAXSIZE) {
                                  $error =$global_error_names{\' OUTOFRANGE\'};
                                  return;
                               }
                            }
                            $error = $global_error_names{\'NOERROR\'};
                            return $value1 * $value2;'
                         
)
         )
      ),
      array( 
# Pr"azedenz 4 => niedrigste
         
'+'    => array(
            
'deriv'   => array('b''+'D_FIRST_VARD_SECOND_VAR),
            
'name'    => 'Addition',
            
'info'    => "keine Information vorhanden",
            
'example' => "5 + 3 = 8",
            
'eval'    => create_function('$value1, $value2, &$error',
                           
'global $global_error_names;' "\n" .
                           
'if (!($value1 == 0 || $value2 == 0) && $value1 / $value2 > 0) {
                               if (abs(log10(abs($value1)) - log10(abs($value2))) < 0.01) {
                                  if (2 * log10(abs($value1)) > MAXSIZE) {
                                     $error = $global_error_names{\'OUTOFRANGE\'};
                                     return;
                                  }
                               }
                            }
                            $error = $global_error_names{\'NOERROR\'};
                            return $value1 + $value2;'
                         
)
         ),
         
'-'    => array(
            
'deriv'   => array('b''-'D_FIRST_VARD_SECOND_VAR),
            
'name'    => 'Subtraktion',
            
'info'    => "keine Information vorhanden",
            
'example' => "5 - 3 = 2",
            
'eval'    => create_function('$value1, $value2, &$error',
                           
'global $global_error_names;' "\n" .
                           
'$value2 = -$value2;
                            if (!($value1 == 0 || $value2 == 0) && $value1 / $value2 > 0) {
                               if (abs(log10(abs($value1)) - log10(abs($value2))) < 0.01) {
                                  if (2 * log10(abs($value1)) > MAXSIZE) {
                                     $error = $global_error_names{\'OUTOFRANGE\'};
                                     return;
                                  }
                               }
                            }
                            $error = $global_error_names{\'NOERROR\'};
                            return $value1 + $value2;'
                         
)
         )
      )
   );

?>

Datei units/parser.php:

<?php

   
####################################################################################
   # Dies ist die Datei 'parser.php'                                                  #
   #                                                                                  #
   # Sie enth"alt den Parser des Parser/Plotter-Projekts                              #
   #                                                                                  #
   # Diese Datei darf frei als Ganzes oder in Teilen f"ur jegliche nicht-             #
   # kommerzielle Zwecke verwandt werden, solange folgede Bedingungen erf"ullt        #
   # werden:                                                                          #
   #    - Dieser Blockkommentar mit den Nutzungsbedingungen muss unver"andert         #
   #      in allen Nachfolgedateien / -ver"offentlichungen am Datei- / Textkopf       #
   #      verwandt werden                                                             #
   #    - Der Quellcode des muss jedem Benutzer von allen Programmen, die ihn         #
   #      verwenden, einsehbar gemacht werden                                         #
   #                                                                                  #
   # Sollten Sie diesen Code, in Teilen oder als Ganzes, auch portiert in             #
   # andere Programmiersprachen oder unter blo"ser Verwendung des Algorithmus         #
   # oder von Teilen von verwandten Algorithmen, f"ur kommerzielle Zwecke nutzen      #
   # wollen, so kontaktieren Sie mich bitte.                                          #
   #                                                                                  #
   # Ich habe den vorliegenden Code von Grund auf selbst programmiert und mich        #
   # dabei auf keine anderen als Standardalgorithmen gest"utzt. Insbesondere den      #
   # Tokenizer, der Parser und die Schrittweitensteurerung habe ich von Grund         #
   # auf und ohne Zuhilfenahme anderer Quellen selbst programmiert. Sollte ich        #
   # mit dem vorliegenden Code bestehende Copyrights oder Patente verletzen oder      #
   # den Urheber geistigen Eigentums vorenthalten, so geschieht dies                  #
   # unabsichtlich. Bitte kontaktieren Sie mich mittels untenstehender E-Mail-        #
   # Adresse oder "uber den Sysadmin.                                                 #
   #                                                                                  #
   # Der Autor "ubernimmt keine Haftung f"ur eventuelle durch die Nutzung dieses      #
   # entstehende oder entstandene mittelbare oder unmittelbare Sch"aden jedweder Art. #
   # Nutzung auf eigene Gefahr.                                                       #
   #                                                                                  #
   # Bitte schicken Sie mir keine E-Mails mit Bitte um die Erkl"arung der             #
   # Funktionsweise des Codes oder von Teilen des Codes; ich habe mich bem"uht,       #
   # den Code so gut wie m"oglich zu kommentieren und habe leider nicht genug         #
   # Zeit, um E-Mails "uber technische Details zu beantworten.                        #
   #                                                                                  #
   # (c) Jan Olligs, 2004                                                             #
   # Alle Rechte vorbehalten                                                          #
   #                                                                                  #
   # Jan.Olligs@gmx.net                                                               #
   ####################################################################################

   ####################################################################################
   #                               Fehlerdeklarationen (global)                       #
   ####################################################################################

   
$global_errors = array(
      
=> 'NOERROR',
      
=> 'ANYERROR',
      
=> 'DIVBYZERO',
      
=> 'OUTOFRANGE',
      
=> 'NOSUCHFUNC',
      
=> 'PARSEERR',
      
=> 'NOSUCHTYPE',
      
=> 'NOTANUMBER'
   
);

   
$global_error_names array_flip($global_errors);

   
####################################################################################
   # Funktion  : error_text                                                           #
   # Zweck     : Wandelt Fehlernummer in Fehlertext um                                #
   # Eingabe   : Fehlernummer         - $err_num                                      #
   # Ausgabe   : Fehlermeldung als String                                             #
   ####################################################################################

   
function error_text($err_num) {
      global 
$global_errors;
      switch (
$global_errors{$err_num}) {
         case (
'NOERROR'):
            return 
'Kein Fehler.';
         case (
'DIVBYZERO'):
            return 
'Division durch Null.';
         case (
'OUTOFRANGE'):
            return 
'Wert nicht in der Definitionsmenge.';
         case (
'NOSUCHFUNC'):
            return 
'Funktion existiert nicht.';
         case (
'PARSEERR'):
            return 
'Fehler beim Parsen.';
         case (
'NOSUCHTYPE'):
            return 
'Interner Fehler: Unbekannter Typ.';
         case (
'NOTANUMBER'):
            return 
'Zahl erwartet, aber nicht vorgefunden.';
         case (
'ANYERROR'):
         default:
            return 
'Unbekannter Fehler.';
      }
   }

   
####################################################################################
   # Hinweis: Die Ausgabe erfolgt , soweit nicht anders angegeben, immer in der Form  #
   #          Array: 0 => Eigentliche Ausgabe, 1 => Fehlernummer                      #
   ####################################################################################

   ####################################################################################
   # Funktion  : check_parens                                                         #
   # Zweck     : "Uberpr"uft, ob Klammern in einem Ausdruck "passen"                  #
   # Eingabe   : Term als String      - $term                                         #
   #             Array mit Klammern   - $parens                                       #
   # Ausgabe   : Stringindex, an dem der Fehler ist, ansonsten -1                     #
   # Sonstiges : - Array mit Klammern in der Form (("offnend, schlie"send), ...)      #
   #             - KEINE ARRAYAUSGABE                                                 #
   ####################################################################################

   
function check_parens($term$parens) {
      
$temp_stack = array();
      for (
$i 0$i strlen($term); ++$i) {
         
$char $term{$i}; # hole Zeichen $i
         
for ($j 0$j count($parens); ++$j) {
            if (
$char == $parens[$j][0]) {  # falls $char eine "offnende
                                            # Klammer enth"alt
               
array_push($temp_stack$j); # pushe Wert auf Stack ...
               
break;                       # ... und fahre fort
            
} elseif ($char == $parens[$j][1]) { # falls $char eine schlie"sende
                                                 # Klammer enth"alt
               
if (count($temp_stack) < 1) {
                  return 
$i;
               }
               
$other array_pop($temp_stack);  # hole letzten Klammerwert vom Stack
               
if ($other == $j) { # falls "offenende und schlie"sender Klammer passen
                  
break;           # n"achstes Zeichen
               
} else {            # sonst
                  
return $i;       # gib Fehlerstelle zur"uck
               
}
            }
         }
      }
      if (
count($temp_stack) > 0) { # wenn der Stack nicht leer ist ...
         
return strlen($term);      # liegt der Fehler am Ende des Strings
      
}
      return -
1# kein Fehler
   
}

   
####################################################################################
   # Funktion  : check_minus                                                          #
   # Zweck     : Wandelt '-' als Vorzeichen in '0 - ' um                              #
   # Eingabe   : Term als String                 - $term                              #
   #             Array mit Klammern              - $parens                            #
   # Ausgabe   : Bearbeiteter Term als String                                         #
   # Sonstiges : Array mit Klammern in der Form (("offnend, schlie"send), ...)        #
   ####################################################################################

   
function check_minus($term$parens) {
      global 
$global_error_names;
      
# - wird nur am Stringanfang und vor "offnender Klammer umgewandelt
      
$new_term '';
      
$opening = array();  # Array mit "offnenden Klammern als Indices
      
foreach ($parens as $pair) {
         
$opening[$pair[0]] = $pair[1];
      }
      
preg_replace('/\s+/'' '$term); # ersetze whitespace durch Leerzeichen
      
for ($i strlen($term) - 1$i >= 0; --$i) { # parse String von hinten nach vorne
         
$char $term{$i}; # hole dir aktuelles Zeichen
         
if ($char != '-') {  # Wenn das Zeichen kein Minuszeichen ist ...
            
$new_term $char $new_term# ... fahre fort
         
} else {             # sonst:
            
if ($i == 0) {    # am Stringanfang:
               
$new_term '0 - ' $new_term# Null hinzuf"ugen ...
               
break;   # ... und tsch"uss
            
}
            --
$i# sonst: betrachte Zeichen davor
            
if ($term{$i} == ' ') { # falls es ein Leerzeichen ist ...
               
if ($i == 0) { # falls es der Stringanfang war ...
                  
$new_term '0 - ' $new_term# verfahre wie oben
                  
break;
               } else { 
# sonst
                  
--$i# betrachte das n"achste nicht-Leerzeichen
               
}
            }
            if (
array_key_exists($term{$i}, $opening)) {
               
# falls es eine "offnende Klammer ist ...
               
$new_term $term{$i} . ' 0 - ' $new_term# stelle eine '0' vor Minus
            
} else { # sonst
               
$new_term $term{$i} . ' - ' $new_term# fahre fort
            
}
         }
      }
      return array(
$new_term$global_error_names{'NOERROR'});
   }

   
####################################################################################
   # Funktion  : add_times                                                            #
   # Zweck     : F"ugt Malzeichen zwischen Zahlen und anderen Objekten                #
   #             hinzu (implizite Multiplikation)                                     #
   # Eingabe   : Term als String                 - $term                              #
   #             M"ogliche n"achste Zeichen      - $poss                              #
   #             Verwandtes Malzeichen           - $times                             #
   # Ausgabe   : Bearbeiteter Term als String                                         #
   # Sonstiges : - $times sollte normalerweise '*' sein ...                           #
   #             - $times darf nur aus einem Zeichen bestehen                         #
   #             - Es wir nur ein Malzeichen gesetzt, wenn das n"achste Zeichen       #
   #               aus $poss ist (normalerweise "offnende Klammern und a-z, A-Z)      #
   ####################################################################################

   
function add_times($term$poss$times) {
      global 
$global_error_names;
      
$new_term '';
      if (
strlen($term) > 0) {
         
$char2 $term{0};
      } else {
         
$char2 '0';                 
      }
      for (
$i 0$i strlen($term) - 1; ++$i) {
         
$char1 $term{$i};     # hole Zeichen $i
         
$char2 $term{$i 1}; # hole Zeichen ($i + 1)
         
$new_term .= $char1;
         if (
ctype_digit($char1) or $char1 == '.') { # m"ogliches Zahlenende
            
if (in_array($char2$poss)) { # und Substitution erw"unscht
               
$new_term .= $times;
            }
         }
      }
      
$new_term .= $char2;
      return array(
$new_term$global_error_names{'NOERROR'});
   }

   
####################################################################################
   # Funktion  : tokenize                                                             #
   # Zweck     : Zerlegt Term als String in tokens                                    #
   # Eingabe   : Term als String                 - $string                            #
   #             Array mit Klammern              - $parens                            #
   #             Un"are Operatoren (Funktionen)  - $unary                             #
   #             Bin"are Operatoren (Operatoren) - $binary                            #
   # Ausgabe   : Tokenliste als Array                                                 #
   # Sonstiges : - Array mit Klammern in der Form (("offnend, schlie"send), ...)      #
   #             - F"ur Operatorsyntax siehe mathdef.php                              #
   #             - $constants sollte auch Variablen enthalten                         #
   ####################################################################################

   
function tokenize($string$parens$unary$binary) {
      global 
$global_error_names;
      
# tokens auf whitespace trennen
      
$tokens preg_split('/\s+/'$string, -1PREG_SPLIT_NO_EMPTY);

      
# Nur Ein-Zeichen-Operatoren k"onnen aus einem String ohne whitespace erkannt
      # werden, alle anderen Operatoren sollten durch Leerzeichen oder Klammern
      # getrennt sein. Wir d"urfen wegen Funktionen wie tan2 nicht auf Zahlen trennen.
      # Deshalb suchen wir jetzt Ein-Zeichen-Operatoren
      
$one_char_ops = array();
      foreach (
$unary as $name => $others) {
         if (
strlen($name) == 1) {
            
array_push($one_char_ops$name);
         }
         foreach (
$others['others'] as $alternative) {
            if (
strlen($alternative) == 1) {
               
array_push($one_char_ops$alternative);
            }
         }
      }
      foreach (
$binary as $level) {
         foreach (
$level as $name => $rest) {
            if (
strlen($name) == 1) {
               
array_push($one_char_ops$name);
            }
         }
      }

      
# Splitten um Ein-Zeichen-Ops
      
for ($i count($tokens) - 1$i >= 0; --$i) {
         
# tokens r"uckw"arts durchgehen, da wir einzelne tokens durch mehrere tokens
         # ersetzen; sonst Probleme mit dem Offset
         
$chunk = array($tokens[$i]);
         foreach (
$one_char_ops as $operator) { # alle Ops durchgehen
            
$regex '/(' preg_quote($operator'/') . ')/';
            for (
$j count($chunk) - 1$j >= 0; --$j) {
               
$temp preg_split($regex$chunk[$j], -1,
                                  
PREG_SPLIT_NO_EMPTY PREG_SPLIT_DELIM_CAPTURE);
               
array_splice($chunk$j1$temp);
            }
         }
         
array_splice($tokens$i1$chunk);
      }

      
# Jetzt kann noch um schlie"sende Klammern und nach "offnenden Klammern ge-
      # splittet werden, nicht jedoch vor "offnenden Klammern, da sie zu Funktionen
      # geh"oren k"onnten.

      # um schlie"sende Klammern splitten
      
foreach ($parens as $open_close) {
         
$regex '/(' preg_quote($open_close[1]) . ')/';
         for (
$i count($tokens) - 1$i >= 0; --$i) { # alle tokens durchgehen
            
$temp preg_split($regex$tokens[$i], -1,
                               
PREG_SPLIT_NO_EMPTY PREG_SPLIT_DELIM_CAPTURE);
            
array_splice($tokens$i1$temp);
         }
      }

      
# vor "offnende Klammern splitten
      
$opening = array(); # Array mit "offnenden Klammern als Indices
      
foreach ($parens as $open_close) {
         
$opening[$open_close[0]] = 1;
      }
      for (
$i count($tokens) - 1$i >= 0; --$i) { # alle tokens durchgehen
         
$sub_tokens = array($tokens[$i]);
         
$j strlen($tokens[$i]) - 2;
            
# "offnende Klammer am Ende des Strings ist nicht interessant
         
while ($j > -1) { # bis zum Anfang des Strings
            
$temp $sub_tokens[0]; # token extrahieren
            
if (array_key_exists($temp{$j}, $opening)) {
               
# wenn Zeichen $j "offnende Klammer ist
               
array_splice($sub_tokens01,
                            array(
substr($temp0$j 1), substr($temp$j 1)));
                  
# nach der Klammer splitten
            
}
            --
$j;
         }
         
array_splice($tokens$i1$sub_tokens);
      }

      return array(
$tokens$global_error_names{'NOERROR'});
   }

   
####################################################################################
   # Funktion  : substitute                                                           #
   # Zweck     : Ersetzt Tokens durch ihre Werte                                      #
   # Eingabe   : Tokenliste      - $tokens                                            #
   #             Werteliste      - $values                                            #
   # Ausgabe   : Bearbeitete Tokenliste                                               #
   # Sonstiges : - Tokenliste kann z.B. auch Stack sein                               #
   #             - Werteliste als Hash in der Form ('pi' => 3.14, 'e' => '2.72', ...) #
   ####################################################################################

   
function substitute($tokens$values) {
      global 
$global_error_names;
      for (
$i 0$i count($tokens); ++$i) { # gehe alle tokens der Reihe nach durch
         
if (array_key_exists($tokens[$i], $values)) { # wenn token eine Konstante ist
            
$tokens[$i] = $values[$tokens[$i]];        # substitiere
            
if (!$tokens[$i]) {
               
$tokens[$i] = '0';
            } else {
               
settype($tokens[$i], "string");
            }
         }
      }
      return array(
$tokens$global_error_names{'NOERROR'});
   }

   
####################################################################################
   # Funktion  : build_tree                                                           #
   # Zweck     : Bldet aus einer Tokenliste einen parse tree                          #
   # Eingabe   : Tokenliste                      - $tokens                            #
   #             Array mit Klammern              - $parens                            #
   #             Un"are Operatoren (Funktionen)  - $unary                             #
   #             Bin"are Operatoren (Operatoren) - $binary                            #
   # Ausgabe   : Array: einziges Element: parse tree als vernestetes Array            #
   # Sonstiges : - Array mit Klammern in der Form (("offnend, schlie"send), ...)      #
   #             - F"ur Operatorsyntax siehe mathdef.php                              #
   #             - parse tree Knoten: Array: 1 => Typ, 2 => Wert, 3, 4 => Kinder      #
   #                - Typ: 'u' - un"ar, 'b' - bin"ar                                  #
   #                - Bei Wert kein Array, sondern einfach Wert                       #
   #                - Bei un"arem Operator ist 4 don't care                           #
   ####################################################################################

   
function build_tree($tokens$parens$unary$binary) {
      global 
$global_error_names;

      
# Pr"azedenz: Klammern, un"are Operatoren, bin"are Operatoren, links-rechts
      # niedrigste Pr"azedenz ist im parse tree am weitesten oben

      # Zuerst nach Klammern (incl. un"are Operatoren) parsen
      
$alt_parens = array();
      
$opening    = array();
      foreach (
$parens as $open_close) {
         
$opening[$open_close[0]] = $open_close[1];
         
$alt_parens[$open_close[0]] = $open_close[1];
         
$alt_parens[$open_close[1]] = $open_close[0];
      }
      
$paren_stack = array();
      for (
$i 0$i count($tokens); ++$i) {
         if (
array_key_exists($tokens[$i]{strlen($tokens[$i]) - 1}, $alt_parens)) {
            
array_push($paren_stack, array($tokens[$i]{strlen($tokens[$i]) - 1}, $i));
         }
      }
      
$temp_paren_stack = array();
      while (
count($paren_stack) > 0) { # Klammern unter den tokens
         
if (array_key_exists($paren_stack[count($paren_stack) - 1][0], $opening)) {
            if (
count($temp_paren_stack) == 0) {
               return array(
''$global_error_names{'PARSEERR'});
            }
            if (
$opening[$paren_stack[count($paren_stack) - 1][0]]
                == 
$temp_paren_stack[count($temp_paren_stack) - 1][0]) {
               if (
count($temp_paren_stack) > 1) {
                  
array_pop($paren_stack);
                  
array_pop($temp_paren_stack);
               } elseif (
count($temp_paren_stack) != 1) {
                   return array(
''$global_error_names{'PARSEERR'});
               } else {
                  
array_push($temp_paren_stackarray_pop($paren_stack));
                  
$temp_tokens array_slice(
                     
$tokens,
                     
$temp_paren_stack[1][1],
                     
$temp_paren_stack[0][1] - $temp_paren_stack[1][1] + 1
                  
);
                  
$temp_tree build_tree(
                                  
array_slice($temp_tokens1count($temp_tokens) - 2),
                                  
$parens$unary$binary
                               
);
                  if (
$temp_tree[1] != $global_error_names{'NOERROR'}) { # Im Fall eines Fehlers
                     
return array(''$temp_tree[1]);
                  }
                  if (
strlen($temp_tokens[0]) == 1) { # Nur Klammern
                     
array_splice(
                        
$tokens,
                        
$temp_paren_stack[1][1],
                        
$temp_paren_stack[0][1] - $temp_paren_stack[1][1] + 1,
                        
$temp_tree[0]
                     );
                  } else { 
# un"arer Operator
                     
array_splice(
                        
$tokens,
                        
$temp_paren_stack[1][1],
                        
$temp_paren_stack[0][1] - $temp_paren_stack[1][1] + 1,
                        
'dummy'
                     
);
                     
$tokens[$temp_paren_stack[1][1]] = array(
                        
'u',
                        
substr($temp_tokens[0], 0strlen($temp_tokens[0]) - 1),
                        
$temp_tree[0][0]
                     );
                  }
                  
array_pop($temp_paren_stack);
                  
array_pop($temp_paren_stack);
               }
            } else {
               return array(
''$global_error_names{'PARSEERR'});
            }
         } else {
            
array_push($temp_paren_stackarray_pop($paren_stack));
         }
      }
      if (
count($temp_paren_stack) > 0) {
         return array(
''$global_error_names{'PARSEERR'});
      }
      
# jetzt die bin"aren Operatoren
      
foreach ($binary as $prec_level) {
         
# und die tokens durchgehen
         
for ($i 1$i count($tokens) - 1; ++$i) {
            if (!
is_array($tokens[$i]) and array_key_exists($tokens[$i], $prec_level)) {
               
array_splice(
                  
$tokens,
                  
$i 1,
                  
3,
                  array(array(
'b'$tokens[$i], $tokens[$i 1], $tokens[$i 1]))
               );
               --
$i;
            }
         }
      }
      if (!
is_array($tokens)) {
         return array(
''$global_error_names{'PARSEERR'});
      }
      if (
count($tokens) != 1) {
         return array(
''$global_error_names{'PARSEERR'});
      }
      if (!
is_array($tokens[0])) {
         
$tokens[0] = array($tokens[0]);
      }

      return array(
$tokens$global_error_names{'NOERROR'});
   }

   
####################################################################################
   # Funktion  : build_stack                                                          #
   # Zweck     : Bildet Stack aus parse tree                                          #
   # Eingabe   : Tree            - $tree                                              #
   # Ausgabe   : Stack als Array                                                      #
   ####################################################################################

   
function build_stack($tree) {
      global 
$global_error_names;
      
$stack = array(); # Ergebnisstack
      
if (!is_array($tree)) { # Konstante / Variable
         
return array(array($tree), $global_error_names{'NOERROR'});
         break;
      }
      switch (
$tree[0]) {
         case 
'u'# un"arer Operator
            
$first build_stack($tree[2]); # hole dir Stack des Arguments
            
if ($first[1] != $global_error_names{'NOERROR'}) { # Im Fall eines Fehlers
               
return array(''$first[1]); # schlage Alarm
            
}
            
# bilde Stack
            
$stack array_merge($stack$tree[1], $first[0]);
            return array(
$stack$global_error_names{'NOERROR'});
            break;
         case 
'b'# bin"arer Operator
            
$first build_stack($tree[2]); # hole dir Stack des ersten Arguments
            
if ($first[1] != $global_error_names{'NOERROR'}) { # Im Fall eines Fehlers
               
return array(''$first[1]); # schlage Alarm
            
}
            
$second build_stack($tree[3]); # hole dir Stack des zweiten Arguments
            
if ($second[1] != $global_error_names{'NOERROR'}) { # Im Fall eines Fehlers
               
return array(''$second[1]); # schlage Alarm
            
}
            
# bilde Stack
            
$stack array_merge($stack$tree[1], $first[0], $second[0]);
            return array(
$stack$global_error_names{'NOERROR'});
            break;
         default : 
# Konstante / Variable
            
return array(array($tree[0]), $global_error_names{'NOERROR'});
            break;
      }
   }

   
####################################################################################
   # Funktion  : process_stack                                                        #
   # Zweck     : F"uhrt die Berechnung an einem Stack durch                           #
   # Eingabe   : Stack                           - $stack                             #
   #             Un"are Operatoren (Funktionen)  - $unary                             #
   #             Bin"are Operatoren (Operatoren) - $binary                            #
   # Ausgabe   : Wert                                                                 #
   ####################################################################################

   
function process_stack($stack$unary$binary) {
      global 
$global_error_names;
      
$result_stack = array(); # tempor"arer Stack f"ur Ergebnisse

      
$unary_lookup = array(); # um alternative Schreibweisen zu konvertieren
      
foreach ($unary as $key => $definition) {
         if (!
is_array($definition)) { continue; } # ACHTUNG: Das w"are ein Fehler in der
                                                   # Implementierung
         
$unary_lookup[$key] = $key# der Operator entspricht sich selbst
         
foreach($definition['others'] as $alternative) {
            
$unary_lookup[$alternative] = $key;
         }
      }

      
$binary_lookup = array(); # um Pr"azedenz festzustellen
      
$precedence 0;
      foreach (
$binary as $level) {
         if (!
is_array($level)) { # ACHTUNG: Das w"are ein Fehler in der
            
++$precedence;        # Implementierung
            
continue;
         }
         foreach (
$level as $operator => $dummy) {
            if (!
is_array($dummy)) { # ACHTUNG: Das w"are ein Fehler in der
               
continue;             # Implementierung
            
}
            
$binary_lookup[$operator] = $precedence;
         }
         ++
$precedence;
      }

      while (
count($stack) > 0) {
         
$current array_pop($stack);
         if (
array_key_exists($current$unary_lookup))  { # un"arer Operator
            
$argument1 array_pop($result_stack);
            
$result $unary{$unary_lookup{$current}}{'eval'}($argument1$error);
            if (
$error != $global_error_names{'NOERROR'}) {
               return array(
''$error);
            }
            
array_push($result_stack$result);
         } elseif (
array_key_exists($current$binary_lookup)) { # bin"arer Operator
            
$argument1 array_pop($result_stack);
            
$argument2 array_pop($result_stack);
            
$result $binary{$binary_lookup{$current}}{$current}{'eval'}($argument1$argument2$error);
            if (
$error != $global_error_names{'NOERROR'}) {
               return array(
''$error);
            }
            
array_push($result_stack$result);
         } else { 
# Zahl (hoffentlich!)
            
if (!is_numeric($current)) {
               return array(
''$global_error_names{'NOTANUMBER'});
            }
            
array_push($result_stack$current);
         }
      }

      if (
count($result_stack) != 1) {
         return array(
''$global_error_names{'ANYERROR'});
      }
      return array(
$result_stack[0], $global_error_names{'NOERROR'});
   }


?>

Datei units/graphics.php:

<?php

   
####################################################################################
   # Dies ist die Datei 'graphics.php'                                                #
   #                                                                                  #
   # Sie enth"alt Methoden f"ur die Grafik des Plotters (Achsen, Plotten, etc.) des   #
   # Parser/Plotter-Projekts                                                          #
   #                                                                                  #
   # Diese Datei darf frei als Ganzes oder in Teilen f"ur jegliche nicht-             #
   # kommerzielle Zwecke verwandt werden, solange folgede Bedingungen erf"ullt        #
   # werden:                                                                          #
   #    - Dieser Blockkommentar mit den Nutzungsbedingungen muss unver"andert         #
   #      in allen Nachfolgedateien / -ver"offentlichungen am Datei- / Textkopf       #
   #      verwandt werden                                                             #
   #    - Der Quellcode des muss jedem Benutzer von allen Programmen, die ihn         #
   #      verwenden, einsehbar gemacht werden                                         #
   #                                                                                  #
   # Sollten Sie diesen Code, in Teilen oder als Ganzes, auch portiert in             #
   # andere Programmiersprachen oder unter blo"ser Verwendung des Algorithmus         #
   # oder von Teilen von verwandten Algorithmen, f"ur kommerzielle Zwecke nutzen      #
   # wollen, so kontaktieren Sie mich bitte.                                          #
   #                                                                                  #
   # Ich habe den vorliegenden Code von Grund auf selbst programmiert und mich        #
   # dabei auf keine anderen als Standardalgorithmen gest"utzt. Insbesondere den      #
   # Tokenizer, der Parser und die Schrittweitensteurerung habe ich von Grund         #
   # auf und ohne Zuhilfenahme anderer Quellen selbst programmiert. Sollte ich        #
   # mit dem vorliegenden Code bestehende Copyrights oder Patente verletzen oder      #
   # den Urheber geistigen Eigentums vorenthalten, so geschieht dies                  #
   # unabsichtlich. Bitte kontaktieren Sie mich mittels untenstehender E-Mail-        #
   # Adresse oder "uber den Sysadmin.                                                 #
   #                                                                                  #
   # Der Autor "ubernimmt keine Haftung f"ur eventuelle durch die Nutzung dieses      #
   # entstehende oder entstandene mittelbare oder unmittelbare Sch"aden jedweder Art. #
   # Nutzung auf eigene Gefahr.                                                       #
   #                                                                                  #
   # Bitte schicken Sie mir keine E-Mails mit Bitte um die Erkl"arung der             #
   # Funktionsweise des Codes oder von Teilen des Codes; ich habe mich bem"uht,       #
   # den Code so gut wie m"oglich zu kommentieren und habe leider nicht genug         #
   # Zeit, um E-Mails "uber technische Details zu beantworten.                        #
   #                                                                                  #
   # (c) Jan Olligs, 2004                                                             #
   # Alle Rechte vorbehalten                                                          #
   #                                                                                  #
   # Jan.Olligs@gmx.net                                                               #
   ####################################################################################

   ####################################################################################
   # Funktion  : init_plot                                                            #
   # Zweck     : Zeichnet in eine GD-Bild Hintergrund, Achsen und Gitterlinien        #
   # Eingabe   : Bild als GD-Grafik         - $image,                                 #
   #             Breite des Bildes          - $width,                                 #
   #             H"ohe des Bildes           - $height,                                #
   #             kleinster x-Wert           - $xmin,                                  #
   #             gr"o"ster x-Wert           - $xmax,                                  #
   #             x-Gitterweite              - $xgrid,                                 #
   #             kleinster y-Wert           - $ymin,                                  #
   #             gr"o"ster y-Wert           - $ymax,                                  #
   #             y-Gitterweite              - $ygrid,                                 #
   #             Hintergrundfarbe           - $back,                                  #
   #             Achsenfarbe                - $axes,                                  #
   #             Farbe der Gitterlinien     - $grid                                   #
   # Ausgabe   : Bearbeitetes Bild                                                    #
   # Sonstiges : Farben sind dem Bild zugeordnete GD-Farben                           #
   ####################################################################################

   
function init_plot($image$width$height$xmin$xmax$xgrid,
      
$ymin$ymax$ygrid$back$axes$grid) {
      
# Hintergrund bemalen
      
ImageFilledRectangle(
         
$image,
         
0,
         
0,
         
$width 1,
         
$height 1,
         
$back
      
);

      
# Gitterlinien zeichnen
      # parallel zur x-Achse
      
if ($ygrid 0) {
         for (
$y $ygrid$y <= $ymax$y += $ygrid) {
            
ImageLine(
               
$image,
               
0,
               (
$ymax $y) * ($height 1) / ($ymax $ymin),
               
$width 1,
               (
$ymax $y) * ($height 1) / ($ymax $ymin),
               
$grid
            
);
         }
         for (
$y = -$ygrid$y >= $ymin$y -= $ygrid) {
            
ImageLine(
               
$image,
               
0,
               (
$ymax $y) * ($height 1) / ($ymax $ymin),
               
$width 1,
               (
$ymax $y) * ($height 1) / ($ymax $ymin),
               
$grid
            
);
         }
      }

      
# parallel zur y-Achse
      
if ($xgrid 0) {
         for (
$x $xgrid$x <= $xmax$x += $xgrid) {
            
ImageLine(
               
$image,
               (
$x $xmin) * ($width 1) / ($xmax $xmin),
               
0,
               (
$x $xmin) * ($width 1) / ($xmax $xmin),
               
$height 1,
               
$grid
            
);
         }
         for (
$x = -$xgrid$x >= $xmin$x -= $xgrid) {
            
ImageLine(
               
$image,
               (
$x $xmin) * ($width 1) / ($xmax $xmin),
               
0,
               (
$x $xmin) * ($width 1) / ($xmax $xmin),
               
$height 1,
               
$grid
            
);
         }
      }

      
# Achsen zeichnen
      # x-Achse
      
ImageLine(
         
$image,
         
0,
         
$ymax * ($height 1) / ($ymax $ymin),
         
$width 1,
         
$ymax * ($height 1) / ($ymax $ymin),
         
$axes
      
);
      
# y-Achse
      
ImageLine(
         
$image,
         (-
$xmin) * ($width 1) / ($xmax $xmin),
         
0,
         (-
$xmin) * ($width 1) / ($xmax $xmin),
         
$height 1,
         
$axes
      
);
      return 
$image;
   }

   
####################################################################################
   # Funktion  : plot_graph                                                           #
   # Zweck     : Zeichnet Graphen aus Array von Punkten in ein GD-Bild                #
   # Eingabe   : Bild als GD-Grafik         - $image,                                 #
   #             Breite des Bildes          - $width,                                 #
   #             H"ohe des Bildes           - $height,                                #
   #             kleinster x-Wert           - $xmin,                                  #
   #             gr"o"ster x-Wert           - $xmax,                                  #
   #             kleinster y-Wert           - $ymin,                                  #
   #             gr"o"ster y-Wert           - $ymax,                                  #
   #             Array mit Punkten          - $points                                 #
   #             Graphenfarbe               - $color,                                 #
   # Ausgabe   : Bearbeitetes Bild                                                    #
   # Sonstiges : - Farben sind dem Bild zugeordnete GD-Farben                         #
   #             - Punkte in der Form (x => (y, Fehlernummer), ...)                   #
   ####################################################################################

   
function plot_graph($image$width$height$xmin$xmax,
      
$ymin$ymax$points$color) {
      global 
$global_error_names;
      
$lastx 0;      # zuletzt bearbeiteter x-Wert
      
$lasty 0;      # zuletzt bearbeiteter y-Wert
      
$undef true;   # letzter Wert war nicht definiert / Fehler
      
$range false;  # letzter Wert war au"serhalb des Bereichs
      
ksort($pointsSORT_NUMERIC); # Punkte nach x-Werten sortieren ...
      
reset($points);               # ... und Arrayz"ahler zur"ucksetzen
      
foreach ($points as $x => $content) {
         
# y-Wert und Fehlertyp extrahieren
         
$y     $content[0];
         
$error $content[1];
         if (
$error != $global_error_names{'NOERROR'}) { # Wenn ein Fehler vorliegt
            
$undef true;
            
$range false;
         } else { 
# Kein Fehler
            
if (!$undef) { # Letzter Wert war definiert
               
if ($xmin <= $x and $x <= $xmax and $ymin <= $y and $y <= $ymax) {
                  
# Punkt im Bereich, alles in Ordnung
                  
ImageLine(
                     
$image,
                     (
$lastx $xmin) * ($width 1) / ($xmax $xmin),
                     (
$ymax $lasty) * ($height 1) / ($ymax $ymin),
                     (
$x $xmin) * ($width 1) / ($xmax $xmin),
                     (
$ymax $y) * ($height 1) / ($ymax $ymin),
                     
$color
                  
);
                  
$range false;
               } else { 
# Punkt au"serhalb des Bereiches
                  
if (!$range) { # der letzte aber nicht, also zeichnen
                     
ImageLine(
                        
$image,
                        (
$lastx $xmin) * ($width 1) / ($xmax $xmin),
                        (
$ymax $lasty) * ($height 1) / ($ymax $ymin),
                        (
$x $xmin) * ($width 1) / ($xmax $xmin),
                        (
$ymax $y) * ($height 1) / ($ymax $ymin),
                        
$color
                     
);
                  }
                  
$range true;
               }
            } else { 
# Letzter Wert war nicht definiert
               
$undef false;
               if (
$xmin <= $x and $x <= $xmax and $ymin <= $y and $y <= $ymax) {
                  
$range false;
               } else {
                  
$range true;
               }
            }
         }
         
$lastx $x;
         
$lasty $y;
      }
      return 
$image;
   }

   
####################################################################################
   # Funktion  : generate_points                                                      #
   # Zweck     : Berechnet Punkte aus den x-Werten.                                   #
   # Eingabe   : Funktion als Stack         - $function,                              #
   #             x-Werte als Array          - $x_values,                              #
   #             Konstanten                 - $constants                              #
   # Ausgabe   : Punkte                                                               #
   # Sonstiges : - Punkte in der Form (x => (y, Fehlernummer), ...)                   #
   ####################################################################################

   
function generate_points($function$x_values$constants) {
      global 
$global_error_names;
      global 
$global_errors;
      global 
$global_unary_operators;
      global 
$global_binary_operators;

      
$results = array();

      
# Konstantensubstitution
      
$temp substitute($function$constants);
      if (
$temp[1] != $global_error_names['NOERROR']) {
         return array(array(
0$temp[1]));
      }
      
$function $temp[0];

      foreach (
$x_values as $x) {
         
$temp substitute($function, array('x' => $x));
         if (
$temp[1] != $global_error_names['NOERROR']) {
            return array(array(
0$temp[1]));
         }
         
$temp $temp[0];
         
$temp process_stack($temp$global_unary_operators$global_binary_operators);
         switch (
$global_errors{$temp[1]}) {
            case (
'NOSUCHFUNC'): # diese Fehler k"onnen nicht
            
case ('PARSEERR'):   # aufgrund eines fehlerhaften
            
case ('NOSUCHTYPE'): # Wertes auftreten
            
case ('NOTANUMBER'):
               return array(array(
0$temp[1]));
         }
         
$results["$x"] = $temp;
      }
      return 
$results;
   }

   
####################################################################################
   # Funktion  : fixed_step                                                           #
   # Zweck     : Berechnet Punkte mit festem delta x.                                 #
   # Eingabe   : Funktion als Stack         - $function,                              #
   #             kleinster x-Wert           - $xmin,                                  #
   #             gr"o"ster x-Wert           - $xmax,                                  #
   #             Schrittweite               - $step,                                  #
   #             Konstanten                 - $constants                              #
   # Ausgabe   : Punkte                                                               #
   # Sonstiges : - Punkte in der Form (x => (y, Fehlernummer), ...)                   #
   #             - Anfangs- und Endwert sind immer in der Ausgabe enthalten           #
   ####################################################################################

   
function fixed_step($function$xmin$xmax$step$constants) {
      global 
$global_error_names;

      
# Fehler in den Parametern -- keine Chance au"Ser f"ur Hellseher
      
if ($step == or $xmin == $xmax ) {
         return array(array(
0$global_error_names{'OUTOFRANGE'}));
      }

      
# Minimum und Maximum vertauscht; wir machen es r"uckg"angig
      
if ($xmin $xmax) {
         
$temp $xmin;
         
$xmin $xmax;
         
$xmax $temp;
      }

      if (
$step 0) {
         
$step = -$step;
      }

      
$x_values = array();
      for (
$x $xmin$x <= $xmax$x += $step) {
         
array_push($x_values$x);
      }
      if (
$x $x_max $step) { # der rechte Punkt muss rein
         
array_push($x_values$x_max);
      }
      return 
generate_points($function$x_values$constants);
   }

   
####################################################################################
   # Funktion  : get_height                                                           #
   # Zweck     : Gibt die H"ohe am zweiten Punkt eines durch drei Punkte bestimmten   #
   #             Dreiecks zur"uck. (in Pixel)                                         #
   # Eingabe   : x-Koordinate Punkt 1       - $x1,                                    #
   #             y-Koordinate Punkt 1       - $y1,                                    #
   #             x-Koordinate Punkt 2       - $x2,                                    #
   #             y-Koordinate Punkt 2       - $y2,                                    #
   #             x-Koordinate Punkt 3       - $x3,                                    #
   #             y-Koordinate Punkt 3       - $y3,                                    #
   #             Aufl"osung x-Richtung      - $resx,                                  #
   #             Aufl"osung y-Richtung      - $resy                                   #
   # Ausgabe   : H"ohe des Dreiecks in Pixel                                          #
   # Sonstiges : - Punkte in normalen Koordinaten, Ausgabe in Pixel                   #
   #             - Aufl"osung in Pixel pro Einheit                                    #
   #             - Nach Heron gilt sqrt(s(s-a)(s-b)(s-c)) = A = (a * h_a) / 2,        #
   #               hieraus ergibt sich die angegebene Formel.                         #
   ####################################################################################

   
function get_height($x1$y1$x2$y2$x3$y3$resx$resy) {
      
$a sqrt($resx $resx * ($x1 $x3) * ($x1 $x3)
              + 
$resy $resy * ($y1 $y3) * ($y1 $y3));
      
$b sqrt($resx $resx * ($x1 $x2) * ($x1 $x2)
              + 
$resy $resy * ($y1 $y2) * ($y1 $y2));
      
$c sqrt($resx $resx * ($x2 $x3) * ($x2 $x3)
              + 
$resy $resy * ($y2 $y3) * ($y2 $y3));
      return 
sqrt(($a $b $c) * (-$a $b $c) * ($a $b $c) * ($a $b $c)) / ($a);
   }

   
####################################################################################
   # Funktion  : auto_step                                                            #
   # Zweck     : Versucht, m"oglichst wenige Punkte zu berechnen, die den Graphen     #
   #             der Funktion m"oglichst "glatt" approximieren                        #
   # Eingabe   : Funktion als Stack         - $function,                              #
   #             kleinster x-Wert           - $xmin,                                  #
   #             gr"o"ster x-Wert           - $xmax,                                  #
   #             kleinster y-Wert           - $ymin,                                  #
   #             gr"o"ster y-Wert           - $ymax,                                  #
   #             Aufl"osung x-Richtung      - $resx,                                  #
   #             Aufl"osung y-Richtung      - $resy,                                  #
   #             Konstanten                 - $constants                             #
   # Ausgabe   : Punkte                                                               #
   # Sonstiges : - Punkte in der Form (x => (y, Fehlernummer), ...)                   #
   #             - Anfangs- und Endwert sind immer in der Ausgabe enthalten           #
   #             - Aufl"osung in Pixel pro Einheit                                    #
   ####################################################################################

   
function auto_step($function$xmin$xmax$ymin$ymax$resx$resy$constants) {
      global 
$global_error_names;
      global 
$global_errors;
      global 
$global_unary_operators;
      global 
$global_binary_operators;

      
$noprocess  false;
      
$outofrange false;

      
# Fehler in den Parametern -- keine Chance au"ser f"ur Hellseher
      
if ($resx <= or $resy <= or $xmin == $xmax or $ymin == $ymax) {
         return array(array(
0$global_error_names{'OUTOFRANGE'}));
      }

      
# Minimum und Maximum vertauscht; wir machen es r"uckg"angig
      
if ($xmin $xmax) {
         
$temp $xmin;
         
$xmin $xmax;
         
$xmax $temp;
      }

      
# Minimum und Maximum vertauscht; wir machen es r"uckg"angig
      
if ($ymin $ymay) {
         
$temp $ymin;
         
$ymin $ymay;
         
$ymay $temp;
      }

      
# Wir berechnen Schrittweite mit Minimum und Maximum und achten darauf, dass
      # keiner der Werte Null wird ("uberpr"uft am kleinsten Wert)
      
$temp 1;
      do {
         
$stepmin CONST_STEP_MIN_RATIO $temp $resx;
         
$step    CONST_STEP_RATIO     $temp $resx;
         
$stepmax CONST_STEP_MAX_RATIO $temp $resx;
         ++
$temp;
      } while (
$stepmin == 0);

      
$results = array();

      
# Konstantensubstitution
      
$temp substitute($function$constants);
      if (
$temp[1] != $global_error_names['NOERROR']) {
         return array(array(
0$temp[1]));
      }
      
$function $temp[0];

      
# Erster Punkt

      
$x $xmin;
         
$temp substitute($function, array('x' => $x));
         if (
$temp[1] != $global_error_names['NOERROR']) {
            return array(array(
0$temp[1]));
         }
         
$temp $temp[0];
         
$temp process_stack($temp$global_unary_operators$global_binary_operators);
         switch (
$global_errors{$temp[1]}) {
            case (
'NOSUCHFUNC'): # diese Fehler k"onnen nicht
            
case ('PARSEERR'):   # aufgrund eines fehlerhaften
            
case ('NOSUCHTYPE'): # Wertes auftreten
            
case ('NOTANUMBER'):
               return array(array(
0$temp[1]));
         }
         
$results["$x"] = $temp;
         
$x2 $x;
         if (
$temp[1] != $global_error_names{'NOERROR'}) {
            
$noprocess true;
         }

      
# Zweiter Punkt

      
$x += $step;
         
$temp substitute($function, array('x' => $x));
         if (
$temp[1] != $global_error_names['NOERROR']) {
            return array(array(
0$temp[1]));
         }
         
$temp $temp[0];
         
$temp process_stack($temp$global_unary_operators$global_binary_operators);
         
$results["$x"] = $temp;
         
$x1 $x;
         if (
$temp[1] != $global_error_names{'NOERROR'}) {
            
$noprocess true;
         }
         if (
$y $ymin or $y $ymax) {
           
$outofrange true;
         }

     
# Der Rest der Punkte

     
$x += $step;
     while (
$x <= $xmax) {
         
$temp substitute($function, array('x' => $x));
         if (
$temp[1] != $global_error_names['NOERROR']) {
            return array(array(
0$temp[1]));
         }
         
$temp $temp[0];
         
$temp process_stack($temp$global_unary_operators$global_binary_operators);
         
$results["$x"] = $temp;
         
$x1 $x;
         if (
$temp[1] == $global_error_names{'NOERROR'}) { # wenn kein Fehler auftritt
            
if (!$noprocess) { # wenn wir alles bearbeiten sollen
               
$height get_height($x2$results["$x2"][0],
                                    
$x1$results["$x1"][0],
                                    
$x,  $y,
                                    
$resx$resy);
               
# die H"ohe des Dreiecks aus den letzten drei Punkten
               
if ($height CONST_MAX_HEIGHT and $step >= $stepmin) {
                  
# wenn die Abweichung zu gro"s ist und wir die Schrittweite
                  # verkleinern k"onnen
                  
$x  $x1# heucheln wir vor, der letzte Punkt zu sein
                  
$x1 $x2;
                  
$step /= 2# und halbieren die Schrittweite
               
} else if ($height CONST_MIN_HEIGHT and $step <= $stepmax) {
                  
# wenn die Abweichung zu klein ist und wir die Schrittweite
                  # vergr"o"sern k"onnen
                  
$step *= 2# verdoppeln wir die Schrittweite
               
}
            } else { 
# wenn wir nicht weitermachen sollten
               
if ($results["$x1"][1] == $global_error_names{'NOERROR'}) {
                  
# falls nur der vorletzte Wert nicht definiert war
                   
$noprocess false# geht es jetzt weiter
                
} else { # sonst
                   
$noprocess true# brauchen wir noch eine Auszeit
                
}
            }
            if (
$y $ymin or $y $ymax) {
               
$outofrange true;
            } else {
               
$outofrange false;
            }
         } else { 
# wenn ein Fehler auftritt
            
if (!$outofrange and $step >= $stepmin) {
               
# wenn man es noch sehen kann, gehen wir m"oglichst nahe heran
               
$x  $x1;  # wir heucheln, der letzte Wert zu sein
               
$x1 $x2;
               
$step /= 2# und halbieren die Schrittweite
            
} else {
               
$noprocess true;
            }
         }
         
$x2 $x1# vorletzten und letzten Punkt bearbeiten
         
$x1 $x;
         
$x += $step;
      }

      
# Falls der rechte Rand nicht dabei ist nehmen eir ihn noch dazu

      
if ($x $xmax $step) {
         
$x $xmax;
         while (
$x <= $xmax) {
            
$temp substitute($function, array('x' => $x));
            if (
$temp[1] != $global_error_names['NOERROR']) {
               return array(array(
0$temp[1]));
            }
            
$temp $temp[0];
            
$temp process_stack($temp$global_unary_operators$global_binary_operators);
            
$results["$x"] = $temp;
            
$x1 $x;
            if (
$temp[1] == $global_error_names{'NOERROR'}) {
               if (!
$noprocess) {
                  
$height get_height($x2$results["$x2"][0],
                                       
$x1$results["$x1"][0],
                                       
$x,  $y,
                                       
$resx$resy);
                  if (
$height CONST_MAX_HEIGHT and $step >= $stepmin) {
                     
$x  $x1;
                     
$x1 $x2;
                     
$step /= 2;
                  } else if (
$height CONST_MIN_HEIGHT and $step <= $stepmax) {
                     
$step *= 2;
                  }
               } else {
                  if (
$results["$x1"][1] == $global_error_names{'NOERROR'}) {
                      
$noprocess false;
                   } else {
                      
$noprocess true;
                   }
               }
               if (
$y $ymin or $y $ymax) {
                  
$outofrange true;
               } else {
                  
$outofrange false;
               }
            } else {
               if (!
$outofrange and $step >= $stepmin) {
                  
$x  $x1;
                  
$x1 $x2;
                  
$step /= 2;
               } else {
                  
$noprocess true;
               }
            }
            
$x2 $x1;
            
$x1 $x;
            
$x += $step;
          }
      }
      return 
$results;
   }

?>

Datei units/plotter_constants.php:

<?php

   
####################################################################################
   # Dies ist die Datei 'plotter_constants.php'                                       #
   #                                                                                  #
   # Sie enth"alt Konstanten f"ur die Grafik des Plotters (Farben, Standardfunktion,  #
   # etc.) des Parser/Plotter-Projekts                                                #
   #                                                                                  #
   # Diese Datei darf frei als Ganzes oder in Teilen f"ur jegliche nicht-             #
   # kommerzielle Zwecke verwandt werden, solange folgede Bedingungen erf"ullt        #
   # werden:                                                                          #
   #    - Dieser Blockkommentar mit den Nutzungsbedingungen muss unver"andert         #
   #      in allen Nachfolgedateien / -ver"offentlichungen am Datei- / Textkopf       #
   #      verwandt werden                                                             #
   #    - Der Quellcode des muss jedem Benutzer von allen Programmen, die ihn         #
   #      verwenden, einsehbar gemacht werden                                         #
   #                                                                                  #
   # Sollten Sie diesen Code, in Teilen oder als Ganzes, auch portiert in             #
   # andere Programmiersprachen oder unter blo"ser Verwendung des Algorithmus         #
   # oder von Teilen von verwandten Algorithmen, f"ur kommerzielle Zwecke nutzen      #
   # wollen, so kontaktieren Sie mich bitte.                                          #
   #                                                                                  #
   # Ich habe den vorliegenden Code von Grund auf selbst programmiert und mich        #
   # dabei auf keine anderen als Standardalgorithmen gest"utzt. Insbesondere den      #
   # Tokenizer, der Parser und die Schrittweitensteurerung habe ich von Grund         #
   # auf und ohne Zuhilfenahme anderer Quellen selbst programmiert. Sollte ich        #
   # mit dem vorliegenden Code bestehende Copyrights oder Patente verletzen oder      #
   # den Urheber geistigen Eigentums vorenthalten, so geschieht dies                  #
   # unabsichtlich. Bitte kontaktieren Sie mich mittels untenstehender E-Mail-        #
   # Adresse oder "uber den Sysadmin.                                                 #
   #                                                                                  #
   # Der Autor "ubernimmt keine Haftung f"ur eventuelle durch die Nutzung dieses      #
   # entstehende oder entstandene mittelbare oder unmittelbare Sch"aden jedweder Art. #
   # Nutzung auf eigene Gefahr.                                                       #
   #                                                                                  #
   # Bitte schicken Sie mir keine E-Mails mit Bitte um die Erkl"arung der             #
   # Funktionsweise des Codes oder von Teilen des Codes; ich habe mich bem"uht,       #
   # den Code so gut wie m"oglich zu kommentieren und habe leider nicht genug         #
   # Zeit, um E-Mails "uber technische Details zu beantworten.                        #
   #                                                                                  #
   # (c) Jan Olligs, 2004                                                             #
   # Alle Rechte vorbehalten                                                          #
   #                                                                                  #
   # Jan.Olligs@gmx.net                                                               #
   ####################################################################################

   ####################################################################################
   #                               Farbdefinitionen als RGB                           #
   ####################################################################################

   
$global_colors = array(
           
#       Name             -R-  -G-  -B-
           
array('Schwarz',           0,   0,   0),
           array(
'Weiß',            255255255),
           array(
'Grau',            200200200),
           array(
'Blau',              0,   0160),
           array(
'Hellblau',          0,   0255),
           array(
'Bordeaux',        160,   0,   0),
           array(
'Rot',             255,   0,   0),
           array(
'Grün',              0160,   0),
           array(
'Hellgrün',          0255,   0),
           array(
'Gelb',            160160,   0),
           array(
'Hellgelb',        255255,   0),
           array(
'Cyan',              0160160),
           array(
'Helles Cyan',       0255255),
           array(
'Mangenta',        160,   0160),
           array(
'Helles Mangenta'255,   0255)
   );

   
# Standardwerte f"ur den Graph / das Formular
   # Erster Wert: 'i': Ignorieren, 'n': positive Zahl, 't': Term, 'c': Farbe,
   #              'p': Prozentzahl, 'b': Boolean, 'e': Berechnen
   
$plotter_standards = array(
      
'func'           => array('t''cos(x)*sin(x)'), # Funktionsterm

      
'img_width'      => array('n'640),             # Bildbreite
      
'img_height'     => array('n'480),             # Bildh"ohe
      
'img_types'      => array('i', array(
                                        array(
'PNG',  IMG_PNG"Content-type: image/png"),
                                        array(
'GIF',  IMG_GIF"Content-type: image/gif"),
                                        array(
'JPEG'IMG_JPG"Content-type: image/jpeg")
                                          )
                               ),
                                                  
# Bildbereich
      
'x_min'          => array('e''-2pi'),        # kleinstes x
      
'x_max'          => array('e''2pi'),         # gr"o"stes x
      
'x_grid'         => array('e''pi/4'),        # x-Gitterweite

      
'y_min'          => array('e''-1.5'),        # kleinstes y
      
'y_max'          => array('e''1.5'),         # gr"o"stes y
      
'y_grid'         => array('e''0.5'),         # y-Gitterweite

      
'step'           => array('e''0.025'),       # Schrittweite
      
'auto_step'      => array('b''true'),        # Schrittweitensteuerung an?
                                                  # Farben
      
'BG_color'       => array('c'1),             # Hintergrundfarbe
      
'PL_color'       => array('c'5),             # Graphenfarbe
      
'AX_color'       => array('c'0),             # Achsfarbe
      
'GR_color'       => array('c'2),             # Gitterlinienfarbe
                                                  # Schatten
      
'shading_min'    => array('e''0'),           # kleinster Schatten-x-Wert
      
'shading_max'    => array('e''pi'),          # gr"o"ster Schatten-x-Wert
      
'SH_color'       => array('c'3),             # Schattenfarbe
      
'shading_trans'  => array('p'30),            # 30 % Transparenz
      
'shading_f1'     => array('t''sin(x)'),      # 1. Grenzfunktion
      
'shading_f2'     => array('t''cos(x)'),      # 2. Grenzfunktion
      
'SF_color'       => array('c'0),             # Farbe der Grenzfunktionen
      
'do_shade'       => array('b''false'),       # Schatten an?
                                                  # Asymptoten
      
'asym_px1'       => array('e''0'),           # Punkt 1 x
      
'asym_py1'       => array('e''0'),           #         y
      
'asym_px2'       => array('e''0'),           # Punkt 2 x
      
'asym_py2'       => array('e''0'),           #         y
      
'AS_color'       => array('c'2),             # Asymptotenfarbe
      
'asym_dash'      => array('b''true')         # gestrichelt?
   
);

   
####################################################################################
   #                               Konstanten f"ur auto_step                          #
   ####################################################################################

   
define('CONST_STEP_MIN_RATIO',  8); # minimale Schrittweite (relativ)
   
define('CONST_STEP_RATIO',      4);     # Anfangsschrittweite (relativ)
   
define('CONST_STEP_MAX_RATIO'16);     # maximale Schrittweite (relativ)

   
define('CONST_MIN_HEIGHT'0.6);        # minimale H"ohe (f"ur Algorithmus)
   
define('CONST_MAX_HEIGHT'1.5);        # maximale H"ohe (f"ur Algorithmus)

?>

Datei units/various.php:

<?php

   
####################################################################################
   # Dies ist die Datei 'various.php'                                                 #
   #                                                                                  #
   # Sie enth"alt verschiedene Methoden f"ur das Parser/Plotter-Projekt               #
   #                                                                                  #
   # Diese Datei darf frei als Ganzes oder in Teilen f"ur jegliche nicht-             #
   # kommerzielle Zwecke verwandt werden, solange folgede Bedingungen erf"ullt        #
   # werden:                                                                          #
   #    - Dieser Blockkommentar mit den Nutzungsbedingungen muss unver"andert         #
   #      in allen Nachfolgedateien / -ver"offentlichungen am Datei- / Textkopf       #
   #      verwandt werden                                                             #
   #    - Der Quellcode des muss jedem Benutzer von allen Programmen, die ihn         #
   #      verwenden, einsehbar gemacht werden                                         #
   #                                                                                  #
   # Sollten Sie diesen Code, in Teilen oder als Ganzes, auch portiert in             #
   # andere Programmiersprachen oder unter blo"ser Verwendung des Algorithmus         #
   # oder von Teilen von verwandten Algorithmen, f"ur kommerzielle Zwecke nutzen      #
   # wollen, so kontaktieren Sie mich bitte.                                          #
   #                                                                                  #
   # Ich habe den vorliegenden Code von Grund auf selbst programmiert und mich        #
   # dabei auf keine anderen als Standardalgorithmen gest"utzt. Insbesondere den      #
   # Tokenizer, der Parser und die Schrittweitensteurerung habe ich von Grund         #
   # auf und ohne Zuhilfenahme anderer Quellen selbst programmiert. Sollte ich        #
   # mit dem vorliegenden Code bestehende Copyrights oder Patente verletzen oder      #
   # den Urheber geistigen Eigentums vorenthalten, so geschieht dies                  #
   # unabsichtlich. Bitte kontaktieren Sie mich mittels untenstehender E-Mail-        #
   # Adresse oder "uber den Sysadmin.                                                 #
   #                                                                                  #
   # Der Autor "ubernimmt keine Haftung f"ur eventuelle durch die Nutzung dieses      #
   # entstehende oder entstandene mittelbare oder unmittelbare Sch"aden jedweder Art. #
   # Nutzung auf eigene Gefahr.                                                       #
   #                                                                                  #
   # Bitte schicken Sie mir keine E-Mails mit Bitte um die Erkl"arung der             #
   # Funktionsweise des Codes oder von Teilen des Codes; ich habe mich bem"uht,       #
   # den Code so gut wie m"oglich zu kommentieren und habe leider nicht genug         #
   # Zeit, um E-Mails "uber technische Details zu beantworten.                        #
   #                                                                                  #
   # (c) Jan Olligs, 2004                                                             #
   # Alle Rechte vorbehalten                                                          #
   #                                                                                  #
   # Jan.Olligs@gmx.net                                                               #
   ####################################################################################

   ####################################################################################
   # Funktion  : check_error                                                          #
   # Zweck     : Untainting von Variablen oder Fehlerausgabe                          #
   # Eingabe   : Zu "uberpr"ufender Wert    - $value,                                 #
   #             Art der Variable           - $kind,                                  #
   #             Fehlermeldung              - $errormsg,                              #
   #             Standardwert               - $standard,                              #
   #             Konstanten (f"ur 'e')      - $constants                              #
   # Ausgabe   : "Uberpr"ufter Wert / Fehlermeldung                                   #
   # Sonstiges : - Wenn $errormsg == true, dann wird eine Fehlermeldung zur"uckge-    #
   #               geben, sonst der korrigierte Wert                                  #
   #             - korrigierter Wert = $standard bei Fehler, $value sonst             #
   #             - M"oglichkeiten f"ur die Variable $kind                             #
   #                  - 'n': number     - Nat"urliche Zahl                            #
   #                  - 't': term       - Term                                        #
   #                  - 'c': color      - Farbe                                       #
   #                  - 'p': percentage - Prozentwert                                 #
   #                  - 'b': boolean    - Bool'scher Wert                             #
   #                  - 'e': evaluate   - Ausdruck berechnen                          #
   ####################################################################################

   
function check_error($value$kind$errormsg true$standard 0$constants = array()) {

      global 
$global_parens;
      global 
$global_error_names;
      global 
$global_unary_operators;
      global 
$global_binary_operators;

      switch (
$kind) {
         case (
'n'):
            if (
$errormsg) {
               if (
is_numeric($value) and is_int($value 0)) {
                  return 
'';
               } else {
                  return 
"Keine ganze Zahl: '$value'.";
               }
            } else {
               if (
is_numeric($value) and is_int($value 0)) {
                  return 
$value;
               } else {
                  return 
$standard;
               }
            }
            break;
         case (
't'):
            if (
$errormsg) {
               
$temp check_parens($value$global_parens);
               if (
$temp > -1) {
                  
$err '';
                  for (
$i 0$i strlen($value); ++$i) {
                     if (
$i == $temp) {
                        
$err .= "<font color=\"red\">" htmlspecialchars($value{$i}) . "</font>";
                     } else {
                        
$err .= htmlspecialchars($value{$i});
                     }
                  }
                  return 
"Die rote Klammer im Term passt nicht: '$err'.";
               }
               
$term check_minus($value$global_parens);
               if (
$term[1] != $global_error_names['NOERROR']) {
                  return 
"Beim Einf&uuml;gen der Minuszeichen ist ein Fehler aufgetreten: <i>"
                       
htmlspecialchars(error_text($term[1])) . "</i>.";
               }
               
$term $term[0];
               
$poss array_merge(range('a''z'), range('A''Z'));
               foreach (
$global_parens as $pair) {
                  
array_push($poss$pair[0]);
               }
               
$term add_times($term$poss'*');
               if (
$term[1] != $global_error_names['NOERROR']) {
                  return 
"Beim Einf&uuml;gen der Malzeichen ist ein Fehler aufgetreten: <i>"
                       
htmlspecialchars(error_text($term[1])) . "</i>.";
               }
               
$term $term[0];
               
$term tokenize($term$global_parens$global_unary_operators,
                                
$global_binary_operators);
               if (
$term[1] != $global_error_names['NOERROR']) {
                  return 
"Bei der Zerlegung in Tokens ist ein Fehler aufgetreten: <i>"
                       
htmlspecialchars(error_text($term[1])) . "</i>.";
               }
               
$term $term[0];
               
$term substitute($term$constants);
               if (
$term[1] != $global_error_names['NOERROR']) {
                  return 
"Bei der Substitution der Konstanten ist ein Fehler aufgetreten: <i>"
                       
htmlspecialchars(error_text($term[1])) . "</i>.";
               }
               
$term $term[0];
               
$term build_tree($term$global_parens$global_unary_operators$global_binary_operators);
               if (
$term[1] != $global_error_names['NOERROR']) {
                  return 
"Beim Aufbau des <i>parse tree</i> ist ein Fehler aufgetreten: <i>"
                       
htmlspecialchars(error_text($term[1])) . "</i>.";
               }
               
$term $term[0][0];
               
$term build_stack($term);
               if (
$term[1] != $global_error_names['NOERROR']) {
                  return 
"Beim Aufbau des Stacks ist ein Fehler aufgetreten: <i>"
                       
htmlspecialchars(error_text($term[1])) . "</i>.";
               }
               
$term $term[0];
               
$term substitute($term, array('x' => '1'));
               if (
$term[1] != $global_error_names['NOERROR']) {
                  return 
"Bei der Substitution von <i>x</i> ist ein Fehler aufgetreten: <i>"
                       
htmlspecialchars(error_text($term[1])) . "</i>.";
               }
               
$term $term[0];
               
$term process_stack($term$global_unary_operators$global_binary_operators);
               if (
                     
$term[1] != $global_error_names['NOERROR'] and
                     
$term[1] != $global_error_names['DIVBYZERO'] and
                     
$term[1] != $global_error_names['OUTOFRANGE']
                  ) {
                  return 
"Bei der Berechnung des Funktionswertes ist ein Fehler aufgetreten: <i>"
                       
htmlspecialchars(error_text($term[1])) . "</i>.";
               }
               return 
'';
            } else {
               
$temp check_parens($value$global_parens);
               if (
$temp > -1) {
                  return 
$standard;
               }
               
$term check_minus($value$global_parens);
               if (
$term[1] != $global_error_names['NOERROR']) {
                  return 
$standard;
               }
               
$term $term[0];
               
$poss array_merge(range('a''z'), range('A''Z'));
               foreach (
$global_parens as $pair) {
                  
array_push($poss$pair[0]);
               }
               
$term add_times($term$poss'*');
               if (
$term[1] != $global_error_names['NOERROR']) {
                  return 
$standard;
               }
               
$term $term[0];
               
$term tokenize($term$global_parens$global_unary_operators,
                                
$global_binary_operators);
               if (
$term[1] != $global_error_names['NOERROR']) {
                  return 
$standard;
               }
               
$term $term[0];
               
$term substitute($term$constants);
               if (
$term[1] != $global_error_names['NOERROR']) {
                  return 
$standard;
               }
               
$term $term[0];
               
$term build_tree($term$global_parens$global_unary_operators$global_binary_operators);
               if (
$term[1] != $global_error_names['NOERROR']) {
                  return 
$standard;
               }
               
$term $term[0][0];
               
$term build_stack($term);
               if (
$term[1] != $global_error_names['NOERROR']) {
                  return 
$standard;
               }
               
$term $term[0];
               
$term substitute($term, array('x' => '1'));
               if (
$term[1] != $global_error_names['NOERROR']) {
                  return 
$standard;
               }
               
$term $term[0];
               
$term process_stack($term$global_unary_operators$global_binary_operators);
               if (
                     
$term[1] != $global_error_names['NOERROR'] and
                     
$term[1] != $global_error_names['DIVBYZERO'] and
                     
$term[1] != $global_error_names['OUTOFRANGE']
                  ) {
                  return 
$standard;
               }
               return 
$value;
            }
            break;
         case (
'c'):
            global 
$global_colors;
            if (
$errormsg) {
               if (!
is_numeric($value) or !is_int($value 0)) {
                  return 
"'$value' ist kein g&uuml;ltiger Farbcode.";
               } elseif (
$value or count($global_colors) <= $value) {
                  return 
"'$value' ist kein g&uuml;ltiger Farbcode.";
               } else {
                  return 
'';
               }
            } else {
               if (!
is_numeric($value) or !is_int($value 0)) {
                  return 
$standard;
               } elseif (
$value or count($global_colors) <= $value) {
                  return 
$standard;
               } else {
                  return 
$value;
               }
            }
            break;
         case (
'p'):
            if (
$errormsg) {
               if (!
is_numeric($value)) {
                  return 
"'$value' ist keine g&uuml;ltige Prozentzahl.";
               } elseif (
$value or 100 $value) {
                  return 
"'$value' ist keine g&uuml;ltige Prozentzahl.";
               } else {
                  return 
'';
               }
            } else {
               if (!
is_numeric($value)) {
                  return 
$standard;
               } elseif (
$value or 100 $value) {
                  return 
$standard;
               } else {
                  return 
$value;
               }
            }
            break;
         case (
'b'):
            if (
$errormsg) {
               if (
strtolower($value) == 'true' or strtolower($value) == 'false') {
                  return 
'';
               } else {
                  return 
"Kein Boolean: '$value'.";
               }
            } else {
               if (
strtolower($value) == 'true' or strtolower($value) == 'false') {
                  return 
$value;
               } else {
                  return 
$standard;
               }
            }
            break;
         case (
'e'):
            if (
$errormsg) {
               
$temp check_parens($value$global_parens);
               if (
$temp > -1) {
                  
$err '';
                  for (
$i 0$i strlen($value); ++$i) {
                     if (
$i == $temp) {
                        
$err .= "<font color=\"red\">" htmlspecialchars($value{$i}) . "</font>";
                     } else {
                        
$err .= htmlspecialchars($value{$i});
                     }
                  }
                  return 
"Die rote Klammer im Term passt nicht: '$err'.";
               }
               
$term check_minus($value$global_parens);
               if (
$term[1] != $global_error_names['NOERROR']) {
                  return 
"Beim Einf&uuml;gen der Minuszeichen ist ein Fehler aufgetreten: <i>"
                       
htmlspecialchars(error_text($term[1])) . "</i>.";
               }
               
$term $term[0];
               
$poss array_merge(range('a''z'), range('A''Z'));
               foreach (
$global_parens as $pair) {
                  
array_push($poss$pair[0]);
               }
               
$term add_times($term$poss'*');
               if (
$term[1] != $global_error_names['NOERROR']) {
                  return 
"Beim Einf&uuml;gen der Malzeichen ist ein Fehler aufgetreten: <i>"
                       
htmlspecialchars(error_text($term[1])) . "</i>.";
               }
               
$term $term[0];
               
$term tokenize($term$global_parens$global_unary_operators,
                                
$global_binary_operators);
               if (
$term[1] != $global_error_names['NOERROR']) {
                  return 
"Bei der Zerlegung in Tokens ist ein Fehler aufgetreten: <i>"
                       
htmlspecialchars(error_text($term[1])) . "</i>.";
               }
               
$term $term[0];
               
$term substitute($term$constants);
               if (
$term[1] != $global_error_names['NOERROR']) {
                  return 
"Bei der Substitution der Konstanten ist ein Fehler aufgetreten: <i>"
                       
htmlspecialchars(error_text($term[1])) . "</i>.";
               }
               
$term $term[0];
               
$term build_tree($term$global_parens$global_unary_operators$global_binary_operators);
               if (
$term[1] != $global_error_names['NOERROR']) {
                  return 
"Beim Aufbau des <i>parse tree</i> ist ein Fehler aufgetreten: <i>"
                       
htmlspecialchars(error_text($term[1])) . "</i>.";
               }
               
$term $term[0][0];
               
$term build_stack($term);
               if (
$term[1] != $global_error_names['NOERROR']) {
                  return 
"Beim Aufbau des Stacks ist ein Fehler aufgetreten: <i>"
                       
htmlspecialchars(error_text($term[1])) . "</i>.";
               }
               
$term $term[0];
               
$term process_stack($term$global_unary_operators$global_binary_operators);
               if (
$term[1] != $global_error_names['NOERROR']) {
                  return 
"Bei der Berechnung des Funktionswertes ist ein Fehler aufgetreten: <i>"
                       
htmlspecialchars(error_text($term[1])) . "</i>.";
               }
               return 
'';
            } else {
               
$temp check_parens($value$global_parens);
               if (
$temp > -1) {
                  return 
check_error($value$kindfalse'0');
               }
               
$term check_minus($value$global_parens);
               if (
$term[1] != $global_error_names['NOERROR']) {
                  return 
check_error($value$kindfalse'0');
               }
               
$term $term[0];
               
$poss array_merge(range('a''z'), range('A''Z'));
               foreach (
$global_parens as $pair) {
                  
array_push($poss$pair[0]);
               }
               
$term add_times($term$poss'*');
               if (
$term[1] != $global_error_names['NOERROR']) {
                  return 
check_error($value$kindfalse'0');
               }
               
$term $term[0];
               
$term tokenize($term$global_parens$global_unary_operators,
                                
$global_binary_operators);
               if (
$term[1] != $global_error_names['NOERROR']) {
                  return 
check_error($value$kindfalse'0');
               }
               
$term $term[0];
               
$term substitute($term$constants);
               if (
$term[1] != $global_error_names['NOERROR']) {
                  return 
check_error($value$kindfalse'0');
               }
               
$term $term[0];
               
$term build_tree($term$global_parens$global_unary_operators$global_binary_operators);
               if (
$term[1] != $global_error_names['NOERROR']) {
                  return 
check_error($value$kindfalse'0');
               }
               
$term $term[0][0];
               
$term build_stack($term);
               if (
$term[1] != $global_error_names['NOERROR']) {
                  return 
check_error($value$kindfalse'0');
               }
               
$term $term[0];
               
$term process_stack($term$global_unary_operators$global_binary_operators);
               if (
                     
$term[1] != $global_error_names['NOERROR'] and
                     
$term[1] != $global_error_names['DIVBYZERO'] and
                     
$term[1] != $global_error_names['OUTOFRANGE']
                  ) {
                  return 
check_error($value$kindfalse'0');
               }
               return 
$term[0];
            }
            break;
         default:
            if (
$errormsg) {
               return 
"Unbekannter Wertetyp: '$kind'.";
            } else {
               return 
$standard;
            }
      }
   }

   
####################################################################################
   # Funktion  : unpack_function_terms                                                #
   # Zweck     : Funktionsparameter aus $_REQUEST-Array in Array extrahieren          #
   # Eingabe   : $_REQUEST-Array            - $request                                #
   # Ausgabe   : Funktionsparameter als Array                                         #
   ####################################################################################

   
function unpack_function_terms($request) {
      
$result = array();
      foreach (
$request as $name => $value) {
         if (
preg_match('/^function_(\d+)_(.+)$/i'$name$matches)) {
            switch (
$matches[2]) {
               case (
'term'):
                  
$result[$matches[1]]['term'] = $value;
                  break;
               case (
'color'):
                  
$result[$matches[1]]['color'] = $value;
                  break;
               case (
'delete'):
                  
$result[$matches[1]]['delete'] = $value;
                  break;
               case (
'param_name'):
                  
$result[$matches[1]]['param']['name'] = $value;
                  break;
               case (
'param_from'):
                  
$result[$matches[1]]['param']['from'] = $value;
                  break;
               case (
'param_to'):
                  
$result[$matches[1]]['param']['to'] = $value;
                  break;
               case (
'param_step'):
                  
$result[$matches[1]]['param']['step'] = $value;
                  break;
            }
         }
      }
      return 
$result;
   }

   
####################################################################################
   # Funktion  : pack_function_terms                                                  #
   # Zweck     : Funktionsparameter aus Array in Werte f"ur $_REQUEST-Array umwandeln #
   # Eingabe   : Funktionsparameter         - $functions                              #
   # Ausgabe   : Array mit Werten f"ur $_REQUEST-Array                                #
   ####################################################################################

   
function pack_function_terms($functions) {
      
$result = array();
      foreach (
$functions as $number => $properties) {
         
$result["function_${number}_term"]       = $properties['term'];
         
$result["function_${number}_color"]      = $properties['color'];
         
$result["function_${number}_delete"]     = $properties['delete'];
         
$result["function_${number}_param_name"] = $properties['param']['name'];
         
$result["function_${number}_param_from"] = $properties['param']['from'];
         
$result["function_${number}_param_to"]   = $properties['param']['to'];
         
$result["function_${number}_param_step"] = $properties['param']['step'];
      }
      return 
$result;
   }

   
####################################################################################
   # Funktion  : unpack_asymptote_terms                                               #
   # Zweck     : Asymptotenparameter aus $_REQUEST-Array in Array extrahieren         #
   # Eingabe   : $_REQUEST-Array            - $request                                #
   # Ausgabe   : Asymptotenparameter als Array                                        #
   ####################################################################################

   
function unpack_asymptote_terms($request) {
      
$result = array();
      foreach (
$request as $name => $value) {
         if (
preg_match('/^asymptote_(\d+)_(.+)$/i'$name$matches)) {
            switch (
$matches[2]) {
               case (
'p1_x'):
               case (
'p1_y'):
               case (
'p2_x'):
               case (
'p2_y'):
               case (
'color'):
               case (
'dashed'):
               case (
'delete'):
                  
$result[$matches[1]][$matches[2]] = $value;
                  break;
            }
         }
      }
      return 
$result;
   }

   
####################################################################################
   # Funktion  : pack_asymptote_terms                                                 #
   # Zweck     : Asymptotenparameter (Array) in Werte f"ur $_REQUEST-Array umwandeln  #
   # Eingabe   : Asymptotenparameter        - $asymptotes                             #
   # Ausgabe   : Array mit Werten f"ur $_REQUEST-Array                                #
   ####################################################################################

   
function pack_asymptote_terms($asymptotes) {
      
$result = array();
      foreach (
$asymptotes as $number => $properties) {
         
$result["asymptote_${number}_p1_x"]   = $properties['p1_x'];
         
$result["asymptote_${number}_p1_y"]   = $properties['p1_y'];
         
$result["asymptote_${number}_p2_x"]   = $properties['p2_x'];
         
$result["asymptote_${number}_p2_y"]   = $properties['p2_y'];
         
$result["asymptote_${number}_color"]  = $properties['color'];
         
$result["asymptote_${number}_dashed"] = $properties['dashed'];
         
$result["asymptote_${number}_delete"] = $properties['delete'];
      }
      return 
$result;
   }

   
####################################################################################
   # Funktion  : get_joined_indices                                                   #
   # Zweck     : x-Werte erhalten, die in einer von zwei Punktmengen enthalten sind   #
   # Eingabe   : Zwei Arrays                - $array1, $array2                        #
   # Ausgabe   : Array mit allen Schl"usseln der beiden Arrays                        #
   ####################################################################################

   
function get_joined_indices($array1$array2) {
      return 
array_unique(array_merge(array_keys($array1), array_keys($array2)));
   }

   
####################################################################################
   # Funktion  : get_missing_indices                                                  #
   # Zweck     : Extrahiert Indices, die nicht in einem Array sind                    #
   # Eingabe   : Array mit Indices          - $indices,                               #
   #             Array (mit Punkten)        - $array                                  #
   # Ausgabe   : Array mit Werten aus $indices, die keine Schl"ussel von $array sind  #
   ####################################################################################

   
function get_missing_indices($indices$array) {
      
$result = array();
      foreach (
$indices as $key) {
         if (!
array_key_exists($key$array)) {
            
array_push($result$key);
         }
      }
      return 
$result;
   }

   
####################################################################################
   # Funktion  : http_build_query                                                     #
   # Zweck     : Baut einen POST-String aus einem Array auf                           #
   # Eingabe   : Siehe PHP-Dokumentation                                              #
   # Ausgabe   : POST-String                                                          #
   # Sonstiges : "Ubernommen von php at brayra dot nospam dot com von der PHP-Website #
   ####################################################################################

   
if(!function_exists('http_build_query')){
      function 
http_build_query($formdata$numeric_prefix ''){
          return 
_http_build_query($formdata,$numeric_prefix);
      }
      function 
_http_build_query($formdata$numeric_prefix '',$key_prefix=''){
          if(
$numeric_prefix != '' && !is_numeric($numeric_prefix)){
              
$prefix=$numeric_prefix;
          } else {
              
$prefix '';
          }
          if(!
is_array($formdata)) return '';
          
$str='';
          foreach(
$formdata as $key => $val){
              if(
is_numeric($key))$key=$prefix.$key;
              if(
$str != ''$str.='&';
              if(
$key_prefix != '') {
                  
$mykey $key_prefix."[$key]";
              } else {
                  
$mykey=&$key;
              }
              if(
is_array($val)){
                  
$str.=_http_build_query($val,'',$mykey);
              } else {
                  
$str.=$mykey.'='.urlencode($val);
              }
          }
          return 
$str;
      }
   }

   
####################################################################################
   # Funktion  : populate_request                                                     #
   # Zweck     : F"ullt $_REQUEST mit Werten, falls Felder nicht definiert sind       #
   # Eingabe   : $_REQUEST-Array         - $request,                                  #
   #             zu pr"ufende Felder     - $items,                                    #
   #             Standard-Werte          - $standards                                 #
   # Ausgabe   : Bearbeitetes $_REQUEST-Array                                         #
   # Sonstiges : - F"ur Standardwerte siehe plotter_constants.php                     #
   #             - $items = ([$_REQUEST-key] => [$standards-key], ...)                #
   ####################################################################################

   
function populate_request($request$items$standards) {
      foreach (
$items as $rq_key => $st_key) {
         if (
is_null($request[$rq_key]) or $request[$rq_key] == '') {
            
$request[$rq_key] = $standards[$st_key][1];
         }
      }
      return 
$request;
   }

   
####################################################################################
   # Funktion  : form_text                                                            #
   # Zweck     : Erstellt Textfeld f"ur HTML-Formular                                 #
   # Eingabe   : $_REQUEST-Array         - $request,                                  #
   #             Feldname                - $name,                                     #
   #             'size'-Parameter        - $size,                                     #
   #             'maxlength'-Parameter   - $maxlength                                 #
   # Ausgabe   : HTML-Code f"ur Textfeld                                              #
   ####################################################################################

   
function form_text($request$name$size$maxlength) {
      return 
'<input type="text" size="'$size
           
'" maxlength="' $maxlength
           
'" name="' htmlspecialchars($name)
           . 
'" value="' htmlspecialchars($request[$name]) . '">';
   }

   
####################################################################################
   # Funktion  : form_img_type                                                        #
   # Zweck     : Erstellt Auswahlfeld f"ur Bildformat f"ur HTML-Formular              #
   # Eingabe   : $_REQUEST-Array         - $request,                                  #
   #             Feldname                - $name,                                     #
   #             Standardwerte           - $standards,                                #
   #             Einr"ucktiefe           - $indent                                    #
   # Ausgabe   : HTML-Code f"ur Typauswahl                                            #
   # Sonstiges : F"ur Standardwerte siehe plotter_constants.php                       #
   ####################################################################################

   
function form_img_type($request$name$standards$indent) {
      
$result '';
      
$result .= str_repeat(' '$indent) . '<select name="' htmlspecialchars($name) . '" size="1">' "\n";
      
$image_type $request[$name];
      if (!
is_numeric($image_type) or !is_int($image_type 0) or $image_type 0
          
or count($standards{'img_types'}[1]) <= $image_type) {
         
$image_type 0;
      }
      if (!(
imagetypes() & $standards{'img_types'}[1][$image_type][1])) {
         
$image_type 0;
      }
      while (!(
imagetypes() & $standards{'img_types'}[1][$image_type][1])) {
         if (
$image_type >= count($standards{'img_types'})) {
            die;
         }
         ++
$image_type;
      }
      foreach (
$standards{'img_types'}[1] as $key => $properties) {
         
$result .= str_repeat(' '$indent)
                  . 
'   <option' . ($key == $image_type ' selected' '')
                  . 
' value="' $key '">'
                  
htmlspecialchars($properties[0]) . "</option>\n";
      }
      
$result .= str_repeat(' '$indent) . '</select>' "\n";
      return 
$result;
   }

   
####################################################################################
   # Funktion  : form_color_select                                                    #
   # Zweck     : Erstellt Auswahlfeld f"ur Farben f"ur HTML-Formular                  #
   # Eingabe   : $_REQUEST-Array         - $request,                                  #
   #             Feldname                - $name,                                     #
   #             Array mit Farben        - $colors,                                   #
   #             Einr"ucktiefe           - $indent                                    #
   # Ausgabe   : HTML-Code f"ur Farbenauswahlfeld                                     #
   # Sonstiges : F"ur Farbenarray siehe plotter_constants.php                         #
   ####################################################################################

   
function form_color_select($request$name$colors$indent) {
      
$result '';
      
$result .= str_repeat(' '$indent) . '<select name="' htmlspecialchars($name) . '" size="1">' "\n";
      
$color $request[$name];
      if (!
is_numeric($color) or !is_int($color 0) or $color or count($colors) <= $color) {
         
$color 0;
      }
      foreach (
$colors as $key => $properties) {
         
$result .= str_repeat(' '$indent)
                  . 
'   <option' . ($key == $color ' selected' '')
                  . 
' value="' $key '">'
                  
htmlspecialchars($properties[0]) . "</option>\n";
      }
      
$result .= str_repeat(' '$indent) . '</select>' "\n";
      return 
$result;
   }

   
####################################################################################
   # Funktion  : form_add_hidden_fields                                               #
   # Zweck     : Erstellt versteckte Felder f"ur HTML-Formular                        #
   # Eingabe   : $_REQUEST-Array         - $request,                                  #
   #             Ausnahmen               - $exceptions,                               #
   #             Einr"ucktiefe           - $indent                                    #
   # Ausgabe   : HTML-Code f"ur versteckte Felder                                     #
   # Sonstiges : - ALLE Felder von $_REQUEST werden ausgegeben, Ausnahme s.u.         #
   #             - Felder, die mit einer RegEx aus $exceptions passen, werden nicht   #
   #               als versteckte Felder ausgegeben ($exceptions ist also ein Array)  #
   ####################################################################################

   
function form_add_hidden_fields($request$exceptions$indent) {
      
$result '';
      foreach (
$request as $field => $content) {
         foreach (
$exceptions as $regex) {
            if (
preg_match($regex$field)) {
               continue 
2;
            }
         }
         
$result .= str_repeat(' '$indent) . '<input type="hidden" name="'
                  
htmlspecialchars($field) . '" value="'
                  
htmlspecialchars($content) . '">' "\n";
      }
      return 
$result;
   }

?>