mirror of
https://github.com/golang/go
synced 2024-11-23 00:00:07 -07:00
- some factoring of scan/parse phase so we can attach other functionality
easily (for instance import dependency extraction) - support for new "..." syntax - minor cleanup R=r OCL=17811 CL=17811
This commit is contained in:
parent
2bfa95741f
commit
cec64a2dd5
@ -17,7 +17,9 @@ install: pretty
|
|||||||
clean:
|
clean:
|
||||||
rm -f pretty *.6 *~
|
rm -f pretty *.6 *~
|
||||||
|
|
||||||
pretty.6: parser.6 printer.6 platform.6 scanner.6
|
pretty.6: printer.6 platform.6 compilation.6
|
||||||
|
|
||||||
|
compilation.6: scanner.6 parser.6 ast.6
|
||||||
|
|
||||||
printer.6: ast.6 scanner.6
|
printer.6: ast.6 scanner.6
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ LDFLAGS = -Wl,-R,/home/iant/go/lib
|
|||||||
PRETTY_OBJS = \
|
PRETTY_OBJS = \
|
||||||
ast.o \
|
ast.o \
|
||||||
pretty.o \
|
pretty.o \
|
||||||
|
compilation.go \
|
||||||
parser.o \
|
parser.o \
|
||||||
platform.o \
|
platform.o \
|
||||||
printer.o \
|
printer.o \
|
||||||
@ -31,13 +32,19 @@ install: pretty
|
|||||||
clean:
|
clean:
|
||||||
rm -f pretty *.o *~
|
rm -f pretty *.o *~
|
||||||
|
|
||||||
pretty.o: parser.o printer.o platform.o scanner.o flag.o
|
|
||||||
|
|
||||||
parser.o: ast.o scanner.o utils.o printer.o
|
pretty.o: printer.o platform.o compilation.o
|
||||||
|
|
||||||
|
compilation.o: scanner.o parser.o ast.o
|
||||||
|
|
||||||
|
printer.o: ast.o scanner.o
|
||||||
|
|
||||||
|
parser.o: scanner.o utils.o printer.o ast.o
|
||||||
|
|
||||||
|
ast.o: scanner.o
|
||||||
|
|
||||||
scanner.o: utils.o platform.o
|
scanner.o: utils.o platform.o
|
||||||
|
|
||||||
ast.o: scanner.o
|
|
||||||
|
|
||||||
flag.o: fmt.o
|
flag.o: fmt.o
|
||||||
$(GO) -O2 -c -g $(GOROOT)/src/lib/flag.go
|
$(GO) -O2 -c -g $(GOROOT)/src/lib/flag.go
|
||||||
|
@ -309,6 +309,9 @@ func (P *Parser) ParseVarDecl(expect_ident bool) *AST.Type {
|
|||||||
x := P.ParseIdent();
|
x := P.ParseIdent();
|
||||||
t = AST.NewType(x.pos, Scanner.IDENT);
|
t = AST.NewType(x.pos, Scanner.IDENT);
|
||||||
t.expr = x;
|
t.expr = x;
|
||||||
|
} else if P.tok == Scanner.ELLIPSIS {
|
||||||
|
t = AST.NewType(P.pos, Scanner.ELLIPSIS);
|
||||||
|
P.Next();
|
||||||
} else {
|
} else {
|
||||||
t = P.ParseType();
|
t = P.ParseType();
|
||||||
}
|
}
|
||||||
@ -316,24 +319,30 @@ func (P *Parser) ParseVarDecl(expect_ident bool) *AST.Type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (P *Parser) ParseVarDeclList(list *AST.List) {
|
func (P *Parser) ParseVarDeclList(list *AST.List, ellipsis_ok bool) {
|
||||||
P.Trace("VarDeclList");
|
P.Trace("VarDeclList");
|
||||||
|
|
||||||
// parse a list of types
|
// parse a list of types
|
||||||
i0 := list.len();
|
i0 := list.len();
|
||||||
|
for {
|
||||||
list.Add(P.ParseVarDecl(i0 > 0));
|
list.Add(P.ParseVarDecl(i0 > 0));
|
||||||
for P.tok == Scanner.COMMA {
|
if P.tok == Scanner.COMMA {
|
||||||
P.Next();
|
P.Next();
|
||||||
list.Add(P.ParseVarDecl(i0 > 0));
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var typ *AST.Type;
|
typ := P.TryType();
|
||||||
if i0 > 0 {
|
if typ == nil && P.tok == Scanner.ELLIPSIS {
|
||||||
|
typ = AST.NewType(P.pos, Scanner.ELLIPSIS);
|
||||||
|
P.Next();
|
||||||
|
}
|
||||||
|
|
||||||
|
if i0 > 0 && typ == nil {
|
||||||
// not the first parameter section; we must have a type
|
// not the first parameter section; we must have a type
|
||||||
typ = P.ParseType();
|
P.Error(P.pos, "type expected");
|
||||||
} else {
|
typ = AST.BadType;
|
||||||
// first parameter section; we may have a type
|
|
||||||
typ = P.TryType();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert the list into a list of (type) expressions
|
// convert the list into a list of (type) expressions
|
||||||
@ -355,7 +364,11 @@ func (P *Parser) ParseVarDeclList(list *AST.List) {
|
|||||||
} else {
|
} else {
|
||||||
// all list entries are types
|
// all list entries are types
|
||||||
// convert all type entries into type expressions
|
// convert all type entries into type expressions
|
||||||
for i, n := i0, list.len(); i < n; i++ {
|
if i0 > 0 {
|
||||||
|
panic("internal parser error");
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, n := 0, list.len(); i < n; i++ {
|
||||||
t := list.at(i).(*AST.Type);
|
t := list.at(i).(*AST.Type);
|
||||||
list.set(i, AST.NewTypeExpr(t));
|
list.set(i, AST.NewTypeExpr(t));
|
||||||
}
|
}
|
||||||
@ -369,14 +382,14 @@ func (P *Parser) ParseVarDeclList(list *AST.List) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (P *Parser) ParseParameterList() *AST.List {
|
func (P *Parser) ParseParameterList(ellipsis_ok bool) *AST.List {
|
||||||
P.Trace("ParameterList");
|
P.Trace("ParameterList");
|
||||||
|
|
||||||
list := AST.NewList();
|
list := AST.NewList();
|
||||||
P.ParseVarDeclList(list);
|
P.ParseVarDeclList(list, ellipsis_ok);
|
||||||
for P.tok == Scanner.COMMA {
|
for P.tok == Scanner.COMMA {
|
||||||
P.Next();
|
P.Next();
|
||||||
P.ParseVarDeclList(list);
|
P.ParseVarDeclList(list, ellipsis_ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
P.Ecart();
|
P.Ecart();
|
||||||
@ -384,13 +397,13 @@ func (P *Parser) ParseParameterList() *AST.List {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (P *Parser) ParseParameters() *AST.Type {
|
func (P *Parser) ParseParameters(ellipsis_ok bool) *AST.Type {
|
||||||
P.Trace("Parameters");
|
P.Trace("Parameters");
|
||||||
|
|
||||||
t := AST.NewType(P.pos, Scanner.STRUCT);
|
t := AST.NewType(P.pos, Scanner.STRUCT);
|
||||||
P.Expect(Scanner.LPAREN);
|
P.Expect(Scanner.LPAREN);
|
||||||
if P.tok != Scanner.RPAREN {
|
if P.tok != Scanner.RPAREN {
|
||||||
t.list = P.ParseParameterList();
|
t.list = P.ParseParameterList(ellipsis_ok);
|
||||||
}
|
}
|
||||||
P.Expect(Scanner.RPAREN);
|
P.Expect(Scanner.RPAREN);
|
||||||
|
|
||||||
@ -420,7 +433,7 @@ func (P *Parser) ParseResult() *AST.Type {
|
|||||||
|
|
||||||
var t *AST.Type;
|
var t *AST.Type;
|
||||||
if P.tok == Scanner.LPAREN {
|
if P.tok == Scanner.LPAREN {
|
||||||
t = P.ParseParameters();
|
t = P.ParseParameters(false);
|
||||||
} else {
|
} else {
|
||||||
typ := P.TryType();
|
typ := P.TryType();
|
||||||
if typ != nil {
|
if typ != nil {
|
||||||
@ -445,7 +458,7 @@ func (P *Parser) ParseFunctionType() *AST.Type {
|
|||||||
P.Trace("FunctionType");
|
P.Trace("FunctionType");
|
||||||
|
|
||||||
t := AST.NewType(P.pos, Scanner.LPAREN);
|
t := AST.NewType(P.pos, Scanner.LPAREN);
|
||||||
t.list = P.ParseParameters().list; // TODO find better solution
|
t.list = P.ParseParameters(true).list; // TODO find better solution
|
||||||
t.elt = P.ParseResult();
|
t.elt = P.ParseResult();
|
||||||
|
|
||||||
P.Ecart();
|
P.Ecart();
|
||||||
@ -509,7 +522,7 @@ func (P *Parser) ParseStructType() *AST.Type {
|
|||||||
P.Next();
|
P.Next();
|
||||||
t.list = AST.NewList();
|
t.list = AST.NewList();
|
||||||
for P.tok == Scanner.IDENT {
|
for P.tok == Scanner.IDENT {
|
||||||
P.ParseVarDeclList(t.list);
|
P.ParseVarDeclList(t.list, false);
|
||||||
if P.tok != Scanner.RBRACE {
|
if P.tok != Scanner.RBRACE {
|
||||||
P.Expect(Scanner.SEMICOLON);
|
P.Expect(Scanner.SEMICOLON);
|
||||||
}
|
}
|
||||||
@ -1423,7 +1436,7 @@ func (P *Parser) ParseFunctionDecl(exported bool) *AST.Decl {
|
|||||||
var recv *AST.Type;
|
var recv *AST.Type;
|
||||||
if P.tok == Scanner.LPAREN {
|
if P.tok == Scanner.LPAREN {
|
||||||
pos := P.pos;
|
pos := P.pos;
|
||||||
recv = P.ParseParameters();
|
recv = P.ParseParameters(true);
|
||||||
if recv.nfields() != 1 {
|
if recv.nfields() != 1 {
|
||||||
P.Error(pos, "must have exactly one receiver");
|
P.Error(pos, "must have exactly one receiver");
|
||||||
}
|
}
|
||||||
|
@ -6,18 +6,19 @@ package main
|
|||||||
|
|
||||||
import Flag "flag"
|
import Flag "flag"
|
||||||
import Platform "platform"
|
import Platform "platform"
|
||||||
import Scanner "scanner"
|
|
||||||
import Parser "parser"
|
|
||||||
import Printer "printer"
|
import Printer "printer"
|
||||||
|
import Compilation "compilation"
|
||||||
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
flags Compilation.Flags;
|
||||||
silent = Flag.Bool("s", false, nil, "silent mode: no pretty print output");
|
silent = Flag.Bool("s", false, nil, "silent mode: no pretty print output");
|
||||||
verbose = Flag.Bool("v", false, nil, "verbose mode: trace parsing");
|
verbose = Flag.Bool("v", false, &flags.verbose, "verbose mode: trace parsing");
|
||||||
sixg = Flag.Bool("6g", true, nil, "6g compatibility mode");
|
sixg = Flag.Bool("6g", true, &flags.sixg, "6g compatibility mode");
|
||||||
columns = Flag.Bool("columns", Platform.USER == "gri", nil, "print column info in error messages");
|
deps = Flag.Bool("d", false, &flags.deps, "print dependency information only");
|
||||||
testmode = Flag.Bool("t", false, nil, "test mode: interprets /* ERROR */ and /* SYNC */ comments");
|
columns = Flag.Bool("columns", Platform.USER == "gri", &flags.columns, "print column info in error messages");
|
||||||
tokenchan = Flag.Bool("token_chan", false, nil, "use token channel for scanner-parser connection");
|
testmode = Flag.Bool("t", false, &flags.testmode, "test mode: interprets /* ERROR */ and /* SYNC */ comments");
|
||||||
|
tokenchan = Flag.Bool("token_chan", false, &flags.tokenchan, "use token channel for scanner-parser connection");
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -45,26 +46,21 @@ func main() {
|
|||||||
sys.exit(1);
|
sys.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
scanner := new(Scanner.Scanner);
|
C := Compilation.Compile(src_file, src, &flags);
|
||||||
scanner.Open(src_file, src, columns.BVal(), testmode.BVal());
|
|
||||||
|
|
||||||
var tstream *<-chan *Scanner.Token;
|
if C.nerrors > 0 {
|
||||||
if tokenchan.BVal() {
|
|
||||||
tstream = scanner.TokenStream();
|
|
||||||
}
|
|
||||||
|
|
||||||
parser := new(Parser.Parser);
|
|
||||||
parser.Open(verbose.BVal(), sixg.BVal(), scanner, tstream);
|
|
||||||
|
|
||||||
prog := parser.ParseProgram();
|
|
||||||
|
|
||||||
if scanner.nerrors > 0 {
|
|
||||||
sys.exit(1);
|
sys.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !silent.BVal() && !testmode.BVal() {
|
if flags.deps {
|
||||||
|
print("deps\n");
|
||||||
|
panic("UNIMPLEMENTED");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if !silent.BVal() && !flags.testmode {
|
||||||
var P Printer.Printer;
|
var P Printer.Printer;
|
||||||
(&P).Program(prog);
|
(&P).Program(C.prog);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,14 +134,13 @@ func (P *Printer) Parameters(pos int, list *AST.List) {
|
|||||||
|
|
||||||
|
|
||||||
func (P *Printer) Fields(list *AST.List) {
|
func (P *Printer) Fields(list *AST.List) {
|
||||||
P.OpenScope(" {");
|
P.OpenScope("{");
|
||||||
var prev int;
|
var prev int;
|
||||||
for i, n := 0, list.len(); i < n; i++ {
|
for i, n := 0, list.len(); i < n; i++ {
|
||||||
x := list.at(i).(*AST.Expr);
|
x := list.at(i).(*AST.Expr);
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
if prev == Scanner.TYPE {
|
if prev == Scanner.TYPE {
|
||||||
P.String(0, ";");
|
P.semi, P.newl = true, 1;
|
||||||
P.newl = 1;
|
|
||||||
} else if prev == x.tok {
|
} else if prev == x.tok {
|
||||||
P.String(0, ", ");
|
P.String(0, ", ");
|
||||||
} else {
|
} else {
|
||||||
@ -203,6 +202,9 @@ func (P *Printer) Type(t *AST.Type) {
|
|||||||
P.Parameters(0, t.elt.list);
|
P.Parameters(0, t.elt.list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case Scanner.ELLIPSIS:
|
||||||
|
P.String(t.pos, "...");
|
||||||
|
|
||||||
default:
|
default:
|
||||||
P.Error(t.pos, t.tok, "type");
|
P.Error(t.pos, t.tok, "type");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user