alt_if nodes and refactor lists

This commit is contained in:
z7zmey 2017-12-19 00:55:57 +02:00
parent 5b54987ddc
commit dbe1e56e2e
7 changed files with 749 additions and 675 deletions

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"bytes"
"flag" "flag"
"fmt" "fmt"
"log" "log"
@ -20,7 +21,10 @@ func main() {
src, _ := os.Open(string(real)) src, _ := os.Open(string(real))
rootnode := parser.Parse(src, real) rootnode := parser.Parse(src, real)
fmt.Println(rootnode)
buf := new(bytes.Buffer)
rootnode.Print(buf, "")
fmt.Println(buf.String())
} }
} }

20
node/stmt/alt_else.go Normal file
View File

@ -0,0 +1,20 @@
package stmt
import (
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/token"
)
type AltElse struct {
Else
}
func NewAltElse(token token.Token, stmt node.Node) node.Node {
return AltElse{
Else{
node.SimpleNode{Name: "AltElse", Attributes: make(map[string]string)},
token,
stmt,
},
}
}

21
node/stmt/alt_else_if.go Normal file
View File

@ -0,0 +1,21 @@
package stmt
import (
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/token"
)
type AltElseIf struct {
ElseIf
}
func NewAltElseIf(token token.Token, cond node.Node, stmt node.Node) node.Node {
return AltElseIf{
ElseIf{
node.SimpleNode{Name: "AltElseIf", Attributes: make(map[string]string)},
token,
cond,
stmt,
},
}
}

39
node/stmt/alt_if.go Normal file
View File

@ -0,0 +1,39 @@
package stmt
import (
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/token"
)
type AltIf struct {
If
}
func NewAltIf(token token.Token, cond node.Node, stmt node.Node) node.Node {
return AltIf{
If{
node.SimpleNode{Name: "AltIf", Attributes: make(map[string]string)},
token,
cond,
stmt,
nil,
nil,
},
}
}
func (n AltIf) AddElseIf(elseIf node.Node) node.Node {
if n.elseIf == nil {
n.elseIf = make([]node.Node, 0)
}
n.elseIf = append(n.elseIf, elseIf)
return n
}
func (n AltIf) SetElse(_else node.Node) node.Node {
n._else = _else
return n
}

View File

@ -5,27 +5,22 @@ import (
"io" "io"
"github.com/z7zmey/php-parser/node" "github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/token"
) )
type StmtList struct { type StmtList struct {
node.SimpleNode node.SimpleNode
openBracket token.Token stmts []node.Node
closeBracket token.Token
stmts []node.Node
} }
func NewStmtList(openBracket token.Token, closeBracket token.Token, stmts []node.Node) node.Node { func NewStmtList(stmts []node.Node) node.Node {
return StmtList{ return StmtList{
node.SimpleNode{Name: "StmtList", Attributes: make(map[string]string)}, node.SimpleNode{Name: "StmtList", Attributes: make(map[string]string)},
openBracket,
closeBracket,
stmts, stmts,
} }
} }
func (n StmtList) Print(out io.Writer, indent string) { func (n StmtList) Print(out io.Writer, indent string) {
fmt.Fprintf(out, "\n%v%v [%d %d]", indent, n.Name, n.openBracket.StartLine, n.closeBracket.EndLine) fmt.Fprintf(out, "\n%v%v [- -]", indent, n.Name)
if n.stmts != nil { if n.stmts != nil {
fmt.Fprintf(out, "\n%vstmts:", indent+" ") fmt.Fprintf(out, "\n%vstmts:", indent+" ")

File diff suppressed because it is too large Load Diff

View File

@ -16,12 +16,12 @@ import (
"github.com/z7zmey/php-parser/node/expr/cast" "github.com/z7zmey/php-parser/node/expr/cast"
) )
var rootnode = node.NewSimpleNode("Root") var rootnode = stmt.NewStmtList([]node.Node{})
func Parse(src io.Reader, fName string) node.Node { func Parse(src io.Reader, fName string) node.Node {
yyDebug = 0 yyDebug = 0
yyErrorVerbose = true yyErrorVerbose = true
rootnode = node.NewSimpleNode("Root") //reset rootnode = stmt.NewStmtList([]node.Node{}) //reset
yyParse(newLexer(src, fName)) yyParse(newLexer(src, fName))
return rootnode return rootnode
} }
@ -207,11 +207,9 @@ func Parse(src io.Reader, fName string) node.Node {
%type <node> variable_class_name dereferencable_scalar constant dereferencable %type <node> variable_class_name dereferencable_scalar constant dereferencable
%type <node> callable_expr callable_variable static_member new_variable %type <node> callable_expr callable_variable static_member new_variable
%type <node> encaps_var encaps_var_offset %type <node> encaps_var encaps_var_offset
%type <node> top_statement_list inner_statement_list if_stmt %type <node> if_stmt
%type <node> alt_if_stmt %type <node> alt_if_stmt
%type <node> parameter_list class_statement_list
%type <node> implements_list if_stmt_without_else %type <node> implements_list if_stmt_without_else
%type <node> non_empty_parameter_list
%type <node> class_const_decl name_list method_body %type <node> class_const_decl name_list method_body
%type <node> alt_if_stmt_without_else %type <node> alt_if_stmt_without_else
%type <node> array_pair possible_array_pair %type <node> array_pair possible_array_pair
@ -227,14 +225,15 @@ func Parse(src io.Reader, fName string) node.Node {
%type <list> unprefixed_use_declarations inline_use_declarations property_list static_var_list %type <list> unprefixed_use_declarations inline_use_declarations property_list static_var_list
%type <list> switch_case_list case_list trait_adaptation_list trait_adaptations unset_variables %type <list> switch_case_list case_list trait_adaptation_list trait_adaptations unset_variables
%type <list> use_declarations lexical_var_list lexical_vars isset_variables non_empty_array_pair_list %type <list> use_declarations lexical_var_list lexical_vars isset_variables non_empty_array_pair_list
%type <list> array_pair_list ctor_arguments argument_list non_empty_argument_list %type <list> array_pair_list ctor_arguments argument_list non_empty_argument_list top_statement_list
%type <list> inner_statement_list parameter_list non_empty_parameter_list class_statement_list
%% %%
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
start: start:
top_statement_list { rootnode = $1; } top_statement_list { rootnode = stmt.NewStmtList($1); }
; ;
reserved_non_modifiers: reserved_non_modifiers:
@ -258,8 +257,8 @@ identifier:
; ;
top_statement_list: top_statement_list:
top_statement_list top_statement { $$ = $1.Append($2); } top_statement_list top_statement { $$ = append($1, $2) }
| /* empty */ { $$ = node.NewSimpleNode("Statements") } | /* empty */ { $$ = []node.Node{} }
; ;
namespace_name: namespace_name:
@ -282,8 +281,8 @@ top_statement:
| T_HALT_COMPILER '(' ')' ';' { $$ = stmt.NewHaltCompiler($1) } | T_HALT_COMPILER '(' ')' ';' { $$ = stmt.NewHaltCompiler($1) }
| T_NAMESPACE namespace_name ';' { $$ = stmt.NewNamespace($1, name.NewName($2), nil) } | T_NAMESPACE namespace_name ';' { $$ = stmt.NewNamespace($1, name.NewName($2), nil) }
| T_NAMESPACE namespace_name '{' top_statement_list '}' | T_NAMESPACE namespace_name '{' top_statement_list '}'
{ $$ = stmt.NewNamespace($1, name.NewName($2), $4.(node.SimpleNode).Children) } { $$ = stmt.NewNamespace($1, name.NewName($2), $4) }
| T_NAMESPACE '{' top_statement_list '}' { $$ = stmt.NewNamespace($1, nil, $3.(node.SimpleNode).Children) } | T_NAMESPACE '{' top_statement_list '}' { $$ = stmt.NewNamespace($1, nil, $3) }
| T_USE mixed_group_use_declaration ';' { $$ = $2.(stmt.GroupUse).SetToken($1) } | T_USE mixed_group_use_declaration ';' { $$ = $2.(stmt.GroupUse).SetToken($1) }
| T_USE use_type group_use_declaration ';' { $$ = $3.(stmt.GroupUse).SetToken($1).(stmt.GroupUse).SetUseType($2) } | T_USE use_type group_use_declaration ';' { $$ = $3.(stmt.GroupUse).SetToken($1).(stmt.GroupUse).SetUseType($2) }
| T_USE use_declarations ';' { $$ = stmt.NewUseList($1, nil, $2) } | T_USE use_declarations ';' { $$ = stmt.NewUseList($1, nil, $2) }
@ -363,8 +362,8 @@ const_list:
; ;
inner_statement_list: inner_statement_list:
inner_statement_list inner_statement { $$ = $1.Append($2); } inner_statement_list inner_statement { $$ = append($1, $2) }
| /* empty */ { $$ = node.NewSimpleNode("StmtList") } | /* empty */ { $$ = []node.Node{} }
; ;
inner_statement: inner_statement:
@ -376,7 +375,7 @@ inner_statement:
| T_HALT_COMPILER '(' ')' ';' { $$ = stmt.NewHaltCompiler($1) } | T_HALT_COMPILER '(' ')' ';' { $$ = stmt.NewHaltCompiler($1) }
statement: statement:
'{' inner_statement_list '}' { $$ = stmt.NewStmtList($1, $3, $2.(node.SimpleNode).Children) } '{' inner_statement_list '}' { $$ = stmt.NewStmtList($2) }
| if_stmt { $$ = $1; } | if_stmt { $$ = $1; }
| alt_if_stmt { $$ = $1; } | alt_if_stmt { $$ = $1; }
| T_WHILE '(' expr ')' while_statement | T_WHILE '(' expr ')' while_statement
@ -403,7 +402,7 @@ statement:
| ';' { $$ = stmt.NewNop($1) } | ';' { $$ = stmt.NewNop($1) }
| T_TRY '{' inner_statement_list '}' catch_list finally_statement | T_TRY '{' inner_statement_list '}' catch_list finally_statement
{ {
$$ = stmt.NewTry($1, $3.(node.SimpleNode).Children, $5, $6) $$ = stmt.NewTry($1, $3, $5, $6)
} }
| T_THROW expr ';' { $$ = stmt.NewThrow($1, $2) } | T_THROW expr ';' { $$ = stmt.NewThrow($1, $2) }
| T_GOTO T_STRING ';' { $$ = stmt.NewGoto($1, $2) } | T_GOTO T_STRING ';' { $$ = stmt.NewGoto($1, $2) }
@ -412,7 +411,7 @@ statement:
catch_list: catch_list:
/* empty */ { $$ = []node.Node{} } /* empty */ { $$ = []node.Node{} }
| catch_list T_CATCH '(' catch_name_list T_VARIABLE ')' '{' inner_statement_list '}' | catch_list T_CATCH '(' catch_name_list T_VARIABLE ')' '{' inner_statement_list '}'
{ $$ = append($1, stmt.NewCatch($2, $4, expr.NewVariable(node.NewIdentifier($5)), $8.(node.SimpleNode).Children)) } { $$ = append($1, stmt.NewCatch($2, $4, expr.NewVariable(node.NewIdentifier($5)), $8)) }
; ;
catch_name_list: catch_name_list:
name { $$ = []node.Node{$1} } name { $$ = []node.Node{$1} }
@ -421,7 +420,7 @@ catch_name_list:
finally_statement: finally_statement:
/* empty */ { $$ = nil } /* empty */ { $$ = nil }
| T_FINALLY '{' inner_statement_list '}' { $$ = stmt.NewFinally($1, $3.(node.SimpleNode).Children) } | T_FINALLY '{' inner_statement_list '}' { $$ = stmt.NewFinally($1, $3) }
; ;
unset_variables: unset_variables:
@ -436,7 +435,7 @@ unset_variable:
function_declaration_statement: function_declaration_statement:
T_FUNCTION returns_ref T_STRING '(' parameter_list ')' return_type '{' inner_statement_list '}' T_FUNCTION returns_ref T_STRING '(' parameter_list ')' return_type '{' inner_statement_list '}'
{ {
$$ = stmt.NewFunction($3, $2 == "true", $5.(node.SimpleNode).Children, $7, $9.(node.SimpleNode).Children) $$ = stmt.NewFunction($3, $2 == "true", $5, $7, $9)
} }
; ;
@ -452,9 +451,9 @@ is_variadic:
class_declaration_statement: class_declaration_statement:
class_modifiers T_CLASS T_STRING extends_from implements_list '{' class_statement_list '}' class_modifiers T_CLASS T_STRING extends_from implements_list '{' class_statement_list '}'
{ $$ = stmt.NewClass($3, $1, nil, $4, $5.(node.SimpleNode).Children, $7.(node.SimpleNode).Children) } { $$ = stmt.NewClass($3, $1, nil, $4, $5.(node.SimpleNode).Children, $7) }
| T_CLASS T_STRING extends_from implements_list '{' class_statement_list '}' | T_CLASS T_STRING extends_from implements_list '{' class_statement_list '}'
{ $$ = stmt.NewClass($2, nil, nil, $3, $4.(node.SimpleNode).Children, $6.(node.SimpleNode).Children) } { $$ = stmt.NewClass($2, nil, nil, $3, $4.(node.SimpleNode).Children, $6) }
; ;
class_modifiers: class_modifiers:
@ -468,12 +467,12 @@ class_modifier:
; ;
trait_declaration_statement: trait_declaration_statement:
T_TRAIT T_STRING '{' class_statement_list '}' { $$ = stmt.NewTrait($2, $4.(node.SimpleNode).Children) } T_TRAIT T_STRING '{' class_statement_list '}' { $$ = stmt.NewTrait($2, $4) }
; ;
interface_declaration_statement: interface_declaration_statement:
T_INTERFACE T_STRING interface_extends_list '{' class_statement_list '}' T_INTERFACE T_STRING interface_extends_list '{' class_statement_list '}'
{ $$ = stmt.NewInterface($1, $2, $3, $5.(node.SimpleNode).Children) } { $$ = stmt.NewInterface($1, $2, $3, $5) }
; ;
extends_from: extends_from:
@ -500,17 +499,17 @@ foreach_variable:
for_statement: for_statement:
statement { $$ = $1; } statement { $$ = $1; }
| ':' inner_statement_list T_ENDFOR ';' { $$ = $2; } | ':' inner_statement_list T_ENDFOR ';' { $$ = stmt.NewStmtList($2); }
; ;
foreach_statement: foreach_statement:
statement { $$ = $1; } statement { $$ = $1; }
| ':' inner_statement_list T_ENDFOREACH ';' { $$ = $2; } | ':' inner_statement_list T_ENDFOREACH ';' { $$ = stmt.NewStmtList($2); }
; ;
declare_statement: declare_statement:
statement { $$ = $1; } statement { $$ = $1; }
| ':' inner_statement_list T_ENDDECLARE ';' { $$ = $2; } | ':' inner_statement_list T_ENDDECLARE ';' { $$ = stmt.NewStmtList($2); }
; ;
switch_case_list: switch_case_list:
@ -524,11 +523,11 @@ case_list:
/* empty */ { $$ = []node.Node{} } /* empty */ { $$ = []node.Node{} }
| case_list T_CASE expr case_separator inner_statement_list | case_list T_CASE expr case_separator inner_statement_list
{ {
$$ = append($1, stmt.NewCase($2, $3, $5.(node.SimpleNode).Children)) $$ = append($1, stmt.NewCase($2, $3, $5))
} }
| case_list T_DEFAULT case_separator inner_statement_list | case_list T_DEFAULT case_separator inner_statement_list
{ {
$$ = append($1, stmt.NewDefault($2, $4.(node.SimpleNode).Children)) $$ = append($1, stmt.NewDefault($2, $4))
} }
; ;
@ -539,7 +538,7 @@ case_separator:
while_statement: while_statement:
statement { $$ = $1; } statement { $$ = $1; }
| ':' inner_statement_list T_ENDWHILE ';' { $$ = $2; } | ':' inner_statement_list T_ENDWHILE ';' { $$ = stmt.NewStmtList($2); }
; ;
if_stmt_without_else: if_stmt_without_else:
@ -563,15 +562,12 @@ if_stmt:
alt_if_stmt_without_else: alt_if_stmt_without_else:
T_IF '(' expr ')' ':' inner_statement_list T_IF '(' expr ')' ':' inner_statement_list
{ {
$$ = node.NewSimpleNode("AltIf"). $$ = stmt.NewAltIf($1, $3, stmt.NewStmtList($6))
Append(node.NewSimpleNode("expr").Append($3)).
Append(node.NewSimpleNode("stmt").Append($6))
} }
| alt_if_stmt_without_else T_ELSEIF '(' expr ')' ':' inner_statement_list | alt_if_stmt_without_else T_ELSEIF '(' expr ')' ':' inner_statement_list
{ {
$$ = $1.Append(node.NewSimpleNode("AltElseIf"). _elseIf := stmt.NewAltElseIf($2, $4, stmt.NewStmtList($7))
Append(node.NewSimpleNode("expr").Append($4)). $$ = $1.(stmt.AltIf).AddElseIf(_elseIf)
Append(node.NewSimpleNode("stmt").Append($7)))
} }
; ;
@ -579,18 +575,19 @@ alt_if_stmt:
alt_if_stmt_without_else T_ENDIF ';' { $$ = $1; } alt_if_stmt_without_else T_ENDIF ';' { $$ = $1; }
| alt_if_stmt_without_else T_ELSE ':' inner_statement_list T_ENDIF ';' | alt_if_stmt_without_else T_ELSE ':' inner_statement_list T_ENDIF ';'
{ {
$$ = $1.Append(node.NewSimpleNode("AltElse").Append(node.NewSimpleNode("stmt").Append($4))) _else := stmt.NewAltElse($2, stmt.NewStmtList($4))
$$ = $1.(stmt.AltIf).SetElse(_else)
} }
; ;
parameter_list: parameter_list:
non_empty_parameter_list { $$ = $1; } non_empty_parameter_list { $$ = $1; }
| /* empty */ { $$ = node.NewSimpleNode("Parameter list"); } | /* empty */ { $$ = nil }
; ;
non_empty_parameter_list: non_empty_parameter_list:
parameter { $$ = node.NewSimpleNode("Parameter list").Append($1) } parameter { $$ = []node.Node{$1} }
| non_empty_parameter_list ',' parameter { $$ = $1.Append($3); } | non_empty_parameter_list ',' parameter { $$ = append($1, $3) }
; ;
parameter: parameter:
@ -669,8 +666,8 @@ static_var:
; ;
class_statement_list: class_statement_list:
class_statement_list class_statement { $$ = $1.Append($2) } class_statement_list class_statement { $$ = append($1, $2) }
| /* empty */ { $$ = node.NewSimpleNode("Stmt") } | /* empty */ { $$ = []node.Node{} }
; ;
class_statement: class_statement:
@ -679,7 +676,7 @@ class_statement:
| T_USE name_list trait_adaptations { $$ = stmt.NewTraitUse($1, $2.(node.SimpleNode).Children, $3) } | T_USE name_list trait_adaptations { $$ = stmt.NewTraitUse($1, $2.(node.SimpleNode).Children, $3) }
| method_modifiers T_FUNCTION returns_ref identifier '(' parameter_list ')' return_type method_body | method_modifiers T_FUNCTION returns_ref identifier '(' parameter_list ')' return_type method_body
{ {
$$ = stmt.NewClassMethod($4, $1.(node.SimpleNode).Children, $3 == "true", $6.(node.SimpleNode).Children, $8, $9.(node.SimpleNode).Children) $$ = stmt.NewClassMethod($4, $1.(node.SimpleNode).Children, $3 == "true", $6, $8, $9.(node.SimpleNode).Children)
} }
; ;
@ -732,7 +729,7 @@ absolute_trait_method_reference:
method_body: method_body:
';' /* abstract method */ { $$ = node.NewSimpleNode("") } ';' /* abstract method */ { $$ = node.NewSimpleNode("") }
| '{' inner_statement_list '}' { $$ = $2; } | '{' inner_statement_list '}' { $$ = stmt.NewStmtList($2) }
; ;
variable_modifiers: variable_modifiers:
@ -803,7 +800,7 @@ non_empty_for_exprs:
anonymous_class: anonymous_class:
T_CLASS ctor_arguments extends_from implements_list '{' class_statement_list '}' T_CLASS ctor_arguments extends_from implements_list '{' class_statement_list '}'
{ {
{ $$ = stmt.NewClass($1, nil, $2, $3, $4.(node.SimpleNode).Children, $6.(node.SimpleNode).Children) } { $$ = stmt.NewClass($1, nil, $2, $3, $4.(node.SimpleNode).Children, $6) }
} }
; ;
@ -897,11 +894,11 @@ expr_without_variable:
| T_YIELD_FROM expr { $$ = expr.NewYieldFrom($2) } | T_YIELD_FROM expr { $$ = expr.NewYieldFrom($2) }
| T_FUNCTION returns_ref '(' parameter_list ')' lexical_vars return_type '{' inner_statement_list '}' | T_FUNCTION returns_ref '(' parameter_list ')' lexical_vars return_type '{' inner_statement_list '}'
{ {
$$ = expr.NewClosure($4.(node.SimpleNode).Children, $6, $7, $9.(node.SimpleNode).Children, false, $2 == "true") $$ = expr.NewClosure($4, $6, $7, $9, false, $2 == "true")
} }
| T_STATIC T_FUNCTION returns_ref '(' parameter_list ')' lexical_vars return_type '{' inner_statement_list '}' | T_STATIC T_FUNCTION returns_ref '(' parameter_list ')' lexical_vars return_type '{' inner_statement_list '}'
{ {
$$ = expr.NewClosure($5.(node.SimpleNode).Children, $7, $8, $10.(node.SimpleNode).Children, true, $3 == "true") $$ = expr.NewClosure($5, $7, $8, $10, true, $3 == "true")
} }
; ;