/*!
* Copyright (C) 2017 Glayzzle (BSD3 License)
* @authors https://github.com/glayzzle/php-parser/graphs/contributors
* @url http://glayzzle.com
*/
"use strict";
module.exports = {
/**
* Reads a switch statement
* ```ebnf
* switch ::= T_SWITCH '(' expr ')' switch_case_list
* ```
* @return {Switch}
* @see http://php.net/manual/en/control-structures.switch.php
*/
read_switch: function() {
this.expect(this.tok.T_SWITCH) && this.next();
var result = this.node('switch'), test, body, shortForm;
this.expect('(') && this.next();
test = this.read_expr();
this.expect(')') && this.next();
shortForm = (this.token === ':');
body = this.read_switch_case_list();
return result(test, body, shortForm);
}
/**
* ```ebnf
* switch_case_list ::= '{' ';'? case_list* '}' | ':' ';'? case_list* T_ENDSWITCH ';'
* ```
* @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L566
*/
,read_switch_case_list: function() {
// DETECT SWITCH MODE
var expect = null,
result = this.node('block'),
items = [];
if (this.token === '{') {
expect = '}';
} else if (this.token === ':') {
expect = this.tok.T_ENDSWITCH;
} else {
this.expect(['{', ':']);
}
// OPTIONNAL ';'
// https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L570
if (this.next().token === ';') {
this.next();
}
// IGNORE THE CLOSE TAG TOKEN WITH SHORT MODE
if (this.token === this.tok.T_CLOSE_TAG) {
this.next();
}
// EXTRACTING CASES
while(this.token !== this.EOF && this.token !== expect) {
items.push( this.read_case_list(expect) );
}
// CHECK END TOKEN
this.expect(expect) && this.next();
if (expect === this.tok.T_ENDSWITCH) {
this.expectEndOfStatement();
}
return result(null, items);
}
/**
* ```ebnf
* case_list ::= ((T_CASE expr) | T_DEFAULT) (':' | ';') inner_statement*
* ```
*/
,read_case_list: function(stopToken) {
var result = this.node('case'), test = null, body = null, items = [];
if (this.token === this.tok.T_CASE) {
test = this.next().read_expr();
} else if (this.token === this.tok.T_DEFAULT) {
// the defaut entry - no condition
this.next();
} else {
this.expect([this.tok.T_CASE, this.tok.T_DEFAULT]);
}
this.expect([':', ';']) && this.next();
body = this.node('block');
while(
this.token != this.EOF
&& this.token !== stopToken
&& this.token !== this.tok.T_CASE
&& this.token !== this.tok.T_DEFAULT
) {
items.push(this.read_inner_statement());
}
return result(
test, items.length > 0 ? body(null, items) : null
);
}
};
|