Skip to content
This repository was archived by the owner on Oct 16, 2022. It is now read-only.

Commit 9d05108

Browse files
committed
line ending flexibility. fixes #29
1 parent b6c8d68 commit 9d05108

File tree

3 files changed

+57
-5
lines changed

3 files changed

+57
-5
lines changed

lexer/lexers.go

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -277,11 +277,19 @@ func lexPHPEnd(l *lexer) stateFn {
277277
}
278278

279279
func lexLineComment(l *lexer) stateFn {
280-
lineLength := strings.Index(l.input[l.pos:], "\n") + 1
280+
lineLength := strings.IndexAny(l.input[l.pos:], "\r\n") + 1
281281
if lineLength == 0 {
282282
// this is the last line, so lex until the end
283283
lineLength = len(l.input[l.pos:])
284284
}
285+
286+
// deal with varying line endings
287+
if l.input[l.pos+lineLength-1] == '\r' &&
288+
len(l.input[l.pos+lineLength:]) > 0 &&
289+
l.input[l.pos+lineLength] == '\n' {
290+
lineLength++
291+
}
292+
285293
// don't lex php end
286294
if phpEndLength := strings.Index(l.input[l.pos:l.pos+lineLength], phpEnd); phpEndLength >= 0 && phpEndLength < lineLength {
287295
lineLength = phpEndLength
@@ -315,17 +323,30 @@ func lexDoc(l *lexer) stateFn {
315323
labelPos := l.pos
316324
l.accept(underscore + alphabet)
317325
l.acceptRun(underscore + alphabet + digits)
318-
endMarker := fmt.Sprintf("\n%s", l.input[labelPos:l.pos])
326+
327+
endMarkerA := fmt.Sprintf("\r\n%s", l.input[labelPos:l.pos])
328+
endMarkerB := fmt.Sprintf("\n%s", l.input[labelPos:l.pos])
329+
endMarkerC := fmt.Sprintf("\r%s", l.input[labelPos:l.pos])
319330
if nowDoc {
320331
l.accept("'")
321332
} else if l.peek() == '"' {
322333
l.next()
323334
}
324-
l.accept("\n")
325-
for !strings.HasPrefix(l.input[l.pos:], endMarker) {
335+
l.accept("\r\n")
336+
l.accept("\r\n")
337+
338+
for !strings.HasPrefix(l.input[l.pos:], endMarkerA) &&
339+
!strings.HasPrefix(l.input[l.pos:], endMarkerB) &&
340+
!strings.HasPrefix(l.input[l.pos:], endMarkerC) {
326341
l.next()
327342
}
328-
l.pos += len(endMarker)
343+
344+
if strings.HasPrefix(l.input[l.pos:], endMarkerA) {
345+
l.pos += len(endMarkerA)
346+
} else {
347+
l.pos += len(endMarkerB)
348+
}
349+
329350
l.emit(token.StringLiteral)
330351
return lexPHP
331352
}

lexer/lineEndings_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package lexer
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/stephens2424/php/token"
8+
)
9+
10+
func TestLineEndings(t *testing.T) {
11+
var testFiles = []string{
12+
"<?php\r//comment\r$test;\r",
13+
"<?php\n//comment\n$test;\n",
14+
"<?php\r\n//comment\r\n$test;\r\n",
15+
"<?php\n//comment\r$test;\r",
16+
"<?php\n//comment\r$test;\n",
17+
}
18+
19+
for i, testFile := range testFiles {
20+
t.Run(fmt.Sprint(i), func(t *testing.T) {
21+
l := token.Subset(NewLexer(testFile), token.Significant|token.CommentType)
22+
assertNext(t, l, token.PHPBegin)
23+
assertNext(t, l, token.CommentLine)
24+
assertNext(t, l, token.VariableOperator)
25+
assertNext(t, l, token.Identifier)
26+
assertNext(t, l, token.StatementEnd)
27+
assertNext(t, l, token.EOF)
28+
})
29+
}
30+
}

testdata/lineEndings.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<?php// commentecho $a = 1;

0 commit comments

Comments
 (0)