Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong line number when parsing string. #93

Closed
ganlvtech opened this issue Jun 3, 2019 · 1 comment
Closed

Wrong line number when parsing string. #93

ganlvtech opened this issue Jun 3, 2019 · 1 comment

Comments

@ganlvtech
Copy link
Contributor

Dev branch.

Test Script

<?php
echo "$
$
$
$
$
";
echo __LINE__;
package main

import (
	"fmt"
	"os"

	"github.com/z7zmey/php-parser/php5"
	"github.com/z7zmey/php-parser/visitor"
)

func main() {
	bytes := []byte(`<?php
echo "$
$
$
$
$
";
echo __LINE__;
`)

	parser := php5.NewParser(bytes)
	parser.Parse()

	for _, e := range parser.GetErrors() {
		fmt.Println(e, e.Pos)
	}

	visitor := visitor.Dumper{
		Writer: os.Stdout,
		Indent: "",
	}

	rootNode := parser.GetRootNode()
	rootNode.Walk(&visitor)
}

Expected Result

[*node.Root]
  "Position": Pos{Line: 2-8 Pos: 6-39}
  "Stmts":
    [*stmt.Echo]
      "Position": Pos{Line: 2-7 Pos: 6-24}
      "Exprs":
        [*scalar.String]
          "Position": Pos{Line: 2-7 Pos: 11-23}
          "Value": "\"$\n$\n$\n$\n$\n\""
    [*stmt.Echo]
      "Position": Pos{Line: 8-8 Pos: 25-39}
      "Exprs":
        [*scalar.MagicConstant]
          "Position": Pos{Line: 8-8 Pos: 30-38}
          "Value": "__LINE__"

Actual Result

[*node.Root]
  "Position": Pos{Line: 2-3 Pos: 6-39}
  "Stmts":
    [*stmt.Echo]
      "Position": Pos{Line: 2-2 Pos: 6-24}
      "Exprs":
        [*scalar.String]
          "Position": Pos{Line: 2-2 Pos: 11-23}
          "Value": "\"$\n$\n$\n$\n$\n\""
    [*stmt.Echo]
      "Position": Pos{Line: 3-3 Pos: 25-39}
      "Exprs":
        [*scalar.MagicConstant]
          "Position": Pos{Line: 3-3 Pos: 30-38}
          "Value": "__LINE__"

My Suggestion

constant_string =
start: (
"'" -> qoute
| "b"i? '"' -> double_qoute
),
qoute: (
(any - [\\'\r\n]) -> qoute
| "\r" @{if lex.p+1 != eof && lex.data[lex.p+1] != '\n' {lex.NewLines.Append(lex.p)}} -> qoute
| "\n" @{lex.NewLines.Append(lex.p)} -> qoute
| "\\" -> qoute_any
| "'" -> final
),
qoute_any: (
any_line -> qoute
),
double_qoute: (
(any - [\\"${\r\n]) -> double_qoute
| "\r" @{if lex.p+1 != eof && lex.data[lex.p+1] != '\n' {lex.NewLines.Append(lex.p)}} -> double_qoute
| "\n" @{lex.NewLines.Append(lex.p)} -> double_qoute
| "\\" -> double_qoute_any
| '"' -> final
| '$' -> double_qoute_nonvarname
| '{' -> double_qoute_nondollar
),
double_qoute_any: (
any_line -> double_qoute
),
double_qoute_nondollar: (
'"' -> final
| "\\" -> double_qoute_any
| [^$\\"] -> double_qoute
),
double_qoute_nonvarname: (
'"' -> final
| "\\" -> double_qoute_any
| /[^"\\{a-zA-Z_\x7f-\xff]/ -> double_qoute
);

constant_string won't parse double quoted string. So maybe we don't need double_qoute_nonvarname and double_qoute_nondollar state.

z7zmey added a commit that referenced this issue Jun 7, 2019
@z7zmey
Copy link
Owner

z7zmey commented Jun 7, 2019

The scanner must interpret double-quoted strings that don't contain variables as T_CONSTANT_ENCAPSED_STRING.
double_qoute_nonvarname and double_qoute_nondollar prevents transition to final state if variable found.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants