ebnf:index
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
| Beide Seiten der vorigen RevisionVorhergehende Überarbeitung | |||
| ebnf:index [2023/09/28 07:51] – angelegt Vincent Tscherter | ebnf:index [2025/09/06 10:14] (aktuell) – Vincent Tscherter | ||
|---|---|---|---|
| Zeile 42: | Zeile 42: | ||
| } </ | } </ | ||
| - | The script is also available as stand-alone version under: | + | The script is also available as stand-alone version under: |
| - | | + | .../ |
| Note: The stand-alone script supports also XML output | Note: The stand-alone script supports also XML output | ||
| - | | + | .../ |
| ===== Syntax ===== | ===== Syntax ===== | ||
| Zeile 70: | Zeile 70: | ||
| * http:// | * http:// | ||
| * replace antialias function | * replace antialias function | ||
| - | |||
| - | ===== Code ===== | ||
| - | <code php syntax.php> | ||
| - | <?php | ||
| - | /** | ||
| - | * Dokuwiki Plugin EBNF: Displays Syntax Diagrams | ||
| - | * | ||
| - | * Syntax: < | ||
| - | * | ||
| - | * @license | ||
| - | * @author | ||
| - | * @version | ||
| - | */ | ||
| - | |||
| - | if(!defined(' | ||
| - | if(!defined(' | ||
| - | require_once(DOKU_PLUGIN.' | ||
| - | |||
| - | class syntax_plugin_ebnf extends DokuWiki_Syntax_Plugin { | ||
| - | |||
| - | function getType(){ | ||
| - | return ' | ||
| - | } | ||
| - | |||
| - | function getSort(){ | ||
| - | return 999; | ||
| - | } | ||
| - | |||
| - | function connectTo($mode) { | ||
| - | $this-> | ||
| - | } | ||
| - | |||
| - | function handle($match, | ||
| - | | ||
| - | case DOKU_LEXER_ENTER : | ||
| - | break; | ||
| - | case DOKU_LEXER_MATCHED : | ||
| - | break; | ||
| - | case DOKU_LEXER_UNMATCHED : | ||
| - | break; | ||
| - | case DOKU_LEXER_EXIT : | ||
| - | break; | ||
| - | case DOKU_LEXER_SPECIAL : | ||
| - | break; | ||
| - | } | ||
| - | return array($match); | ||
| - | } | ||
| - | |||
| - | function render($mode, | ||
| - | if($mode == ' | ||
| - | try { | ||
| - | $text = substr($data[0], | ||
| - | $text = preg_replace( "/ | ||
| - | $text = preg_replace( "/ | ||
| - | $text = urlencode($text); | ||
| - | | ||
| - | } catch (Exception $e) { | ||
| - | $renderer-> | ||
| - | } | ||
| - | return true; | ||
| - | } | ||
| - | return false; | ||
| - | } | ||
| - | } | ||
| - | ?> | ||
| - | </ | ||
| - | <code php ebnf.php> | ||
| - | <?php | ||
| - | /* | ||
| - | This program is free software: you can redistribute it and/or modify | ||
| - | it under the terms of the GNU General Public License as published by | ||
| - | the Free Software Foundation, either version 3 of the License, or | ||
| - | (at your option) any later version. | ||
| - | |||
| - | This program is distributed in the hope that it will be useful, | ||
| - | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| - | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
| - | GNU General Public License for more details. | ||
| - | |||
| - | You should have received a copy of the GNU General Public License | ||
| - | along with this program. | ||
| - | |||
| - | Vincent Tscherter, tscherter@karmin.ch, | ||
| - | |||
| - | 2009-01-18 version 0.1 first release | ||
| - | 2009-01-02 version 0.2 | ||
| - | - title und comment literal added | ||
| - | - ";" | ||
| - | */ | ||
| - | error_reporting(E_ALL|E_STRICT); | ||
| - | |||
| - | // | ||
| - | define(' | ||
| - | |||
| - | // parser | ||
| - | define(' | ||
| - | define(' | ||
| - | define(' | ||
| - | define(' | ||
| - | |||
| - | // rendering | ||
| - | define(' | ||
| - | define(' | ||
| - | define(' | ||
| - | |||
| - | // lexemes | ||
| - | $ebnf_lexemes[] = array( ' | ||
| - | $ebnf_lexemes[] = array( ' | ||
| - | $ebnf_lexemes[] = array( ' | ||
| - | $ebnf_lexemes[] = array( ' | ||
| - | $ebnf_lexemes[] = array( ' | ||
| - | |||
| - | // input example | ||
| - | $input = <<< | ||
| - | "EBNF defined in itself" | ||
| - | syntax | ||
| - | rule = identifier " | ||
| - | expression = term { " | ||
| - | term = factor { factor } . | ||
| - | factor | ||
| - | | literal | ||
| - | | " | ||
| - | | " | ||
| - | | " | ||
| - | identifier = character { character } . | ||
| - | title = literal . | ||
| - | comment | ||
| - | literal | ||
| - | | '"' | ||
| - | } | ||
| - | EOD; | ||
| - | |||
| - | if (isset($_GET[' | ||
| - | $input = $_GET[' | ||
| - | $input = stripslashes($input); | ||
| - | } | ||
| - | |||
| - | $format = " | ||
| - | if (isset($_GET[' | ||
| - | |||
| - | try { | ||
| - | $tokens = ebnf_scan($input, | ||
| - | $dom = ebnf_parse_syntax($tokens); | ||
| - | if ($format == ' | ||
| - | header(' | ||
| - | echo $dom-> | ||
| - | } else { | ||
| - | render_node($dom-> | ||
| - | } | ||
| - | } catch (Exception $e) { | ||
| - | header(' | ||
| - | $dom = new DOMDocument(); | ||
| - | $syntax = $dom-> | ||
| - | $syntax-> | ||
| - | $syntax-> | ||
| - | $dom-> | ||
| - | render_node($dom-> | ||
| - | } | ||
| - | |||
| - | function rr($im, $x1, $y1, $x2, $y2, $r, $black){ | ||
| - | imageline($im, | ||
| - | imageline($im, | ||
| - | imageline($im, | ||
| - | imageline($im, | ||
| - | imagearc($im, | ||
| - | imagearc($im, | ||
| - | imagearc($im, | ||
| - | imagearc($im, | ||
| - | } | ||
| - | |||
| - | function create_image($w, | ||
| - | global $white, $black, $blue, $red, $green, $silver; | ||
| - | $im = imagecreatetruecolor($w, | ||
| - | imageantialias($im, | ||
| - | $white = imagecolorallocate ($im, 255, 255, 255); | ||
| - | $black = imagecolorallocate ($im, 0, 0, 0); | ||
| - | $blue = imagecolorallocate ($im, 0, 0, 255); | ||
| - | $red = imagecolorallocate ($im, 255, 0, 0); | ||
| - | $green = imagecolorallocate ($im, 0, 200, 0); | ||
| - | $silver = imagecolorallocate ($im, 127, 127, 127); | ||
| - | imagefilledrectangle($im, | ||
| - | return $im; | ||
| - | } | ||
| - | |||
| - | function arrow($image, | ||
| - | global $white, $black; | ||
| - | if (!$lefttoright) | ||
| - | imagefilledpolygon($image, | ||
| - | array($x, $y-UNIT/3, $x-UNIT, $y, $x, $y+UNIT/3), 3, $black); | ||
| - | else | ||
| - | imagefilledpolygon($image, | ||
| - | array($x-UNIT, | ||
| - | } | ||
| - | |||
| - | |||
| - | function render_node($node, | ||
| - | global $white, $black, $blue, $red, $green, $silver; | ||
| - | if ($node-> | ||
| - | $text = $node-> | ||
| - | $w = imagefontwidth(FONT)*(strlen($text)) + 4*UNIT; | ||
| - | $h = 2*UNIT; | ||
| - | $im = create_image($w, | ||
| - | |||
| - | if ($node-> | ||
| - | imagerectangle($im, | ||
| - | imagestring($im, | ||
| - | } else { | ||
| - | if ($text!=" | ||
| - | rr($im, UNIT, 0, $w-UNIT-1, $h-1, UNIT/2, $black); | ||
| - | imagestring($im, | ||
| - | $text, $text!=" | ||
| - | } | ||
| - | imageline($im, | ||
| - | imageline($im, | ||
| - | return $im; | ||
| - | } else if ($node-> | ||
| - | if ($node-> | ||
| - | $lefttoright = ! $lefttoright; | ||
| - | $inner = render_node($node-> | ||
| - | $w = imagesx($inner)+6*UNIT; | ||
| - | $h = imagesy($inner)+2*UNIT; | ||
| - | $im = create_image($w, | ||
| - | imagecopy($im, | ||
| - | imageline($im, | ||
| - | arrow($im, $w/ | ||
| - | arrow($im, 3*UNIT, 3*UNIT, $lefttoright); | ||
| - | arrow($im, $w-2*UNIT, 3*UNIT, $lefttoright); | ||
| - | imageline($im, | ||
| - | imageline($im, | ||
| - | imageline($im, | ||
| - | imageline($im, | ||
| - | return $im; | ||
| - | } else if ($node-> | ||
| - | $inner = render_childs($node, | ||
| - | if (!$lefttoright) | ||
| - | $inner = array_reverse($inner); | ||
| - | $w = count($inner)*UNIT-UNIT; | ||
| - | for ($i = 0; $i< | ||
| - | $w += imagesx($inner[$i]); | ||
| - | $h = max($h, imagesy($inner[$i])); | ||
| - | } $im = create_image($w, | ||
| - | imagecopy($im, | ||
| - | $x = imagesx($inner[0])+UNIT; | ||
| - | for ($i = 1; $i< | ||
| - | imageline($im, | ||
| - | arrow($im, $x, UNIT, $lefttoright); | ||
| - | imagecopy($im, | ||
| - | $x += imagesx($inner[$i])+UNIT; | ||
| - | } return $im; | ||
| - | } else if ($node-> | ||
| - | $inner = render_childs($node, | ||
| - | $h = (count($inner)-1)*UNIT; | ||
| - | for ($i = 0; $i< | ||
| - | $h += imagesy($inner[$i]); | ||
| - | $w = max($w, imagesx($inner[$i])); | ||
| - | } $w += 6*UNIT; $im = create_image($w, | ||
| - | imageline($im, | ||
| - | imageline($im, | ||
| - | for ($i = 0; $i< | ||
| - | imageline($im, | ||
| - | imagecopy($im, | ||
| - | arrow($im, 3*UNIT, $y+UNIT, $lefttoright); | ||
| - | arrow($im, $w-2*UNIT, $y+UNIT, $lefttoright); | ||
| - | $top = $y + UNIT; | ||
| - | $y += imagesy($inner[$i])+UNIT; | ||
| - | } | ||
| - | imageline($im, | ||
| - | imageline($im, | ||
| - | return $im; | ||
| - | } else if ($node-> | ||
| - | $title = $node-> | ||
| - | $meta = $node-> | ||
| - | $node = $node-> | ||
| - | $names = array(); | ||
| - | $images = array(); | ||
| - | while ($node!=null) { | ||
| - | | ||
| - | $im = render_node($node-> | ||
| - | | ||
| - | $node = $node-> | ||
| - | } $wn = 0; $wr = 0; $h = 5*UNIT; | ||
| - | for ($i = 0; $i< | ||
| - | $wn = max($wn, imagefontwidth(FONT)*strlen($names[$i])); | ||
| - | $wr = max($wr, imagesx($images[$i])); | ||
| - | $h += imagesy($images[$i])+2*UNIT; | ||
| - | } | ||
| - | if ($title=='' | ||
| - | if ($meta=='' | ||
| - | $w = max($wr+$wn+3*UNIT, | ||
| - | $im = create_image($w, | ||
| - | $y = 2*UNIT; | ||
| - | if ($title!='' | ||
| - | imagestring($im, | ||
| - | $title, $green); | ||
| - | imageline($im, | ||
| - | $y += 2*UNIT; | ||
| - | } | ||
| - | for ($i = 0; $i< | ||
| - | imagestring($im, | ||
| - | imagecopy($im, | ||
| - | imageline($im, | ||
| - | imageline($im, | ||
| - | imageline($im, | ||
| - | $y += 2*UNIT + imagesy($images[$i]); | ||
| - | } | ||
| - | imagestring($im, | ||
| - | $meta, $silver); | ||
| - | rr($im, 0,0,$w-1, $h-1, UNIT/2, $green); | ||
| - | header(' | ||
| - | imagepng($im); | ||
| - | return $im; | ||
| - | } | ||
| - | } | ||
| - | |||
| - | function render_childs($node, | ||
| - | | ||
| - | $node = $node-> | ||
| - | while ($node!=null) { | ||
| - | | ||
| - | $node = $node-> | ||
| - | } return $childs; | ||
| - | } | ||
| - | |||
| - | function ebnf_scan(& | ||
| - | global $ebnf_lexemes; | ||
| - | $i = 0; $n = strlen($input); | ||
| - | while ($i < $n) { | ||
| - | $j = 0; | ||
| - | while ($j < $m && | ||
| - | preg_match("/ | ||
| - | if ($j<$m) { | ||
| - | if ($ebnf_lexemes[$j][' | ||
| - | $tokens[] = array(' | ||
| - | ' | ||
| - | $i += strlen($matches[0]); | ||
| - | } else | ||
| - | throw new Exception(" | ||
| - | } return $tokens; | ||
| - | } | ||
| - | |||
| - | |||
| - | function ebnf_check_token($token, | ||
| - | return $token[' | ||
| - | } | ||
| - | |||
| - | function ebnf_parse_syntax(& | ||
| - | $dom = new DOMDocument(); | ||
| - | $syntax = $dom-> | ||
| - | $syntax-> | ||
| - | $dom-> | ||
| - | $i = 0; $token = $tokens[$i++]; | ||
| - | if ($token[' | ||
| - | $syntax-> | ||
| - | stripcslashes(substr($token[' | ||
| - | $token = $tokens[$i++]; | ||
| - | } | ||
| - | if (!ebnf_check_token($token, | ||
| - | throw new Exception(" | ||
| - | $token = $tokens[$i]; | ||
| - | while ($i < count($tokens) && $token[' | ||
| - | $syntax-> | ||
| - | if ($i< | ||
| - | } $i++; if (!ebnf_check_token($token, | ||
| - | throw new Exception(" | ||
| - | if ($i< | ||
| - | $token = $tokens[$i]; | ||
| - | if ($token[' | ||
| - | $syntax-> | ||
| - | stripcslashes(substr($token[' | ||
| - | } | ||
| - | } | ||
| - | return $dom; | ||
| - | } | ||
| - | |||
| - | function ebnf_parse_production(& | ||
| - | $token = $tokens[$i++]; | ||
| - | if ($token[' | ||
| - | throw new Exception(" | ||
| - | $production = $dom-> | ||
| - | $production-> | ||
| - | $token = $tokens[$i++]; | ||
| - | if (!ebnf_check_token($token, | ||
| - | throw new Exception(" | ||
| - | $production-> | ||
| - | $token = $tokens[$i++]; | ||
| - | if (!ebnf_check_token($token, | ||
| - | && !ebnf_check_token($token, | ||
| - | throw new Exception(" | ||
| - | return $production; | ||
| - | } | ||
| - | |||
| - | function ebnf_parse_expression(& | ||
| - | $choise = $dom-> | ||
| - | $choise-> | ||
| - | $token=$tokens[$i]; | ||
| - | while (ebnf_check_token($token, | ||
| - | $i++; | ||
| - | $choise-> | ||
| - | $token=$tokens[$i]; | ||
| - | } return $mul ? $choise : $choise-> | ||
| - | } | ||
| - | |||
| - | function ebnf_parse_term(& | ||
| - | $sequence = $dom-> | ||
| - | $factor = ebnf_parse_factor($dom, | ||
| - | $sequence-> | ||
| - | $token=$tokens[$i]; | ||
| - | while ($token[' | ||
| - | && $token[' | ||
| - | $sequence-> | ||
| - | $token=$tokens[$i]; | ||
| - | } return $mul ? $sequence: $sequence-> | ||
| - | } | ||
| - | |||
| - | function ebnf_parse_factor(& | ||
| - | $token = $tokens[$i++]; | ||
| - | if ($token[' | ||
| - | $identifier = $dom-> | ||
| - | $identifier-> | ||
| - | return $identifier; | ||
| - | } if ($token[' | ||
| - | $literal = $dom-> | ||
| - | $literal-> | ||
| - | return $literal; | ||
| - | } if (ebnf_check_token($token, | ||
| - | $expression = ebnf_parse_expression($dom, | ||
| - | $token = $tokens[$i++]; | ||
| - | if (!ebnf_check_token($token, | ||
| - | throw new Exception(" | ||
| - | return $expression; | ||
| - | } if (ebnf_check_token($token, | ||
| - | $option = $dom-> | ||
| - | $option-> | ||
| - | $token = $tokens[$i++]; | ||
| - | if (!ebnf_check_token($token, | ||
| - | throw new Exception(" | ||
| - | return $option; | ||
| - | } if (ebnf_check_token($token, | ||
| - | $loop = $dom-> | ||
| - | $loop-> | ||
| - | $token = $tokens[$i++]; | ||
| - | if (!ebnf_check_token($token, | ||
| - | throw new Exception(" | ||
| - | return $loop; | ||
| - | } | ||
| - | throw new Exception(" | ||
| - | } | ||
| - | |||
| - | ?></ | ||
ebnf/index.1695880309.txt.gz · Zuletzt geändert: von Vincent Tscherter
