[ Index ] |
PHP Cross Reference of vtigercrm-6.1.0 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Base class for lexers 4 */ 5 abstract class AntlrLexer extends BaseRecognizer{ 6 public static $DEFAULT_TOKEN_CHANNEL = 0; 7 protected $input; 8 9 public function __construct($input, $state=null) { 10 if($state==null){ 11 $state = new RecognizerSharedState(); 12 } 13 $this->state = $state; 14 $this->input = $input; 15 } 16 17 public function reset() { 18 parent::reset(); // reset all recognizer state variables 19 // wack Lexer state variables 20 if ( $this->input!=null ) { 21 $this->input->seek(0); // rewind the input 22 } 23 if ( $this->state==null ) { 24 return; // no shared state work to do 25 } 26 $this->state->token = null; 27 $this->state->type = TokenConst::$INVALID_TOKEN_TYPE; 28 $this->state->channel = TokenConst::$DEFAULT_CHANNEL; 29 $this->state->tokenStartCharIndex = -1; 30 $this->state->tokenStartCharPositionInLine = -1; 31 $this->state->tokenStartLine = -1; 32 $this->state->text = null; 33 } 34 35 36 /** Return a token from this source; i.e., match a token on the char 37 * stream. 38 */ 39 public function nextToken() { 40 while (true) { 41 $this->state->token = null; 42 $this->state->channel = 0;//Token::DEFAULT_CHANNEL; 43 $this->state->tokenStartCharIndex = $this->input->index(); 44 $this->state->tokenStartCharPositionInLine = $this->input->getCharPositionInLine(); 45 $this->state->tokenStartLine = $this->input->getLine(); 46 $this->state->text = null; 47 if ( $this->input->LA(1)==CharStreamConst::$EOF ) { 48 return TokenConst::$EOF_TOKEN; 49 } 50 try { 51 $this->mTokens(); 52 if ( $this->state->token==null ) { 53 $this->emit(); 54 } 55 else if ( $this->state->token==Token::$SKIP_TOKEN ) { 56 continue; 57 } 58 return $this->state->token; 59 } 60 catch (NoViableAltException $nva) { 61 $this->reportError($nva); 62 $this->recover($nva); // throw out current char and try again 63 } 64 catch (RecognitionException $re) { 65 $this->reportError($re); 66 // match() routine has already called recover() 67 } 68 } 69 } 70 71 /** Instruct the lexer to skip creating a token for current lexer rule 72 * and look for another token. nextToken() knows to keep looking when 73 * a lexer rule finishes with token set to SKIP_TOKEN. Recall that 74 * if token==null at end of any token rule, it creates one for you 75 * and emits it. 76 */ 77 public function skip() { 78 $this->state->token = TokenConst::$SKIP_TOKEN; 79 } 80 81 /** This is the lexer entry point that sets instance var 'token' */ 82 public abstract function mTokens(); 83 84 /** Set the char stream and reset the lexer */ 85 public function setCharStream($input) { 86 $this->input = null; 87 $this->reset(); 88 $this->input = $input; 89 } 90 91 public function getCharStream() { 92 return $this->input; 93 } 94 95 public function getSourceName() { 96 return $this->input->getSourceName(); 97 } 98 99 /** Currently does not support multiple emits per nextToken invocation 100 * for efficiency reasons. Subclass and override this method and 101 * nextToken (to push tokens into a list and pull from that list rather 102 * than a single variable as this implementation does). 103 */ 104 /** The standard method called to automatically emit a token at the 105 * outermost lexical rule. The token object should point into the 106 * char buffer start..stop. If there is a text override in 'text', 107 * use that to set the token's text. Override this method to emit 108 * custom Token objects. 109 * 110 * If you are building trees, then you should also override 111 * Parser or TreeParser.getMissingSymbol(). 112 */ 113 public function emit($token=null) { 114 if($token==null){ 115 $token = CommonToken::forInput($this->input, $this->state->type, $this->state->channel, 116 $this->state->tokenStartCharIndex, $this->getCharIndex()-1); 117 $token->setLine($this->state->tokenStartLine); 118 $token->setText($this->state->text); 119 $token->setCharPositionInLine($this->state->tokenStartCharPositionInLine); 120 } 121 $this->state->token = $token; 122 return $token; 123 } 124 125 function matchString($s){ 126 $i = 0; 127 while ( $i<strlen($s)) { 128 if ( $this->input->LA(1)!=charAt($s, $i) ) { 129 if ( $this->state->backtracking>0 ) { 130 $this->state->failed = true; 131 return; 132 } 133 $mte = new MismatchedTokenException(charAt($s, $i), $this->input); 134 $this->recover($mte); 135 throw $mte; 136 } 137 $i++; 138 $this->input->consume(); 139 $state->failed = false; 140 } 141 } 142 143 public function matchAny() { 144 $this->input->consume(); 145 } 146 147 public function matchChar($c) { 148 if ($this->input->LA(1)!=$c ) { 149 if ( $this->state->backtracking>0 ) { 150 $this->state->failed = true; 151 return; 152 } 153 $mte = new MismatchedTokenException($c, $this->input); 154 $this->recover($mte); // don't really recover; just consume in lexer 155 throw $mte; 156 } 157 $this->input->consume(); 158 $this->state->failed = false; 159 } 160 161 public function matchRange($a, $b) { 162 if ( $this->input->LA(1)<$a || $this->input->LA(1)>$b ) { 163 if ( $this->state->backtracking>0 ) { 164 $this->state->failed = true; 165 return; 166 } 167 $mre = new MismatchedRangeException($a, $b, $this->input); 168 $this->recover($mre); 169 throw $mre; 170 } 171 $this->input->consume(); 172 $this->state->failed = false; 173 } 174 175 public function getLine() { 176 return $this->input->getLine(); 177 } 178 179 public function getCharPositionInLine() { 180 return $this->input->getCharPositionInLine(); 181 } 182 183 /** What is the index of the current character of lookahead? */ 184 public function getCharIndex() { 185 return $this->input->index(); 186 } 187 188 189 /** Return the text matched so far for the current token or any 190 * text override. 191 */ 192 public function getText() { 193 if ( $this->state->text!=null ) { 194 return $this->state->text; 195 } 196 return $this->input->substring($this->state->tokenStartCharIndex,$this->getCharIndex()-1); 197 } 198 199 /** Set the complete text of this token; it wipes any previous 200 * changes to the text. 201 */ 202 public function setText($text) { 203 $this->state->text = $text; 204 } 205 206 public function reportError($e) { 207 /** TODO: not thought about recovery in lexer yet. 208 * 209 // if we've already reported an error and have not matched a token 210 // yet successfully, don't report any errors. 211 if ( errorRecovery ) { 212 //System.err.print("[SPURIOUS] "); 213 return; 214 } 215 errorRecovery = true; 216 */ 217 218 $this->displayRecognitionError($this->getTokenNames(), $e); 219 } 220 221 public function getErrorMessage($e, $tokenNames) { 222 $msg = null; 223 if ( $e instanceof MismatchedTokenException ) { 224 $mte = $e; 225 $msg = "mismatched character ".$this->getCharErrorDisplay($e->c). 226 " expecting ".$this->getCharErrorDisplay($mte->expecting); 227 } 228 else if ( $e instanceof NoViableAltException ) { 229 $nvae = $e; 230 // for development, can add "decision=<<"+nvae.grammarDecisionDescription+">>" 231 // and "(decision="+nvae.decisionNumber+") and 232 // "state "+nvae.stateNumber 233 $msg = "no viable alternative at character ".$this->getCharErrorDisplay($e->c); 234 } 235 else if ( $e instanceof EarlyExitException ) { 236 $eee = $e; 237 // for development, can add "(decision="+eee.decisionNumber+")" 238 $msg = "required (...)+ loop did not match anything at character ".$this->getCharErrorDisplay($e->c); 239 } 240 else if ( $e instanceof MismatchedNotSetException ) { 241 $mse = $e; 242 $msg = "mismatched character ".$this->getCharErrorDisplay($e->c)." expecting set ".$mse->expecting; 243 } 244 else if ( $e instanceof MismatchedSetException ) { 245 $mse = $e; 246 $msg = "mismatched character ".$this->getCharErrorDisplay($e->c)." expecting set ".$mse->expecting; 247 } 248 else if ( $e instanceof MismatchedRangeException ) { 249 $mre = $e; 250 $msg = "mismatched character ".$this->getCharErrorDisplay($e->c)." expecting set ". 251 $this->getCharErrorDisplay($mre->a)."..".$this->getCharErrorDisplay($mre->b); 252 } 253 else { 254 $msg = parent::getErrorMessage($e, $tokenNames); 255 } 256 return $msg; 257 } 258 259 public function getCharErrorDisplay($c) { 260 $s = chr($c); 261 switch ( $s ) { 262 case '\n' : 263 $s = "\\n"; 264 break; 265 case '\t' : 266 $s = "\\t"; 267 break; 268 case '\r' : 269 $s = "\\r"; 270 break; 271 } 272 if ($c==TokenConst::$EOF){ 273 $s = "<EOF>"; 274 } 275 return "'".$s."'"; 276 } 277 278 /** Lexers can normally match any char in it's vocabulary after matching 279 * a token, so do the easy thing and just kill a character and hope 280 * it all works out. You can instead use the rule invocation stack 281 * to do sophisticated error recovery if you are in a fragment rule. 282 */ 283 public function recover($re) { 284 $this->input->consume(); 285 } 286 287 288 public function traceIn($ruleName, $ruleIndex) { 289 $inputSymbol = $this->input->LT(1)." line=".$this->getLine().":".$this->getCharPositionInLine(); 290 parent::traceIn($ruleName, $ruleIndex, $inputSymbol); 291 } 292 293 public function traceOut($ruleName, $ruleIndex) { 294 $inputSymbol = $this->input->LT(1)." line=".$this->getLine().":".$this->getCharPositionInLine(); 295 parent::traceOut($ruleName, $ruleIndex, $inputSymbol); 296 } 297 } 298 299 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:08:37 2014 | Cross-referenced by PHPXref 0.7.1 |