string nodes
This commit is contained in:
parent
4da2844ea8
commit
1c1926516e
10
example.php
10
example.php
@ -27,13 +27,17 @@ $a = "string
|
|||||||
with $var
|
with $var
|
||||||
";
|
";
|
||||||
|
|
||||||
$a = 'string
|
$a = "string
|
||||||
with out $var';
|
with out \$var";
|
||||||
|
|
||||||
$a = <<<test
|
$a = <<<test
|
||||||
string
|
string $var
|
||||||
test;
|
test;
|
||||||
|
|
||||||
|
`test
|
||||||
|
$var
|
||||||
|
`;
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<?= $b = 22; $b ?>
|
<?= $b = 22; $b ?>
|
33
node/node_expr_shellexec.go
Normal file
33
node/node_expr_shellexec.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package node
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/z7zmey/php-parser/token"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
type NodeExprShellExec struct {
|
||||||
|
*simpleNode
|
||||||
|
startToken token.Token
|
||||||
|
endToken token.Token
|
||||||
|
parts []Node
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func NewNodeExprShellExec(startToken token.Token, parts []Node, endToken token.Token) Node {
|
||||||
|
return NodeExprShellExec{
|
||||||
|
&simpleNode{name: "NodeExprShellExec", attributes: make(map[string]string)},
|
||||||
|
startToken,
|
||||||
|
endToken,
|
||||||
|
parts,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n NodeExprShellExec) Print(out io.Writer, indent string) {
|
||||||
|
fmt.Fprintf(out, "\n%v%v [%d %d]", indent, n.name, n.startToken.StartLine, n.endToken.EndLine)
|
||||||
|
fmt.Fprintf(out, "\n%vparts:", indent+" ",)
|
||||||
|
for _, nn := range n.parts {
|
||||||
|
nn.Print(out, indent+" ")
|
||||||
|
}
|
||||||
|
}
|
33
node/node_scalar_encapsed.go
Normal file
33
node/node_scalar_encapsed.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package node
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/z7zmey/php-parser/token"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
type NodeScalarEncapsed struct {
|
||||||
|
*simpleNode
|
||||||
|
startToken token.Token
|
||||||
|
endToken token.Token
|
||||||
|
parts []Node
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func NewNodeScalarEncapsed(startToken token.Token, parts []Node, endToken token.Token) Node {
|
||||||
|
return NodeScalarEncapsed{
|
||||||
|
&simpleNode{name: "NodeScalarEncapsed", attributes: make(map[string]string)},
|
||||||
|
startToken,
|
||||||
|
endToken,
|
||||||
|
parts,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n NodeScalarEncapsed) Print(out io.Writer, indent string) {
|
||||||
|
fmt.Fprintf(out, "\n%v%v [%d %d]", indent, n.name, n.startToken.StartLine, n.endToken.EndLine)
|
||||||
|
fmt.Fprintf(out, "\n%vparts:", indent+" ",)
|
||||||
|
for _, nn := range n.parts {
|
||||||
|
nn.Print(out, indent+" ")
|
||||||
|
}
|
||||||
|
}
|
27
node/node_scalar_encapsed_string_part.go
Normal file
27
node/node_scalar_encapsed_string_part.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package node
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/z7zmey/php-parser/token"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
type NodeScalarEncapsedStringPart struct {
|
||||||
|
*simpleNode
|
||||||
|
token token.Token
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func NewNodeScalarEncapsedStringPart(t token.Token) Node {
|
||||||
|
return NodeScalarEncapsedStringPart{
|
||||||
|
&simpleNode{name: "NodeScalarEncapsedStringPart", attributes: make(map[string]string)},
|
||||||
|
t,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n NodeScalarEncapsedStringPart) Print(out io.Writer, indent string) {
|
||||||
|
fmt.Fprintf(out, "\n%v%v [%d %d] %q", indent, n.name, n.token.StartLine, n.token.EndLine, n.token.Value)
|
||||||
|
for _, nn := range n.children {
|
||||||
|
nn.Print(out, indent+" ")
|
||||||
|
}
|
||||||
|
}
|
28
node/node_scalar_string.go
Normal file
28
node/node_scalar_string.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package node
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/z7zmey/php-parser/token"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
type NodeScalarString struct {
|
||||||
|
*simpleNode
|
||||||
|
token token.Token
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func NewNodeScalarString(t token.Token) Node {
|
||||||
|
return NodeScalarString{
|
||||||
|
&simpleNode{name: "NodeScalarString", attributes: make(map[string]string)},
|
||||||
|
t,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n NodeScalarString) Print(out io.Writer, indent string) {
|
||||||
|
fmt.Fprintf(out, "\n%v%v [%d %d] %q", indent, n.name, n.token.StartLine, n.token.EndLine, n.token.Value)
|
||||||
|
for _, nn := range n.children {
|
||||||
|
nn.Print(out, indent+" ")
|
||||||
|
}
|
||||||
|
}
|
33
parser.y
33
parser.y
@ -10,6 +10,8 @@ import (
|
|||||||
var rootnode = node.SimpleNode("Root")
|
var rootnode = node.SimpleNode("Root")
|
||||||
|
|
||||||
func parse(src io.Reader, fName string) node.Node {
|
func parse(src io.Reader, fName string) node.Node {
|
||||||
|
yyDebug = 0
|
||||||
|
yyErrorVerbose = true
|
||||||
rootnode = node.SimpleNode("Root") //reset
|
rootnode = node.SimpleNode("Root") //reset
|
||||||
yyParse(newLexer(src, fName))
|
yyParse(newLexer(src, fName))
|
||||||
return rootnode
|
return rootnode
|
||||||
@ -21,6 +23,7 @@ func parse(src io.Reader, fName string) node.Node {
|
|||||||
node node.Node
|
node node.Node
|
||||||
token token.Token
|
token token.Token
|
||||||
value string
|
value string
|
||||||
|
list []node.Node
|
||||||
}
|
}
|
||||||
|
|
||||||
%left T_INCLUDE T_INCLUDE_ONCE T_EVAL T_REQUIRE T_REQUIRE_ONCE
|
%left T_INCLUDE T_INCLUDE_ONCE T_EVAL T_REQUIRE T_REQUIRE_ONCE
|
||||||
@ -158,6 +161,8 @@ func parse(src io.Reader, fName string) node.Node {
|
|||||||
%token <token> T_PRIVATE
|
%token <token> T_PRIVATE
|
||||||
%token <token> T_PROTECTED
|
%token <token> T_PROTECTED
|
||||||
%token <token> T_PUBLIC
|
%token <token> T_PUBLIC
|
||||||
|
%token <token> '"'
|
||||||
|
%token <token> '`'
|
||||||
|
|
||||||
%type <value> is_reference
|
%type <value> is_reference
|
||||||
%type <value> is_variadic
|
%type <value> is_variadic
|
||||||
@ -180,7 +185,7 @@ func parse(src io.Reader, fName string) node.Node {
|
|||||||
%type <node> absolute_trait_method_reference trait_method_reference property echo_expr
|
%type <node> absolute_trait_method_reference trait_method_reference property echo_expr
|
||||||
%type <node> new_expr anonymous_class class_name class_name_reference simple_variable
|
%type <node> new_expr anonymous_class class_name class_name_reference simple_variable
|
||||||
%type <node> internal_functions_in_yacc
|
%type <node> internal_functions_in_yacc
|
||||||
%type <node> exit_expr scalar backticks_expr lexical_var function_call member_name property_name
|
%type <node> exit_expr scalar lexical_var function_call member_name property_name
|
||||||
%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 isset_variables
|
%type <node> encaps_var encaps_var_offset isset_variables
|
||||||
@ -191,7 +196,7 @@ func parse(src io.Reader, fName string) node.Node {
|
|||||||
%type <node> non_empty_parameter_list argument_list non_empty_argument_list property_list
|
%type <node> non_empty_parameter_list argument_list non_empty_argument_list property_list
|
||||||
%type <node> class_const_list class_const_decl name_list trait_adaptations method_body non_empty_for_exprs
|
%type <node> class_const_list class_const_decl name_list trait_adaptations method_body non_empty_for_exprs
|
||||||
%type <node> ctor_arguments alt_if_stmt_without_else trait_adaptation_list lexical_vars
|
%type <node> ctor_arguments alt_if_stmt_without_else trait_adaptation_list lexical_vars
|
||||||
%type <node> lexical_var_list encaps_list
|
%type <node> lexical_var_list
|
||||||
%type <node> array_pair non_empty_array_pair_list array_pair_list possible_array_pair
|
%type <node> array_pair non_empty_array_pair_list array_pair_list possible_array_pair
|
||||||
%type <node> isset_variable type return_type type_expr
|
%type <node> isset_variable type return_type type_expr
|
||||||
%type <node> identifier
|
%type <node> identifier
|
||||||
@ -200,6 +205,8 @@ func parse(src io.Reader, fName string) node.Node {
|
|||||||
%type <node> method_modifiers non_empty_member_modifiers member_modifier
|
%type <node> method_modifiers non_empty_member_modifiers member_modifier
|
||||||
%type <node> class_modifiers use_type
|
%type <node> class_modifiers use_type
|
||||||
|
|
||||||
|
%type <list> encaps_list backticks_expr
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
@ -900,7 +907,7 @@ expr_without_variable:
|
|||||||
| T_EXIT exit_expr { $$ = node.SimpleNode("Exit").Append($2); }
|
| T_EXIT exit_expr { $$ = node.SimpleNode("Exit").Append($2); }
|
||||||
| '@' expr { $$ = node.SimpleNode("Silence").Append($2); }
|
| '@' expr { $$ = node.SimpleNode("Silence").Append($2); }
|
||||||
| scalar { $$ = $1; }
|
| scalar { $$ = $1; }
|
||||||
| '`' backticks_expr '`' { $$ = node.SimpleNode("ShellExec").Append($2) }
|
| '`' backticks_expr '`' { $$ = node.NewNodeExprShellExec($1, $2, $3) }
|
||||||
| T_PRINT expr { $$ = node.SimpleNode("Print").Append($2); }
|
| T_PRINT expr { $$ = node.SimpleNode("Print").Append($2); }
|
||||||
| T_YIELD { $$ = node.SimpleNode("Yield"); }
|
| T_YIELD { $$ = node.SimpleNode("Yield"); }
|
||||||
| T_YIELD expr { $$ = node.SimpleNode("Yield").Append($2); }
|
| T_YIELD expr { $$ = node.SimpleNode("Yield").Append($2); }
|
||||||
@ -971,8 +978,8 @@ exit_expr:
|
|||||||
;
|
;
|
||||||
|
|
||||||
backticks_expr:
|
backticks_expr:
|
||||||
/* empty */ { $$ = node.SimpleNode("EmptyBackticks") }
|
/* empty */ { $$ = []node.Node{} }
|
||||||
| T_ENCAPSED_AND_WHITESPACE { $$ = node.TokenNode("String", $1) }
|
| T_ENCAPSED_AND_WHITESPACE { $$ = []node.Node{node.NewNodeScalarEncapsedStringPart($1)} }
|
||||||
| encaps_list { $$ = $1; }
|
| encaps_list { $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -984,7 +991,7 @@ ctor_arguments:
|
|||||||
dereferencable_scalar:
|
dereferencable_scalar:
|
||||||
T_ARRAY '(' array_pair_list ')' { $$ = $3; }
|
T_ARRAY '(' array_pair_list ')' { $$ = $3; }
|
||||||
| '[' array_pair_list ']' { $$ = $2; }
|
| '[' array_pair_list ']' { $$ = $2; }
|
||||||
| T_CONSTANT_ENCAPSED_STRING { $$ = node.TokenNode("String", $1) }
|
| T_CONSTANT_ENCAPSED_STRING { $$ = node.NewNodeScalarString($1) }
|
||||||
;
|
;
|
||||||
|
|
||||||
scalar:
|
scalar:
|
||||||
@ -999,11 +1006,11 @@ scalar:
|
|||||||
| T_NS_C { $$ = node.TokenNode("MagicConst", $1) }
|
| T_NS_C { $$ = node.TokenNode("MagicConst", $1) }
|
||||||
| T_CLASS_C { $$ = node.TokenNode("MagicConst", $1) }
|
| T_CLASS_C { $$ = node.TokenNode("MagicConst", $1) }
|
||||||
| T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE T_END_HEREDOC
|
| T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE T_END_HEREDOC
|
||||||
{ $$ = node.SimpleNode("Scalar").Append(node.TokenNode("Heredoc", $1)).Append(node.TokenNode("string", $2)).Append(node.TokenNode("HeredocEnd", $3)) }
|
{ $$ = node.NewNodeScalarString($2) /* TODO: mark as Heredoc*/ }
|
||||||
| T_START_HEREDOC T_END_HEREDOC
|
| T_START_HEREDOC T_END_HEREDOC
|
||||||
{ $$ = node.SimpleNode("Scalar").Append(node.TokenNode("Heredoc", $1)).Append(node.TokenNode("HeredocEnd", $2)) }
|
{ $$ = node.SimpleNode("Scalar").Append(node.TokenNode("Heredoc", $1)).Append(node.TokenNode("HeredocEnd", $2)) }
|
||||||
| '"' encaps_list '"' { $$ = $2; }
|
| '"' encaps_list '"' { $$ = node.NewNodeScalarEncapsed($1, $2, $3) }
|
||||||
| T_START_HEREDOC encaps_list T_END_HEREDOC { $$ = $2; }
|
| T_START_HEREDOC encaps_list T_END_HEREDOC { $$ = node.NewNodeScalarEncapsed($1, $2, $3) }
|
||||||
| dereferencable_scalar { $$ = $1; }
|
| dereferencable_scalar { $$ = $1; }
|
||||||
| constant { $$ = $1; }
|
| constant { $$ = $1; }
|
||||||
;
|
;
|
||||||
@ -1127,10 +1134,10 @@ array_pair:
|
|||||||
;
|
;
|
||||||
|
|
||||||
encaps_list:
|
encaps_list:
|
||||||
encaps_list encaps_var { $$ = $1.Append($2) }
|
encaps_list encaps_var { $$ = append($1, $2) }
|
||||||
| encaps_list T_ENCAPSED_AND_WHITESPACE { $$ = $1.Append(node.SimpleNode("String").Attribute("value", $2.String())) }
|
| encaps_list T_ENCAPSED_AND_WHITESPACE { $$ = append($1, node.NewNodeScalarEncapsedStringPart($2)) }
|
||||||
| encaps_var { $$ = node.SimpleNode("EncapsList").Append($1) }
|
| encaps_var { $$ = []node.Node{$1} }
|
||||||
| T_ENCAPSED_AND_WHITESPACE encaps_var { $$ = node.SimpleNode("EncapsList").Append(node.SimpleNode("String").Attribute("value", $1.String())).Append($2) }
|
| T_ENCAPSED_AND_WHITESPACE encaps_var { $$ = []node.Node{node.NewNodeScalarEncapsedStringPart($1), $2} }
|
||||||
;
|
;
|
||||||
|
|
||||||
encaps_var:
|
encaps_var:
|
||||||
|
5782
scanner.go
5782
scanner.go
File diff suppressed because it is too large
Load Diff
@ -241,7 +241,6 @@ NEW_LINE (\r|\n|\r\n)
|
|||||||
<PHP>(#|[/][/]).*{NEW_LINE} lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil)));// return T_COMMENT; // TODO: handle ?>
|
<PHP>(#|[/][/]).*{NEW_LINE} lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil)));// return T_COMMENT; // TODO: handle ?>
|
||||||
<PHP>[/][*][^*]*[*]+([^*/][^*]*[*]+)*[/] lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil)));// return T_COMMENT; // TODO: handle ?>
|
<PHP>[/][*][^*]*[*]+([^*/][^*]*[*]+)*[/] lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil)));// return T_COMMENT; // TODO: handle ?>
|
||||||
<PHP>[/][*][*][^*]*[*]+([^*/][^*]*[*]+)*[/] lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil)));// return T_DOC_COMMENT; // TODO: handle ?>
|
<PHP>[/][*][*][^*]*[*]+([^*/][^*]*[*]+)*[/] lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil)));// return T_DOC_COMMENT; // TODO: handle ?>
|
||||||
<PHP>'[^']*(\\')*' lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil))); return T_CONSTANT_ENCAPSED_STRING
|
|
||||||
<PHP>{OPERATORS} lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil))); return rune2Class(rune(l.TokenBytes(nil)[0]))
|
<PHP>{OPERATORS} lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil))); return rune2Class(rune(l.TokenBytes(nil)[0]))
|
||||||
|
|
||||||
<PHP>\{ l.pushState(PHP); lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil))); return rune2Class(rune(l.TokenBytes(nil)[0]))
|
<PHP>\{ l.pushState(PHP); lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil))); return rune2Class(rune(l.TokenBytes(nil)[0]))
|
||||||
@ -257,8 +256,8 @@ NEW_LINE (\r|\n|\r\n)
|
|||||||
|
|
||||||
<PHP>[\']([^\\\']*([\\][\'])*)*[\'] lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil))); return T_CONSTANT_ENCAPSED_STRING;
|
<PHP>[\']([^\\\']*([\\][\'])*)*[\'] lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil))); return T_CONSTANT_ENCAPSED_STRING;
|
||||||
|
|
||||||
<PHP>` l.begin(BACKQUOTE); lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil))); rune2Class(rune(l.TokenBytes(nil)[0]))
|
<PHP>` l.begin(BACKQUOTE); lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil))); return rune2Class(rune(l.TokenBytes(nil)[0]))
|
||||||
<BACKQUOTE>` l.begin(PHP); lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil))); rune2Class(rune(l.TokenBytes(nil)[0]))
|
<BACKQUOTE>` l.begin(PHP); lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil))); return rune2Class(rune(l.TokenBytes(nil)[0]))
|
||||||
|
|
||||||
<PHP>[b]?\<\<\<[ \t]*({VAR_NAME}|([']{VAR_NAME}['])|(["]{VAR_NAME}["])){NEW_LINE}
|
<PHP>[b]?\<\<\<[ \t]*({VAR_NAME}|([']{VAR_NAME}['])|(["]{VAR_NAME}["])){NEW_LINE}
|
||||||
tb := l.TokenBytes(nil)
|
tb := l.TokenBytes(nil)
|
||||||
@ -442,7 +441,7 @@ NEW_LINE (\r|\n|\r\n)
|
|||||||
c = l.Next()
|
c = l.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
<BACKQUOTE>.
|
<BACKQUOTE>.|[ \t\n\r]
|
||||||
F2:for {
|
F2:for {
|
||||||
if c == -1 {
|
if c == -1 {
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user