Best Syzkaller code snippet using ast.expect
package_text.go
Source:package_text.go
...76}77func (p *gc_parser) errorf(format string, args ...interface{}) {78 p.error(fmt.Sprintf(format, args...))79}80func (p *gc_parser) expect(tok rune) string {81 lit := p.lit82 if p.tok != tok {83 p.errorf("expected %s, got %s (%q)", scanner.TokenString(tok),84 scanner.TokenString(p.tok), lit)85 }86 p.next()87 return lit88}89func (p *gc_parser) expect_keyword(keyword string) {90 lit := p.expect(scanner.Ident)91 if lit != keyword {92 p.errorf("expected keyword: %s, got: %q", keyword, lit)93 }94}95func (p *gc_parser) expect_special(what string) {96 i := 097 for i < len(what) {98 if p.tok != rune(what[i]) {99 break100 }101 nc := p.scanner.Peek()102 if i != len(what)-1 && nc <= ' ' {103 break104 }105 p.next()106 i++107 }108 if i < len(what) {109 p.errorf("expected: %q, got: %q", what, what[0:i])110 }111}112// dotIdentifier = "?" | ( ident | '·' ) { ident | int | '·' } .113// we're doing lexer job here, kind of114func (p *gc_parser) parse_dot_ident() string {115 if p.tok == '?' {116 p.next()117 return "?"118 }119 ident := ""120 sep := 'x'121 i, j := 0, -1122 for (p.tok == scanner.Ident || p.tok == scanner.Int || p.tok == '·') && sep > ' ' {123 ident += p.lit124 if p.tok == '·' {125 ident += "·"126 j = i127 i++128 }129 i += len(p.lit)130 sep = p.scanner.Peek()131 p.next()132 }133 // middot = \xc2\xb7134 if j != -1 && i > j+1 {135 c := ident[j+2]136 if c >= '0' && c <= '9' {137 ident = ident[0:j]138 }139 }140 return ident141}142// ImportPath = string_lit .143// quoted name of the path, but we return it as an identifier, taking an alias144// from 'pathToAlias' map, it is filled by import statements145func (p *gc_parser) parse_package() *ast.Ident {146 path, err := strconv.Unquote(p.expect(scanner.String))147 if err != nil {148 panic(err)149 }150 return ast.NewIdent(path)151}152// ExportedName = "@" ImportPath "." dotIdentifier .153func (p *gc_parser) parse_exported_name() *ast.SelectorExpr {154 p.expect('@')155 pkg := p.parse_package()156 if pkg.Name == "" {157 pkg.Name = "!" + p.pfc.name + "!" + p.pfc.defalias158 } else {159 pkg.Name = p.path_to_name[pkg.Name]160 }161 p.expect('.')162 name := ast.NewIdent(p.parse_dot_ident())163 return &ast.SelectorExpr{X: pkg, Sel: name}164}165// Name = identifier | "?" | ExportedName .166func (p *gc_parser) parse_name() (string, ast.Expr) {167 switch p.tok {168 case scanner.Ident:169 name := p.lit170 p.next()171 return name, ast.NewIdent(name)172 case '?':173 p.next()174 return "?", ast.NewIdent("?")175 case '@':176 en := p.parse_exported_name()177 return en.Sel.Name, en178 }179 p.error("name expected")180 return "", nil181}182// Field = Name Type [ string_lit ] .183func (p *gc_parser) parse_field() *ast.Field {184 var tag string185 name, _ := p.parse_name()186 typ := p.parse_type()187 if p.tok == scanner.String {188 tag = p.expect(scanner.String)189 }190 var names []*ast.Ident191 if name != "?" {192 names = []*ast.Ident{ast.NewIdent(name)}193 }194 return &ast.Field{195 Names: names,196 Type: typ,197 Tag: &ast.BasicLit{Kind: token.STRING, Value: tag},198 }199}200// Parameter = ( identifier | "?" ) [ "..." ] Type [ string_lit ] .201func (p *gc_parser) parse_parameter() *ast.Field {202 // name203 name, _ := p.parse_name()204 // type205 var typ ast.Expr206 if p.tok == '.' {207 p.expect_special("...")208 typ = &ast.Ellipsis{Elt: p.parse_type()}209 } else {210 typ = p.parse_type()211 }212 var tag string213 if p.tok == scanner.String {214 tag = p.expect(scanner.String)215 }216 return &ast.Field{217 Names: []*ast.Ident{ast.NewIdent(name)},218 Type: typ,219 Tag: &ast.BasicLit{Kind: token.STRING, Value: tag},220 }221}222// Parameters = "(" [ ParameterList ] ")" .223// ParameterList = { Parameter "," } Parameter .224func (p *gc_parser) parse_parameters() *ast.FieldList {225 flds := []*ast.Field{}226 parse_parameter := func() {227 par := p.parse_parameter()228 flds = append(flds, par)229 }230 p.expect('(')231 if p.tok != ')' {232 parse_parameter()233 for p.tok == ',' {234 p.next()235 parse_parameter()236 }237 }238 p.expect(')')239 return &ast.FieldList{List: flds}240}241// Signature = Parameters [ Result ] .242// Result = Type | Parameters .243func (p *gc_parser) parse_signature() *ast.FuncType {244 var params *ast.FieldList245 var results *ast.FieldList246 params = p.parse_parameters()247 switch p.tok {248 case scanner.Ident, '[', '*', '<', '@':249 fld := &ast.Field{Type: p.parse_type()}250 results = &ast.FieldList{List: []*ast.Field{fld}}251 case '(':252 results = p.parse_parameters()253 }254 return &ast.FuncType{Params: params, Results: results}255}256// MethodOrEmbedSpec = Name [ Signature ] .257func (p *gc_parser) parse_method_or_embed_spec() *ast.Field {258 name, nameexpr := p.parse_name()259 if p.tok == '(' {260 typ := p.parse_signature()261 return &ast.Field{262 Names: []*ast.Ident{ast.NewIdent(name)},263 Type: typ,264 }265 }266 return &ast.Field{267 Type: nameexpr,268 }269}270// int_lit = [ "-" | "+" ] { "0" ... "9" } .271func (p *gc_parser) parse_int() {272 switch p.tok {273 case '-', '+':274 p.next()275 }276 p.expect(scanner.Int)277}278// number = int_lit [ "p" int_lit ] .279func (p *gc_parser) parse_number() {280 p.parse_int()281 if p.lit == "p" {282 p.next()283 p.parse_int()284 }285}286//-------------------------------------------------------------------------------287// gc_parser.types288//-------------------------------------------------------------------------------289// InterfaceType = "interface" "{" [ MethodOrEmbedList ] "}" .290// MethodOrEmbedList = MethodOrEmbedSpec { ";" MethodOrEmbedSpec } .291func (p *gc_parser) parse_interface_type() ast.Expr {292 var methods []*ast.Field293 parse_method := func() {294 meth := p.parse_method_or_embed_spec()295 methods = append(methods, meth)296 }297 p.expect_keyword("interface")298 p.expect('{')299 if p.tok != '}' {300 parse_method()301 for p.tok == ';' {302 p.next()303 parse_method()304 }305 }306 p.expect('}')307 return &ast.InterfaceType{Methods: &ast.FieldList{List: methods}}308}309// StructType = "struct" "{" [ FieldList ] "}" .310// FieldList = Field { ";" Field } .311func (p *gc_parser) parse_struct_type() ast.Expr {312 var fields []*ast.Field313 parse_field := func() {314 fld := p.parse_field()315 fields = append(fields, fld)316 }317 p.expect_keyword("struct")318 p.expect('{')319 if p.tok != '}' {320 parse_field()321 for p.tok == ';' {322 p.next()323 parse_field()324 }325 }326 p.expect('}')327 return &ast.StructType{Fields: &ast.FieldList{List: fields}}328}329// MapType = "map" "[" Type "]" Type .330func (p *gc_parser) parse_map_type() ast.Expr {331 p.expect_keyword("map")332 p.expect('[')333 key := p.parse_type()334 p.expect(']')335 elt := p.parse_type()336 return &ast.MapType{Key: key, Value: elt}337}338// ChanType = ( "chan" [ "<-" ] | "<-" "chan" ) Type .339func (p *gc_parser) parse_chan_type() ast.Expr {340 dir := ast.SEND | ast.RECV341 if p.tok == scanner.Ident {342 p.expect_keyword("chan")343 if p.tok == '<' {344 p.expect_special("<-")345 dir = ast.SEND346 }347 } else {348 p.expect_special("<-")349 p.expect_keyword("chan")350 dir = ast.RECV351 }352 elt := p.parse_type()353 return &ast.ChanType{Dir: dir, Value: elt}354}355// ArrayOrSliceType = ArrayType | SliceType .356// ArrayType = "[" int_lit "]" Type .357// SliceType = "[" "]" Type .358func (p *gc_parser) parse_array_or_slice_type() ast.Expr {359 p.expect('[')360 if p.tok == ']' {361 // SliceType362 p.next() // skip ']'363 return &ast.ArrayType{Len: nil, Elt: p.parse_type()}364 }365 // ArrayType366 lit := p.expect(scanner.Int)367 p.expect(']')368 return &ast.ArrayType{369 Len: &ast.BasicLit{Kind: token.INT, Value: lit},370 Elt: p.parse_type(),371 }372}373// Type =374// BasicType | TypeName | ArrayType | SliceType | StructType |375// PointerType | FuncType | InterfaceType | MapType | ChanType |376// "(" Type ")" .377// BasicType = ident .378// TypeName = ExportedName .379// SliceType = "[" "]" Type .380// PointerType = "*" Type .381// FuncType = "func" Signature .382func (p *gc_parser) parse_type() ast.Expr {383 switch p.tok {384 case scanner.Ident:385 switch p.lit {386 case "struct":387 return p.parse_struct_type()388 case "func":389 p.next()390 return p.parse_signature()391 case "interface":392 return p.parse_interface_type()393 case "map":394 return p.parse_map_type()395 case "chan":396 return p.parse_chan_type()397 default:398 lit := p.lit399 p.next()400 return ast.NewIdent(lit)401 }402 case '@':403 return p.parse_exported_name()404 case '[':405 return p.parse_array_or_slice_type()406 case '*':407 p.next()408 return &ast.StarExpr{X: p.parse_type()}409 case '<':410 return p.parse_chan_type()411 case '(':412 p.next()413 typ := p.parse_type()414 p.expect(')')415 return typ416 }417 p.errorf("unexpected token: %s", scanner.TokenString(p.tok))418 return nil419}420//-------------------------------------------------------------------------------421// gc_parser.declarations422//-------------------------------------------------------------------------------423// ImportDecl = "import" identifier string_lit .424func (p *gc_parser) parse_import_decl() {425 p.expect_keyword("import")426 alias := p.expect(scanner.Ident)427 path := p.parse_package()428 fullName := "!" + path.Name + "!" + alias429 p.path_to_name[path.Name] = fullName430 p.pfc.add_package_to_scope(fullName, path.Name)431}432// ConstDecl = "const" ExportedName [ Type ] "=" Literal .433// Literal = bool_lit | int_lit | float_lit | complex_lit | string_lit .434// bool_lit = "true" | "false" .435// complex_lit = "(" float_lit "+" float_lit ")" .436// rune_lit = "(" int_lit "+" int_lit ")" .437// string_lit = `"` { unicode_char } `"` .438func (p *gc_parser) parse_const_decl() (string, *ast.GenDecl) {439 // TODO: do we really need actual const value? gocode doesn't use this440 p.expect_keyword("const")441 name := p.parse_exported_name()442 var typ ast.Expr443 if p.tok != '=' {444 typ = p.parse_type()445 }446 p.expect('=')447 // skip the value448 switch p.tok {449 case scanner.Ident:450 // must be bool, true or false451 p.next()452 case '-', '+', scanner.Int:453 // number454 p.parse_number()455 case '(':456 // complex_lit or rune_lit457 p.next() // skip '('458 if p.tok == scanner.Char {459 p.next()460 } else {461 p.parse_number()462 }463 p.expect('+')464 p.parse_number()465 p.expect(')')466 case scanner.Char:467 p.next()468 case scanner.String:469 p.next()470 default:471 p.error("expected literal")472 }473 return name.X.(*ast.Ident).Name, &ast.GenDecl{474 Tok: token.CONST,475 Specs: []ast.Spec{476 &ast.ValueSpec{477 Names: []*ast.Ident{name.Sel},478 Type: typ,479 Values: []ast.Expr{&ast.BasicLit{Kind: token.INT, Value: "0"}},480 },481 },482 }483}484// TypeDecl = "type" ExportedName Type .485func (p *gc_parser) parse_type_decl() (string, *ast.GenDecl) {486 p.expect_keyword("type")487 name := p.parse_exported_name()488 typ := p.parse_type()489 return name.X.(*ast.Ident).Name, &ast.GenDecl{490 Tok: token.TYPE,491 Specs: []ast.Spec{492 &ast.TypeSpec{493 Name: name.Sel,494 Type: typ,495 },496 },497 }498}499// VarDecl = "var" ExportedName Type .500func (p *gc_parser) parse_var_decl() (string, *ast.GenDecl) {501 p.expect_keyword("var")502 name := p.parse_exported_name()503 typ := p.parse_type()504 return name.X.(*ast.Ident).Name, &ast.GenDecl{505 Tok: token.VAR,506 Specs: []ast.Spec{507 &ast.ValueSpec{508 Names: []*ast.Ident{name.Sel},509 Type: typ,510 },511 },512 }513}514// FuncBody = "{" ... "}" .515func (p *gc_parser) parse_func_body() {516 p.expect('{')517 for i := 1; i > 0; p.next() {518 switch p.tok {519 case '{':520 i++521 case '}':522 i--523 }524 }525}526// FuncDecl = "func" ExportedName Signature [ FuncBody ] .527func (p *gc_parser) parse_func_decl() (string, *ast.FuncDecl) {528 // "func" was already consumed by lookahead529 name := p.parse_exported_name()530 typ := p.parse_signature()531 if p.tok == '{' {532 p.parse_func_body()533 }534 return name.X.(*ast.Ident).Name, &ast.FuncDecl{535 Name: name.Sel,536 Type: typ,537 }538}539func strip_method_receiver(recv *ast.FieldList) string {540 var sel *ast.SelectorExpr541 // find selector expression542 typ := recv.List[0].Type543 switch t := typ.(type) {544 case *ast.StarExpr:545 sel = t.X.(*ast.SelectorExpr)546 case *ast.SelectorExpr:547 sel = t548 }549 // extract package path550 pkg := sel.X.(*ast.Ident).Name551 // write back stripped type552 switch t := typ.(type) {553 case *ast.StarExpr:554 t.X = sel.Sel555 case *ast.SelectorExpr:556 recv.List[0].Type = sel.Sel557 }558 return pkg559}560// MethodDecl = "func" Receiver Name Signature .561// Receiver = "(" ( identifier | "?" ) [ "*" ] ExportedName ")" [ FuncBody ] .562func (p *gc_parser) parse_method_decl() (string, *ast.FuncDecl) {563 recv := p.parse_parameters()564 pkg := strip_method_receiver(recv)565 name, _ := p.parse_name()566 typ := p.parse_signature()567 if p.tok == '{' {568 p.parse_func_body()569 }570 return pkg, &ast.FuncDecl{571 Recv: recv,572 Name: ast.NewIdent(name),573 Type: typ,574 }575}576// Decl = [ ImportDecl | ConstDecl | TypeDecl | VarDecl | FuncDecl | MethodDecl ] "\n" .577func (p *gc_parser) parse_decl() (pkg string, decl ast.Decl) {578 switch p.lit {579 case "import":580 p.parse_import_decl()581 case "const":582 pkg, decl = p.parse_const_decl()583 case "type":584 pkg, decl = p.parse_type_decl()585 case "var":586 pkg, decl = p.parse_var_decl()587 case "func":588 p.next()589 if p.tok == '(' {590 pkg, decl = p.parse_method_decl()591 } else {592 pkg, decl = p.parse_func_decl()593 }594 }595 p.expect('\n')596 return597}598// Export = PackageClause { Decl } "$$" .599// PackageClause = "package" identifier [ "safe" ] "\n" .600func (p *gc_parser) parse_export(callback func(string, ast.Decl)) {601 p.expect_keyword("package")602 p.pfc.defalias = p.expect(scanner.Ident)603 if p.tok != '\n' {604 p.expect_keyword("safe")605 }606 p.expect('\n')607 for p.tok != '$' && p.tok != scanner.EOF {608 pkg, decl := p.parse_decl()609 if decl != nil {610 callback(pkg, decl)611 }612 }613}...
parser.go
Source:parser.go
...34 }35 return p.statement()36}37func (p *Parser) varDeclaration() ast.Stmt {38 varName := p.requireToken(lexing.Identifier, "variable name expected")39 var initializer ast.Expr40 if p.peek().TokenType == lexing.Equal {41 p.advance()42 initializer = p.expression()43 }44 p.requireToken(lexing.Semicolon, "';' expected")45 return ast.VarDeclarationStmt{46 Name: varName,47 Initializer: initializer,48 }49}50func (p *Parser) funDeclaration() ast.Stmt {51 funcName := p.requireToken(lexing.Identifier, "function name expected")52 p.requireToken(lexing.LeftParen, "function declaration expect '('")53 parameters := make([]lexing.Token, 0)54 if !p.match(lexing.RightParen) {55 parameters = append(parameters, p.requireToken(lexing.Identifier,56 "function declaration expect identifier as param name"))57 for p.match(lexing.Comma) {58 p.advance()59 if len(parameters) >= 255 {60 p.parseError(p.peek(), "declared more than 255 parameters")61 break62 }63 parameters = append(parameters, p.requireToken(lexing.Identifier,64 "function declaration expect identifier as param name"))65 }66 }67 p.requireToken(lexing.RightParen, "function declaration expect ')'")68 p.requireToken(lexing.LeftBrace, "expect '{' before function body")69 innerFunc := p.isFuncScope70 p.isFuncScope = true71 defer func() {72 if !innerFunc {73 p.isFuncScope = false74 }75 }()76 statement := p.blockStatement()77 return ast.FunDeclarationStmt{78 Name: funcName,79 Params: parameters,80 Statement: statement.(ast.BlockStmt),81 }82}83func (p *Parser) statement() ast.Stmt {84 switch {85 case p.match(lexing.LeftBrace):86 p.advance()87 return p.blockStatement()88 case p.match(lexing.If):89 p.advance()90 return p.ifStatement()91 case p.match(lexing.While):92 p.advance()93 return p.whileStatement()94 case p.match(lexing.For):95 p.advance()96 return p.forStatement()97 case p.match(lexing.Break):98 if p.isLoopScope {99 p.advance()100 return p.breakStatement()101 } else {102 p.parseError(p.peek(), "break statement not within loop")103 }104 case p.match(lexing.Continue):105 if p.isLoopScope {106 p.advance()107 return p.continueStatement()108 } else {109 p.parseError(p.peek(), "continue statement not within loop")110 }111 case p.match(lexing.Return):112 if p.isFuncScope {113 return p.returnStatement(p.advance())114 } else {115 p.parseError(p.peek(), "return statement not within func body")116 }117 }118 return p.expressionStatement()119}120func (p *Parser) returnStatement(returnToken lexing.Token) ast.Stmt {121 var returnExpr ast.Expr122 if !p.match(lexing.Semicolon) {123 returnExpr = p.expression()124 }125 p.requireToken(lexing.Semicolon, "expect ';' after return keyword")126 return ast.ReturnStmt{127 ReturnToken: returnToken,128 Expr: returnExpr,129 }130}131func (p *Parser) breakStatement() ast.Stmt {132 p.requireToken(lexing.Semicolon, "expect ';' after break statement")133 return ast.BreakStmt{}134}135func (p *Parser) continueStatement() ast.Stmt {136 p.requireToken(lexing.Semicolon, "expect ';' after continue statement")137 return ast.ContinueStmt{}138}139func (p *Parser) forStatement() ast.Stmt {140 p.requireToken(lexing.LeftParen, "for statement expect '('")141 var initializerStmt ast.Stmt142 switch {143 case p.match(lexing.Var):144 p.advance()145 initializerStmt = p.varDeclaration()146 case p.match(lexing.Semicolon):147 p.advance()148 default:149 initializerStmt = p.expressionStatement()150 }151 var conditionExpr ast.Expr152 if !p.match(lexing.Semicolon) {153 conditionExpr = p.expression()154 } else {155 conditionExpr = ast.LiteralExpr{LiteralValue: true}156 }157 p.requireToken(lexing.Semicolon,158 "for statement expect ';' between condition and increment expressions")159 var incrementExpr ast.Expr160 if !p.match(lexing.RightParen) {161 incrementExpr = p.expression()162 }163 p.requireToken(lexing.RightParen, "for statement expect ')'")164 innerLoop := p.isLoopScope165 p.isLoopScope = true166 defer func() {167 if !innerLoop {168 p.isLoopScope = false169 }170 }()171 statement := p.statement()172 return ast.ForStmt{173 InitializerStmt: initializerStmt,174 ConditionExpr: conditionExpr,175 IncrementExpr: incrementExpr,176 Statement: statement,177 }178}179func (p *Parser) whileStatement() ast.Stmt {180 p.requireToken(lexing.LeftParen, "while statement expect '(' before condition")181 conditionExpr := p.expression()182 p.requireToken(lexing.RightParen, "while statement expect ')' after condition")183 innerLoop := p.isLoopScope184 p.isLoopScope = true185 defer func() {186 if !innerLoop {187 p.isLoopScope = false188 }189 }()190 statement := p.statement()191 return ast.ForStmt{192 ConditionExpr: conditionExpr,193 Statement: statement,194 }195}196func (p *Parser) ifStatement() ast.Stmt {197 p.requireToken(lexing.LeftParen, "if statement expect '(' before condition")198 conditionExpr := p.expression()199 p.requireToken(lexing.RightParen, "if statement expect ')' after condition")200 ifStatement := p.statement()201 var elseStatement ast.Stmt202 if p.match(lexing.Else) {203 p.advance()204 elseStatement = p.statement()205 }206 return ast.IfStmt{207 ConditionExpr: conditionExpr,208 IfStatement: ifStatement,209 ElseStatement: elseStatement,210 }211}212func (p *Parser) blockStatement() ast.Stmt {213 var stmts []ast.Stmt214 for !p.match(lexing.RightBrace) && !p.isEof() {215 stmts = append(stmts, p.declaration())216 }217 p.requireToken(lexing.RightBrace, "'}' end of block expected")218 return ast.BlockStmt{Stmts: stmts}219}220func (p *Parser) expressionStatement() ast.Stmt {221 expr := p.expression()222 p.requireToken(lexing.Semicolon, "';' expected")223 return ast.ExpressionStmt{Expr: expr}224}225func (p *Parser) expression() ast.Expr {226 return p.comma()227}228func (p *Parser) lambda() ast.Expr {229 p.requireToken(lexing.LeftParen, "lambda declaration expect '('")230 parameters := make([]lexing.Token, 0)231 if !p.match(lexing.RightParen) {232 parameters = append(parameters, p.requireToken(lexing.Identifier,233 "lambda declaration expect identifier as param name"))234 for p.match(lexing.Comma) {235 p.advance()236 if len(parameters) >= 255 {237 p.parseError(p.peek(), "declared more than 255 parameters")238 break239 }240 parameters = append(parameters, p.requireToken(lexing.Identifier,241 "lambda declaration expect identifier as param name"))242 }243 }244 p.requireToken(lexing.RightParen, "lambda declaration expect ')'")245 p.requireToken(lexing.LeftBrace, "expect '{' before lambda body")246 innerFunc := p.isFuncScope247 p.isFuncScope = true248 defer func() {249 if !innerFunc {250 p.isFuncScope = false251 }252 }()253 statement := p.blockStatement()254 return ast.LambdaExpr{255 Params: parameters,256 Statement: statement.(ast.BlockStmt),257 }258}259func (p *Parser) comma() ast.Expr {260 var expr ast.Expr261 expr = p.assignment()262 for p.match(lexing.Comma) {263 operator := p.advance()264 rightExpr := p.assignment()265 expr = ast.BinaryExpr{266 LeftExpr: expr,267 Operator: operator,268 RightExpr: rightExpr,269 }270 }271 return expr272}273func (p *Parser) assignment() ast.Expr {274 if p.match(lexing.Fun) {275 p.advance()276 return p.lambda()277 }278 expr := p.logicalOr()279 if p.match(lexing.Equal) {280 equalToken := p.advance()281 value := p.assignment()282 switch expr.(type) {283 case ast.VariableExpr:284 return ast.AssignExpr{285 Variable: expr.(ast.VariableExpr),286 Initializer: value,287 }288 case ast.IndexExpr:289 return ast.AssignExpr{290 Variable: expr.(ast.IndexExpr),291 Initializer: value,292 }293 }294 p.parseError(equalToken, "invalid assignment target")295 }296 if p.match(lexing.Question) {297 p.advance()298 trueValue := p.logicalOr()299 p.requireToken(lexing.Colon, "ternary operator expect ':'")300 falseValue := p.logicalOr()301 return ast.TernaryExpr{302 Condition: expr,303 TrueExpr: trueValue,304 FalseExpr: falseValue,305 }306 }307 return expr308}309func (p *Parser) logicalOr() ast.Expr {310 var expr ast.Expr311 expr = p.logicalAnd()312 for p.match(lexing.Or) {313 operator := p.advance()314 rightExpr := p.logicalAnd()315 expr = ast.LogicalExpr{316 LeftExpr: expr,317 Operator: operator,318 RightExpr: rightExpr,319 }320 }321 return expr322}323func (p *Parser) logicalAnd() ast.Expr {324 var expr ast.Expr325 expr = p.equality()326 for p.match(lexing.And) {327 operator := p.advance()328 rightExpr := p.equality()329 expr = ast.LogicalExpr{330 LeftExpr: expr,331 Operator: operator,332 RightExpr: rightExpr,333 }334 }335 return expr336}337func (p *Parser) equality() ast.Expr {338 var expr ast.Expr339 expr = p.comparison()340 for p.match(lexing.BangEqual, lexing.EqualEqual) {341 operator := p.advance()342 rightExpr := p.comparison()343 expr = ast.BinaryExpr{344 LeftExpr: expr,345 Operator: operator,346 RightExpr: rightExpr,347 }348 }349 return expr350}351func (p *Parser) comparison() ast.Expr {352 var expr ast.Expr353 expr = p.term()354 for p.match(lexing.Less, lexing.LessEqual, lexing.Greater, lexing.GreaterEqual) {355 operator := p.advance()356 rightExpr := p.term()357 expr = ast.BinaryExpr{358 LeftExpr: expr,359 Operator: operator,360 RightExpr: rightExpr,361 }362 }363 return expr364}365func (p *Parser) term() ast.Expr {366 var expr ast.Expr367 expr = p.factor()368 for p.match(lexing.Minus, lexing.Plus) {369 operator := p.advance()370 rightExpr := p.factor()371 expr = ast.BinaryExpr{372 LeftExpr: expr,373 Operator: operator,374 RightExpr: rightExpr,375 }376 }377 return expr378}379func (p *Parser) factor() ast.Expr {380 var expr ast.Expr381 expr = p.unary()382 for p.match(lexing.Star, lexing.Slash) {383 operator := p.advance()384 rightExpr := p.unary()385 expr = ast.BinaryExpr{386 LeftExpr: expr,387 Operator: operator,388 RightExpr: rightExpr,389 }390 }391 return expr392}393func (p *Parser) unary() ast.Expr {394 for p.match(lexing.Bang, lexing.Minus) {395 operator := p.advance()396 rightExpr := p.unary()397 return ast.UnaryExpr{398 Operator: operator,399 RightExpr: rightExpr,400 }401 }402 return p.call()403}404func (p *Parser) call() ast.Expr {405 expr := p.primary()406 if p.match(lexing.LeftParen) {407 for p.match(lexing.LeftParen) {408 p.advance()409 expr = p.callArguments(expr)410 }411 return expr412 }413 if p.match(lexing.LeftBracket) {414 for p.match(lexing.LeftBracket) {415 p.advance()416 expr = p.arrayIndex(expr)417 }418 return expr419 }420 return expr421}422func (p *Parser) callArguments(callee ast.Expr) ast.Expr {423 arguments := make([]ast.Expr, 0)424 if !p.match(lexing.RightParen) {425 arguments = append(arguments, p.assignment())426 for p.match(lexing.Comma) {427 p.advance()428 if len(arguments) >= 255 {429 p.parseError(p.peek(), "passed more than 255 arguments")430 break431 }432 arguments = append(arguments, p.assignment())433 }434 }435 paren := p.requireToken(lexing.RightParen, "function call expect ')'")436 return ast.CallExpr{437 Callee: callee,438 Paren: paren,439 Arguments: arguments,440 }441}442func (p *Parser) arrayIndex(array ast.Expr) ast.Expr {443 indexExpr := p.expression()444 bracket := p.requireToken(lexing.RightBracket, "array index expression expect ']'")445 return ast.IndexExpr{446 Array: array,447 Bracket: bracket,448 IndexExpr: indexExpr,449 }450}451func (p *Parser) primary() ast.Expr {452 switch {453 case p.match(lexing.False):454 p.advance()455 return ast.LiteralExpr{LiteralValue: false}456 case p.match(lexing.True):457 p.advance()458 return ast.LiteralExpr{LiteralValue: true}459 case p.match(lexing.Nil):460 p.advance()461 return ast.LiteralExpr{LiteralValue: nil}462 case p.match(lexing.Number, lexing.String):463 astNode := ast.LiteralExpr{LiteralValue: p.peek().Literal}464 p.advance()465 return astNode466 case p.match(lexing.LeftParen):467 p.advance()468 expr := p.expression()469 p.requireToken(lexing.RightParen, "expect ')' token after expression")470 return ast.GroupingExpr{Expr: expr}471 case p.match(lexing.LeftBracket):472 p.advance()473 return p.arrayElements()474 case p.match(lexing.Identifier):475 return ast.VariableExpr{Name: p.advance()}476 }477 p.parseError(p.peek(), "expect expression")478 return nil479}480func (p *Parser) arrayElements() ast.Expr {481 elements := make([]ast.Expr, 0)482 if !p.match(lexing.RightBracket) {483 elements = append(elements, p.assignment())484 for p.match(lexing.Comma) {485 p.advance()486 elements = append(elements, p.assignment())487 }488 }489 p.requireToken(lexing.RightBracket, "array initializer expect ']'")490 return ast.ArrayExpr{491 Elements: elements,492 }493}494func (p *Parser) requireToken(tokenType lexing.TokenType, message string) lexing.Token {495 if p.match(tokenType) {496 return p.advance()497 } else {498 p.parseError(p.peek(), message)499 return lexing.Token{}500 }501}502func (p *Parser) parseError(token lexing.Token, message string) {503 var buffer bytes.Buffer...
expect
Using AI Code Generation
1import (2func main() {3 fset := token.NewFileSet()4 f, err := parser.ParseFile(fset, "1.go", nil, 0)5 if err != nil {6 panic(err)7 }8 ast.Inspect(f, func(n ast.Node) bool {9 switch x := n.(type) {10 if fun, ok := x.Fun.(*ast.Ident); ok && fun.Name == "expect" {11 fmt.Println(fset.Position(x.Lparen))12 }13 }14 })15}16The Position() method returns a token.Position object, which has the following fields:17To find the position of a node, we can use the Position() method on the fset object. This method takes the position of the node as the argument and returns the position of the node in the
expect
Using AI Code Generation
1import (2func main() {3 fset := token.NewFileSet()4 node, err := parser.ParseFile(fset, "2.go", nil, 0)5 if err != nil {6 fmt.Println(err)7 }8 for _, d := range node.Decls {9 fn, ok := d.(*ast.FuncDecl)10 if !ok {11 }12 fmt.Println(fn.Name.Name)13 }14}
expect
Using AI Code Generation
1import (2func main() {3 import "fmt"4 func main() {5 fmt.Println("hello, world")6 }7 f, err := parser.ParseFile(fset, "main.go", src, parser.ParseComments)8 if err != nil {9 panic(err)10 }11 ast.Print(fset, f)12}
expect
Using AI Code Generation
1import (2func main() {3 node, err := parser.ParseFile(fset, "2.go", nil, parser.ImportsOnly)4 if err != nil {5 }6 for _, s := range node.Imports {7 fmt.Println(s.Path.Value)8 }9}10import (11func main() {12 node, err := parser.ParseFile(fset, "3.go", nil, parser.ParseComments)13 if err != nil {14 }15 ast.Print(fset, node)16}17import (18func main() {19 node, err := parser.ParseFile(fset, "4.go", nil, parser.ParseComments)20 if err != nil {21 }22 ast.Print(fset, node)23}24import (25func main() {26 node, err := parser.ParseFile(fset, "5.go", nil
expect
Using AI Code Generation
1import (2func main() {3import "fmt"4func main() {5 fmt.Println("Hello, World!")6}7 f, err := parser.ParseFile(fset, "hello.go", src, 0)8 if err != nil {9 }10 ast.Print(fset, f)11}
expect
Using AI Code Generation
1import (2func main() {3 import (4 func main() {5 fmt.Println("Hello, playground")6 }`7 f, err := parser.ParseFile(fset, "src.go", src, parser.ImportsOnly)8 if err != nil {9 panic(err)10 }11 for _, s := range f.Imports {12 fmt.Println(fset.Position(s.Pos()), fset.Position(s.End()), s.Path.Value)13 }14}15{src.go 2 8} {src.go 2 21} "fmt"16import (17func main() {18 import (19 func main() {20 fmt.Println("Hello, playground")21 }`22 f, err := parser.ParseFile(fset, "src.go", src, parser.ImportsOnly)23 if err != nil {24 panic(err)25 }26 for _, s := range f.Imports {27 fmt.Println(fset.Position(s.Pos()), fset.Position(s.End()), s.Path.Value)28 }29}30{src.go 2 8} {src.go 2 21} "fmt"31import (32func main() {
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!