File modules/dsl/ast/DslElement.class.php

Last commit: Wed Jun 1 00:11:40 2022 +0200	Jan Dankert	New: DSL as a filter for number values
1 <?php 2 3 namespace dsl\ast; 4 5 use dsl\DslParserException; 6 use dsl\DslToken; 7 8 class DslElement 9 { 10 11 /** 12 * 13 * @param $tokens DslToken[] 14 * @return DslToken[] 15 * @throws DslParserException 16 */ 17 protected function getGroup(&$tokens) 18 { 19 $groupTokens = []; 20 $depth = 0; 21 22 $nextToken = array_shift($tokens); 23 if ($nextToken == null) 24 throw new DslParserException('Unexpecting end, missing closing group'); 25 if ($nextToken->type != DslToken::T_BRACKET_OPEN) 26 throw new DslParserException('Expecting parenthesis', $nextToken->lineNumber); 27 28 while (true) { 29 $nextToken = array_shift($tokens); 30 if ($nextToken == null) 31 throw new DslParserException('Unclosed parenthesis'); 32 if ($nextToken->type == DslToken::T_BRACKET_OPEN) 33 $depth += 1; 34 if ($nextToken->type == DslToken::T_BRACKET_CLOSE) 35 if ($depth == 0) 36 return $groupTokens; 37 else 38 $depth--; 39 40 $groupTokens[] = $nextToken; 41 } 42 } 43 44 /** 45 * 46 * @param $tokens DslToken[] 47 * @return DslToken[] 48 * @throws DslParserException 49 */ 50 protected function getBlock(&$tokens) 51 { 52 $blockTokens = []; 53 $depth = 0; 54 55 $nextToken = array_shift($tokens); 56 if ($nextToken->type != DslToken::T_BLOCK_BEGIN) 57 throw new DslParserException('Expecting block', $nextToken->lineNumber); 58 59 while (true) { 60 $nextToken = array_shift($tokens); 61 if ($nextToken->type == null) 62 throw new DslParserException('Unclosed block', $nextToken->lineNumber); 63 if ($nextToken->type == DslToken::T_BLOCK_BEGIN) 64 $depth += 1; 65 if ($nextToken->type == DslToken::T_BLOCK_END) 66 if ($depth == 0) 67 return $blockTokens; 68 else 69 $depth--; 70 71 $blockTokens[] = $nextToken; 72 } 73 } 74 75 /** 76 * 77 * @param $tokens DslToken[] 78 * @return DslToken[] 79 * @throws DslParserException 80 */ 81 protected function getStatementOrBlock(&$tokens) 82 { 83 if (!$tokens) 84 return []; 85 86 $firstToken = $tokens[0]; 87 if ($firstToken->type == DslToken::T_BLOCK_BEGIN) 88 return $this->getBlock($tokens); 89 else 90 return $this->getSingleStatement($tokens,true); 91 } 92 93 94 /** 95 * Gets the first single statement out of the tokens. 96 * 97 * @param $tokens DslToken[] 98 * @return DslToken[] 99 * @throws DslParserException 100 */ 101 protected function getSingleStatement(&$tokens, $withEnd = false) 102 { 103 $depth = 0; 104 $statementTokens = []; 105 while (true) { 106 $nextToken = array_shift($tokens); 107 if ($nextToken == null) 108 var_export( $statementTokens ); 109 if ($nextToken == null) 110 throw new DslParserException('unrecognized statement'); 111 112 if ($depth == 0 && $nextToken->type == DslToken::T_STATEMENT_END) { 113 if ( $withEnd ) 114 $statementTokens[] = $nextToken; 115 return $statementTokens; 116 } 117 118 if ($nextToken->type == DslToken::T_BLOCK_BEGIN) 119 $depth++; 120 if ($nextToken->type == DslToken::T_BLOCK_END) 121 $depth--; 122 if ($depth < 0) 123 throw new DslParserException('Unexpected closing block', $nextToken->lineNumber); 124 125 $statementTokens[] = $nextToken; 126 } 127 } 128 129 130 /** 131 * Split tokens on comma separator. 132 * 133 * @param DslToken[] $functionParameter 134 * @return DslToken[][] 135 */ 136 protected function splitByComma($functionParameter) 137 { 138 $parts = []; 139 $act = []; 140 foreach ( $functionParameter as $token ) { 141 142 if ( $token->type == DslToken::T_OPERATOR && $token->value == ',' ) { 143 $parts[] = $act; 144 $act = []; // Cleanup 145 continue; 146 } 147 148 $act[] = $token; 149 } 150 151 if ( $act ) 152 $parts[] = $act; 153 154 return $parts; 155 } 156 }
Download modules/dsl/ast/DslElement.class.php
History Wed, 1 Jun 2022 00:11:40 +0200 Jan Dankert New: DSL as a filter for number values Sun, 29 May 2022 16:56:40 +0200 Jan Dankert New: DSL with support for functions with return values, full arithmetic, object properties Sun, 29 May 2022 01:13:27 +0200 Jan Dankert New: DSL with support for functions Wed, 25 May 2022 22:47:17 +0200 Jan Dankert New: DSL (domain specific language) for code elements. The old way with PHP code ist not sandboxed and unsecure. This approach is a minimalistic, javascript-like, scripting engine. For now only simple function calls are possible, for example: alert("example");