issue #2 - deny numbers and slashes in first char in variable name
This commit is contained in:
parent
07f02e4497
commit
d31819db30
@ -4,11 +4,14 @@ import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/z7zmey/php-parser/node/scalar"
|
||||
|
||||
"github.com/z7zmey/php-parser/node/name"
|
||||
|
||||
"github.com/z7zmey/php-parser/node/expr"
|
||||
|
||||
"github.com/z7zmey/php-parser/node"
|
||||
"github.com/z7zmey/php-parser/node/expr/binary"
|
||||
"github.com/z7zmey/php-parser/node/stmt"
|
||||
"github.com/z7zmey/php-parser/php5"
|
||||
"github.com/z7zmey/php-parser/php7"
|
||||
@ -125,3 +128,37 @@ func TestFunctionCallVar(t *testing.T) {
|
||||
actual, _, _ = php5.Parse(bytes.NewBufferString(src), "test.php")
|
||||
assertEqual(t, expected, actual)
|
||||
}
|
||||
|
||||
func TestFunctionCallExprArg(t *testing.T) {
|
||||
src := `<? ceil($foo/3);`
|
||||
|
||||
expected := &stmt.StmtList{
|
||||
Stmts: []node.Node{
|
||||
&stmt.Expression{
|
||||
Expr: &expr.FunctionCall{
|
||||
Function: &name.Name{
|
||||
Parts: []node.Node{
|
||||
&name.NamePart{Value: "ceil"},
|
||||
},
|
||||
},
|
||||
Arguments: []node.Node{
|
||||
&node.Argument{
|
||||
Variadic: false,
|
||||
IsReference: false,
|
||||
Expr: &binary.Div{
|
||||
Left: &expr.Variable{VarName: &node.Identifier{Value: "foo"}},
|
||||
Right: &scalar.Lnumber{Value: "3"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
actual, _, _ := php7.Parse(bytes.NewBufferString(src), "test.php")
|
||||
assertEqual(t, expected, actual)
|
||||
|
||||
actual, _, _ = php5.Parse(bytes.NewBufferString(src), "test.php")
|
||||
assertEqual(t, expected, actual)
|
||||
}
|
||||
|
4151
scanner/scanner.go
4151
scanner/scanner.go
File diff suppressed because it is too large
Load Diff
@ -54,7 +54,7 @@ DNUM ([0-9]*"."[0-9]+)|([0-9]+"."[0-9]*)
|
||||
HNUM 0x[0-9a-fA-F]+
|
||||
BNUM 0b[01]+
|
||||
EXPONENT_DNUM (({LNUM}|{DNUM})[eE][+-]?{LNUM})
|
||||
VAR_NAME [a-zA-Z_\x7f-\xff^0-9/][a-zA-Z0-9_\x7f-\xff]*
|
||||
VAR_NAME [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*
|
||||
OPERATORS [;:,.\[\]()|\/\^&\+-*=%!~$<>?@]
|
||||
NEW_LINE (\r|\n|\r\n)
|
||||
|
||||
@ -449,42 +449,39 @@ NEW_LINE (\r|\n|\r\n)
|
||||
<STRING>\" l.popState(); lval.Token(l.newToken(l.Token())); return Rune2Class(l.Token()[0].Rune)
|
||||
<STRING,HEREDOC,BACKQUOTE>\{\$ lval.Token(l.newToken(l.ungetChars(1))); l.pushState(PHP); return T_CURLY_OPEN
|
||||
<STRING,HEREDOC,BACKQUOTE>\$\{ l.pushState(STRING_VAR_NAME); lval.Token(l.newToken(l.Token())); return T_DOLLAR_OPEN_CURLY_BRACES
|
||||
<STRING,HEREDOC,BACKQUOTE>\$ l.ungetChars(1);l.pushState(STRING_VAR)
|
||||
<STRING,HEREDOC,BACKQUOTE>\${VAR_NAME} l.ungetChars(len(l.Token()));l.pushState(STRING_VAR)
|
||||
<STRING>.|[ \t\n\r]
|
||||
F1:for {
|
||||
switch l.Prev.Rune {
|
||||
currentChar := l.Prev
|
||||
tb := []lex.Char{currentChar}
|
||||
for {
|
||||
switch currentChar.Rune {
|
||||
case '$':
|
||||
c = l.Next();
|
||||
if l.Prev.Rune == '{' || isValidFirstVarNameRune(l.Prev.Rune) {
|
||||
l.ungetChars(2)
|
||||
tb := l.Token()
|
||||
lval.Token(l.newToken(tb[:len(tb)-2]));
|
||||
if c == '{' || isValidFirstVarNameRune(rune(c)) {
|
||||
l.ungetChars(1)
|
||||
lval.Token(l.newToken(tb[:len(tb)-1]));
|
||||
return T_ENCAPSED_AND_WHITESPACE
|
||||
break F1;
|
||||
}
|
||||
l.ungetChars(1)
|
||||
|
||||
}
|
||||
|
||||
case '{':
|
||||
c = l.Next();
|
||||
if l.Prev.Rune == '$' {
|
||||
l.ungetChars(2)
|
||||
tb := l.Token()
|
||||
lval.Token(l.newToken(tb[:len(tb)-2]));
|
||||
if rune(c) == '$' {
|
||||
l.ungetChars(1)
|
||||
lval.Token(l.newToken(tb[:len(tb)-1]));
|
||||
return T_ENCAPSED_AND_WHITESPACE
|
||||
break F1;
|
||||
}
|
||||
l.ungetChars(1)
|
||||
}
|
||||
|
||||
case '\\':
|
||||
currentChar := l.Last
|
||||
tb = append(tb, currentChar)
|
||||
c = l.Next();
|
||||
}
|
||||
|
||||
if rune(c) == '"' {
|
||||
lval.Token(l.newToken(l.Token()));
|
||||
return T_ENCAPSED_AND_WHITESPACE
|
||||
break F1;
|
||||
}
|
||||
|
||||
currentChar = l.Last
|
||||
tb = append(tb, currentChar)
|
||||
c = l.Next()
|
||||
|
||||
if c == -1 {
|
||||
|
@ -436,6 +436,12 @@ func TestTeplateStringTokens(t *testing.T) {
|
||||
"test $var {$var} ${var_name} {s $ \$a "
|
||||
|
||||
"{$var}"
|
||||
|
||||
"$foo/"
|
||||
"$foo/100;"
|
||||
|
||||
"$/$foo"
|
||||
"$0$foo"
|
||||
`
|
||||
|
||||
expected := []int{
|
||||
@ -485,6 +491,26 @@ func TestTeplateStringTokens(t *testing.T) {
|
||||
scanner.T_VARIABLE,
|
||||
scanner.Rune2Class('}'),
|
||||
scanner.Rune2Class('"'),
|
||||
|
||||
scanner.Rune2Class('"'),
|
||||
scanner.T_VARIABLE,
|
||||
scanner.T_ENCAPSED_AND_WHITESPACE,
|
||||
scanner.Rune2Class('"'),
|
||||
|
||||
scanner.Rune2Class('"'),
|
||||
scanner.T_VARIABLE,
|
||||
scanner.T_ENCAPSED_AND_WHITESPACE,
|
||||
scanner.Rune2Class('"'),
|
||||
|
||||
scanner.Rune2Class('"'),
|
||||
scanner.T_ENCAPSED_AND_WHITESPACE,
|
||||
scanner.T_VARIABLE,
|
||||
scanner.Rune2Class('"'),
|
||||
|
||||
scanner.Rune2Class('"'),
|
||||
scanner.T_ENCAPSED_AND_WHITESPACE,
|
||||
scanner.T_VARIABLE,
|
||||
scanner.Rune2Class('"'),
|
||||
}
|
||||
|
||||
lexer := scanner.NewLexer(bytes.NewBufferString(src), "test.php")
|
||||
@ -633,3 +659,37 @@ func TestStringTokensAfterVariable(t *testing.T) {
|
||||
assertEqual(t, expected, actual)
|
||||
assertEqual(t, expectedTokens, actualTokens)
|
||||
}
|
||||
|
||||
func TestSlashAfterVariable(t *testing.T) {
|
||||
src := `<?php $foo/3`
|
||||
|
||||
expected := []int{
|
||||
scanner.T_VARIABLE,
|
||||
scanner.Rune2Class('/'),
|
||||
scanner.T_LNUMBER,
|
||||
}
|
||||
|
||||
expectedTokens := []string{
|
||||
"$foo",
|
||||
"/",
|
||||
"3",
|
||||
}
|
||||
|
||||
lexer := scanner.NewLexer(bytes.NewBufferString(src), "test.php")
|
||||
lv := &lval{}
|
||||
actual := []int{}
|
||||
actualTokens := []string{}
|
||||
|
||||
for {
|
||||
token := lexer.Lex(lv)
|
||||
if token < 0 {
|
||||
break
|
||||
}
|
||||
|
||||
actualTokens = append(actualTokens, lv.Tkn.Value)
|
||||
actual = append(actual, token)
|
||||
}
|
||||
|
||||
assertEqual(t, expected, actual)
|
||||
assertEqual(t, expectedTokens, actualTokens)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user