fix(parser): peel stacked labels the way the formatter renders them
Assisted-by: GLM 5.3
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
go test fuzz v1
|
||||
string("A:A:")
|
||||
+17
-11
@@ -160,12 +160,20 @@ func (p *state) parseLine(line []token.Token) {
|
||||
return
|
||||
}
|
||||
|
||||
// Label (ident immediately followed by a colon).
|
||||
// Label (ident immediately followed by a colon). Stacked labels
|
||||
// share one line ("a: b: MOVQ …"): each peels off as its own Label,
|
||||
// the same statement sequence the canonical layout puts on separate
|
||||
// lines, so a file and its formatted image parse alike. A directive
|
||||
// never peels: it stays with the instruction parse, as in the
|
||||
// formatter's label handling.
|
||||
if len(line) >= 2 && line[1].Kind == token.Colon {
|
||||
lbl := &ast.Label{Name: line[0], Colon: line[1]}
|
||||
p.addStmt(lbl)
|
||||
// A label may share its line with an instruction: "loop: MOVQ …".
|
||||
if rest := dropColon(line); len(rest) > 0 {
|
||||
rest := line
|
||||
for len(rest) >= 2 && rest[0].Kind == token.Ident && rest[1].Kind == token.Colon &&
|
||||
!isDirective(rest[0].Text) {
|
||||
p.addStmt(&ast.Label{Name: rest[0], Colon: rest[1]})
|
||||
rest = rest[2:]
|
||||
}
|
||||
if len(rest) > 0 {
|
||||
p.parseInstr(rest)
|
||||
}
|
||||
p.pending = nil
|
||||
@@ -182,12 +190,10 @@ func (p *state) parseLine(line []token.Token) {
|
||||
p.pending = nil
|
||||
}
|
||||
|
||||
// dropColon removes the leading "ident :" of a label, returning the remainder.
|
||||
func dropColon(line []token.Token) []token.Token {
|
||||
if len(line) >= 2 && line[1].Kind == token.Colon {
|
||||
return line[2:]
|
||||
}
|
||||
return nil
|
||||
// isDirective reports whether the identifier names a top-level declaration
|
||||
// directive rather than an instruction or a label.
|
||||
func isDirective(s string) bool {
|
||||
return s == "TEXT" || s == "DATA" || s == "GLOBL"
|
||||
}
|
||||
|
||||
func (p *state) addStmt(s ast.Stmt) {
|
||||
|
||||
Reference in New Issue
Block a user