mirror of
https://github.com/golang/go
synced 2024-11-26 20:01:19 -07:00
aa9ce6148a
convention used in template.go) R=rsc DELTA=22 (3 added, 1 deleted, 18 changed) OCL=29780 CL=29782
335 lines
4.6 KiB
Plaintext
335 lines
4.6 KiB
Plaintext
// Copyright 2009 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// Format file for printing AST nodes.
|
|
|
|
ast "ast";
|
|
token "token";
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Basic types, support rules
|
|
|
|
array =
|
|
*;
|
|
|
|
ptr =
|
|
*;
|
|
|
|
string =
|
|
"%s";
|
|
|
|
char =
|
|
"%c";
|
|
|
|
bytes =
|
|
{*};
|
|
|
|
empty =
|
|
;
|
|
|
|
exists =
|
|
*:empty;
|
|
|
|
ast.Expr =
|
|
*;
|
|
|
|
ast.Stmt =
|
|
*;
|
|
|
|
ast.Decl =
|
|
*;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Tokens and comments
|
|
|
|
token.Token =
|
|
@:string;
|
|
|
|
ast.Comment =
|
|
// TODO this doesn't indent properly after //-style comments because
|
|
// the '\n'-char is printed as part of the comment - need to
|
|
// address this
|
|
Text:string [Text:isMultiLineComment "\n"];
|
|
|
|
ast.Comments =
|
|
{*};
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Expressions & Types
|
|
|
|
ast.Field =
|
|
[Names:exists {Names / ", "} " "] Type;
|
|
|
|
ast.BadExpr =
|
|
"BAD EXPR";
|
|
|
|
ast.Ident =
|
|
Value;
|
|
|
|
ast.Ellipsis =
|
|
"...";
|
|
|
|
ast.IntLit =
|
|
Value:string;
|
|
|
|
ast.FloatLit =
|
|
Value:string;
|
|
|
|
ast.CharLit =
|
|
Value:string;
|
|
|
|
ast.StringLit =
|
|
Value:string;
|
|
|
|
ast.StringList =
|
|
{Strings / "\n"};
|
|
|
|
ast.FuncLit =
|
|
Type " " Body @:clearOptSemi; // no optional ; after a func literal body
|
|
|
|
ast.CompositeLit =
|
|
Type "{" {Elts / ", "} "}";
|
|
|
|
ast.ParenExpr =
|
|
"(" X ")";
|
|
|
|
ast.SelectorExpr =
|
|
X "." Sel;
|
|
|
|
ast.IndexExpr =
|
|
X "[" Index [":" End] "]";
|
|
|
|
ast.TypeAssertExpr =
|
|
X ".(" Type ")";
|
|
|
|
ast.CallExpr =
|
|
Fun "(" {Args / ", "} ")";
|
|
|
|
ast.StarExpr =
|
|
"*" X;
|
|
|
|
ast.UnaryExpr =
|
|
Op X;
|
|
|
|
ast.BinaryExpr =
|
|
X " " Op " " Y;
|
|
|
|
ast.KeyValueExpr =
|
|
Key ": " Value;
|
|
|
|
ast.ArrayType =
|
|
"[" [Len] "]" Elt;
|
|
|
|
ast.StructType =
|
|
"struct"
|
|
[Lbrace:isValidPos " {"]
|
|
[ Fields:exists
|
|
( "\t" >> "\n"
|
|
{Fields / ";\n"}
|
|
) "\n"
|
|
]
|
|
[Rbrace:isValidPos "}"];
|
|
|
|
signature =
|
|
"(" {Params / ", "} ")" [Results:exists " (" {Results / ", "} ")"];
|
|
|
|
funcSignature =
|
|
*:signature;
|
|
|
|
ast.FuncType =
|
|
[Position:isValidPos "func"] @:signature;
|
|
|
|
ast.InterfaceType =
|
|
"interface"
|
|
[Lbrace:isValidPos " {"]
|
|
[ Methods:exists
|
|
( "\t" >> "\n"
|
|
{Methods / ";\n"}
|
|
) "\n"
|
|
]
|
|
[Rbrace:isValidPos "}"];
|
|
|
|
ast.MapType =
|
|
"map[" Key "]" Value;
|
|
|
|
ast.ChanType =
|
|
( Dir:isSend Dir:isRecv
|
|
"chan "
|
|
| Dir:isSend
|
|
"chan <- "
|
|
| "<-chan "
|
|
)
|
|
Value;
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Statements
|
|
|
|
ast.BadStmt =
|
|
"BAD STMT";
|
|
|
|
ast.DeclStmt =
|
|
Decl;
|
|
|
|
ast.EmptyStmt =
|
|
;
|
|
|
|
ast.LabeledStmt =
|
|
Label ":\t" Stmt;
|
|
|
|
ast.ExprStmt =
|
|
X;
|
|
|
|
ast.IncDecStmt =
|
|
X Tok;
|
|
|
|
ast.AssignStmt =
|
|
{Lhs / ", "} " " Tok " " {Rhs / ", "};
|
|
|
|
ast.GoStmt =
|
|
"go " Call;
|
|
|
|
ast.DeferStmt =
|
|
"defer " Call;
|
|
|
|
ast.ReturnStmt =
|
|
"return" {" " Results / ","};
|
|
|
|
ast.BranchStmt =
|
|
Tok [" " Label];
|
|
|
|
stmtList =
|
|
{@ / @:optSemi "\n"};
|
|
|
|
blockStmt = // like ast.BlockStmt but w/o indentation
|
|
"{"
|
|
[List:exists
|
|
"\n"
|
|
List:stmtList
|
|
"\n"
|
|
]
|
|
"}" @:setOptSemi;
|
|
|
|
blockStmtPtr =
|
|
*:blockStmt;
|
|
|
|
ast.BlockStmt =
|
|
"{"
|
|
[List:exists
|
|
( "\t" >> "\n"
|
|
List:stmtList
|
|
) "\n"
|
|
]
|
|
"}" @:setOptSemi;
|
|
|
|
ast.IfStmt =
|
|
"if " [Init "; "] [Cond " "] Body [" else " Else];
|
|
|
|
ast.CaseClause =
|
|
( Values:exists "case " {Values / ", "}
|
|
| "default"
|
|
)
|
|
":"
|
|
[Body:exists
|
|
( "\t" >> "\n"
|
|
Body:stmtList
|
|
)
|
|
];
|
|
|
|
ast.SwitchStmt =
|
|
"switch " [Init "; "] [Tag " "]
|
|
Body:blockStmtPtr;
|
|
|
|
ast.TypeCaseClause =
|
|
( Type:exists "case " Type
|
|
| "default"
|
|
)
|
|
":"
|
|
[Body:exists
|
|
( "\t" >> "\n"
|
|
Body:stmtList
|
|
)
|
|
];
|
|
|
|
ast.TypeSwitchStmt =
|
|
"switch " Assign " "
|
|
Body:blockStmtPtr;
|
|
|
|
ast.CommClause =
|
|
( "case " [Lhs " " Tok " "] Rhs
|
|
| "default"
|
|
)
|
|
":"
|
|
[Body:exists
|
|
( "\t" >> "\n"
|
|
Body:stmtList
|
|
)
|
|
];
|
|
|
|
ast.SelectStmt =
|
|
"select "
|
|
Body:blockStmtPtr;
|
|
|
|
ast.ForStmt =
|
|
"for "
|
|
[ (Init:exists | Post:exists)
|
|
[Init] "; " [Cond] "; " [Post " "]
|
|
| Cond " "
|
|
]
|
|
Body;
|
|
|
|
ast.RangeStmt =
|
|
"for " Key [", " Value] " " Tok " range " X
|
|
" "
|
|
Body;
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Declarations
|
|
|
|
ast.Spec =
|
|
*;
|
|
|
|
ast.ImportSpec =
|
|
Doc
|
|
[Name] "\t" {Path};
|
|
|
|
ast.ValueSpec =
|
|
{Names / ", "} [" " Type] [Values:exists " = " {Values / ", "}];
|
|
|
|
ast.TypeSpec =
|
|
Name " " // TODO using "\t" instead of " " screws up struct field alignment
|
|
Type;
|
|
|
|
ast.BadDecl =
|
|
"BAD DECL";
|
|
|
|
ast.GenDecl =
|
|
Doc
|
|
Tok " "
|
|
( Lparen:isValidPos "("
|
|
[Specs:exists
|
|
( "\t" >> "\n"
|
|
{Specs / ";\n"}
|
|
) "\n"
|
|
]
|
|
")" @:setOptSemi
|
|
| {Specs / ";\n"}
|
|
);
|
|
|
|
ast.FuncDecl =
|
|
"func " ["(" Recv ") "] Name Type:funcSignature
|
|
[" " Body]
|
|
"\n";
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Program
|
|
|
|
ast.Program =
|
|
Doc
|
|
"package " Name "\n\n"
|
|
{Decls / "\n\n"};
|