github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/go/tao/auth/parser.go (about) 1 // Copyright (c) 2014, Kevin Walsh. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // This code borrows heavily from the parser design and implementation for the 16 // template package. See http://golang.org/src/pkg/text/template/parse/parse.go 17 // 18 // It also borrows from the parser in package 19 // github.com/kevinawalsh/datalog/dlengine 20 // licensed by the author here under the above Apache License, Version 2.0. 21 22 package auth 23 24 import ( 25 "fmt" 26 ) 27 28 // The functions in this file use one token lookahead, but only when more input 29 // is actually called for. The lexer may read one rune ahead while getting a 30 // token, but will unread that rune when the token is completed. The goal is to 31 // allow parsing an element out of a string or input stream that contains other 32 // data after the element. 33 // 34 // The parseX() functions properly handle outer parenthesis. For 35 // example, parsePred() will accept "P(1)", "(P(1))", and " ( ((P((1 )) ) ))". 36 // The expectX() functions do not allow outer parenthesis. So 37 // expectPred() will handle "P(1)" and "P( (( 1) ))", but not "(P(1))". 38 // 39 // Onless otherwise documented, in all cases the parseX() and expectX() 40 // functions are greedy, consuming input until either an error is encountered or 41 // the element can't be expanded further. 42 43 // parser holds the state of the recursive descent parser. 44 type parser struct { 45 lex *lexer 46 lookahead token 47 haveLookahead bool 48 } 49 50 // cur advances the lexer if needed and returns the first unprocessed token. 51 func (p *parser) cur() token { 52 if !p.haveLookahead { 53 p.lookahead = p.lex.nextToken() 54 p.haveLookahead = true 55 } 56 return p.lookahead 57 } 58 59 // advance discards lookahead; the next call to cur() will get a new token. 60 func (p *parser) advance() { 61 // if !p.haveLookahead { 62 // panic("advance should only be called when there is a current token") 63 // } 64 p.haveLookahead = false 65 } 66 67 // expect checks whether cur matches t and, if so, advances to the next token. 68 func (p *parser) expect(t token) error { 69 if p.cur() != t { 70 return fmt.Errorf("expected %q, found %v", t.val, p.cur()) 71 } 72 p.advance() 73 return nil 74 } 75 76 // skipOpenParens skips and counts open parens. 77 func (p *parser) skipOpenParens() int { 78 var n int 79 for n = 0; p.cur() == tokenLP; n++ { 80 p.advance() 81 } 82 return n 83 } 84 85 // expectCloseParens expects n close parens. 86 func (p *parser) expectCloseParens(n int) error { 87 for n > 0 { 88 err := p.expect(tokenRP) 89 if err != nil { 90 return err 91 } 92 n-- 93 } 94 return nil 95 } 96 97 // expectPrinTail expects a PrinTail. 98 func (p *parser) expectPrinTail() (pt PrinTail, err error) { 99 if p.cur() != tokenExt { 100 err = fmt.Errorf(`expected "ext", found %v`, p.cur()) 101 return 102 } 103 p.advance() 104 for p.lex.peek() == '.' { 105 pt.Ext, err = p.expectSubPrin() 106 if err != nil { 107 return 108 } 109 } 110 if len(pt.Ext) == 0 { 111 err = fmt.Errorf(`an "ext" PrinTail must have at least one extension`) 112 } 113 return 114 } 115 116 // expectPrin expects a Prin. 117 func (p *parser) expectPrin() (prin Prin, err error) { 118 if !isPrinToken(p.cur()) { 119 err = fmt.Errorf(`expected a principal token, found %v`, p.cur()) 120 return 121 } 122 prin.Type = p.cur().val.(string) 123 p.advance() 124 if r := p.lex.peek(); r != '(' { 125 err = fmt.Errorf(`expected '(' directly after "key", found %q`, r) 126 return 127 } 128 err = p.expect(tokenLP) 129 if err != nil { 130 return 131 } 132 prin.KeyHash, err = p.expectTerm() 133 if err != nil { 134 return 135 } 136 err = p.expect(tokenRP) 137 if err != nil { 138 return 139 } 140 for p.lex.peek() == '.' { 141 prin.Ext, err = p.expectSubPrin() 142 } 143 return 144 } 145 146 // parsePrin parses a Prin with optional outer parens. 147 func (p *parser) parsePrin() (prin Prin, err error) { 148 n := p.skipOpenParens() 149 prin, err = p.expectPrin() 150 if err != nil { 151 return 152 } 153 err = p.expectCloseParens(n) 154 return 155 } 156 157 // parsePrinTail parses a PrinTail with optional outer parens. 158 func (p *parser) parsePrinTail() (pt PrinTail, err error) { 159 n := p.skipOpenParens() 160 pt, err = p.expectPrinTail() 161 if err != nil { 162 return 163 } 164 err = p.expectCloseParens(n) 165 return 166 } 167 168 // expectSubPrin expects a SubPrin. 169 func (p *parser) expectSubPrin() (s SubPrin, err error) { 170 if p.cur() != tokenDot { 171 err = fmt.Errorf(`expected '.', found %v`, p.cur()) 172 return 173 } 174 p.advance() 175 name, args, err := p.expectNameAndArgs() 176 if err != nil { 177 return 178 } 179 s = append(s, PrinExt{name, args}) 180 for p.lex.peek() == '.' { 181 if p.cur() != tokenDot { 182 panic("not reached") 183 } 184 p.advance() 185 name, args, err = p.expectNameAndArgs() 186 if err != nil { 187 return 188 } 189 s = append(s, PrinExt{name, args}) 190 } 191 return 192 } 193 194 // expectNameAndArgs expects an identifier followed by a parenthesized list of 195 // zero or more comma-separated terms. 196 func (p *parser) expectNameAndArgs() (name string, args []Term, err error) { 197 name, hadParen, args, err := p.expectIdentifierOrNameAndArgs() 198 if !hadParen { 199 err = fmt.Errorf("expected '(', found %v", p.cur()) 200 } 201 return 202 } 203 204 // expectIdentifierOrNameAndArgs expects an identifier, optionally followed by a 205 // parenthesized list of zero or more comma-separated terms. 206 func (p *parser) expectIdentifierOrNameAndArgs() (name string, hadParen bool, args []Term, err error) { 207 if p.cur().typ != itemIdentifier { 208 err = fmt.Errorf("expected identifier, found %v", p.cur()) 209 return 210 } 211 name = p.cur().val.(string) 212 p.advance() 213 if p.lex.peek() != '(' { 214 // no parens 215 return 216 } 217 if p.cur() != tokenLP { 218 panic("not reached") 219 } 220 hadParen = true 221 p.advance() 222 if p.cur() == tokenRP { 223 // empty parens 224 p.advance() 225 return 226 } 227 for { 228 var t Term 229 t, err = p.parseTerm() 230 if err != nil { 231 return 232 } 233 args = append(args, t) 234 if p.cur() != tokenComma { 235 break 236 } 237 p.advance() 238 } 239 err = p.expect(tokenRP) 240 return 241 } 242 243 // expectStr expects a Str. 244 func (p *parser) expectStr() (Str, error) { 245 if p.cur().typ != itemStr { 246 return "", fmt.Errorf("expected string, found %v", p.cur()) 247 } 248 t := Str(p.cur().val.(string)) 249 p.advance() 250 return t, nil 251 } 252 253 // parseStr parses a Str with optional outer parens. 254 func (p *parser) parseStr() (t Str, err error) { 255 n := p.skipOpenParens() 256 t, err = p.expectStr() 257 if err != nil { 258 return 259 } 260 err = p.expectCloseParens(n) 261 return 262 } 263 264 // expectBytes expects a Bytes. 265 func (p *parser) expectBytes() (Bytes, error) { 266 if p.cur().typ != itemBytes { 267 return nil, fmt.Errorf("expected bytes, found %v", p.cur()) 268 } 269 t := Bytes(p.cur().val.([]byte)) 270 p.advance() 271 return t, nil 272 } 273 274 // parseBytes parses a Bytes with optional outer parens. 275 func (p *parser) parseBytes() (t Bytes, err error) { 276 n := p.skipOpenParens() 277 t, err = p.expectBytes() 278 if err != nil { 279 return 280 } 281 err = p.expectCloseParens(n) 282 return 283 } 284 285 // expectInt expects an Int. 286 func (p *parser) expectInt() (Int, error) { 287 if p.cur().typ != itemInt { 288 return 0, fmt.Errorf("expected int, found %v", p.cur()) 289 } 290 t := Int(p.cur().val.(int64)) 291 p.advance() 292 return t, nil 293 } 294 295 // parseInt parses an Int with optional outer parens. 296 func (p *parser) parseInt() (Int, error) { 297 n := p.skipOpenParens() 298 t, err := p.expectInt() 299 if err != nil { 300 return 0, err 301 } 302 err = p.expectCloseParens(n) 303 if err != nil { 304 return 0, err 305 } 306 return t, nil 307 } 308 309 // expectTermVar expects a TermVar. 310 func (p *parser) expectTermVar() (TermVar, error) { 311 if p.cur().typ != itemIdentifier { 312 return "", fmt.Errorf("expected identifier, found %v", p.cur()) 313 } 314 t := TermVar(p.cur().val.(string)) 315 p.advance() 316 return t, nil 317 } 318 319 // parseTermVar parses a TermVar with optional outer parens. 320 func (p *parser) parseTermVar() (TermVar, error) { 321 n := p.skipOpenParens() 322 t, err := p.expectTermVar() 323 if err != nil { 324 return "", err 325 } 326 err = p.expectCloseParens(n) 327 if err != nil { 328 return "", err 329 } 330 return t, nil 331 } 332 333 // expectTerm expects a Term. 334 func (p *parser) expectTerm() (Term, error) { 335 switch p.cur().typ { 336 case itemStr: 337 return p.expectStr() 338 case itemBytes: 339 return p.expectBytes() 340 case itemInt: 341 return p.expectInt() 342 case itemKeyword: 343 switch { 344 case p.cur() == tokenExt: 345 return p.expectPrinTail() 346 case isPrinToken(p.cur()): 347 return p.expectPrin() 348 default: 349 return nil, fmt.Errorf(`expected keyword of principal token or ext, found %s`, p.cur().val) 350 } 351 case itemIdentifier: 352 return p.expectTermVar() 353 default: 354 return nil, fmt.Errorf("expected term, found %v", p.cur()) 355 } 356 } 357 358 // parseTerm parses a Term with optional outer parens. 359 func (p *parser) parseTerm() (Term, error) { 360 n := p.skipOpenParens() 361 t, err := p.expectTerm() 362 if err != nil { 363 return nil, err 364 } 365 err = p.expectCloseParens(n) 366 if err != nil { 367 return nil, err 368 } 369 return t, nil 370 } 371 372 // expectPred expects a Pred. 373 func (p *parser) expectPred() (f Pred, err error) { 374 name, args, err := p.expectNameAndArgs() 375 if err != nil { 376 return 377 } 378 return Pred{name, args}, nil 379 } 380 381 // parsePred parses a Pred with optional outer parens. 382 func (p *parser) parsePred() (f Pred, err error) { 383 n := p.skipOpenParens() 384 f, err = p.expectPred() 385 if err != nil { 386 return 387 } 388 err = p.expectCloseParens(n) 389 return 390 } 391 392 // expectConst expects a Const. 393 func (p *parser) expectConst() (f Const, err error) { 394 if p.cur() != tokenTrue && p.cur() != tokenFalse { 395 err = fmt.Errorf("expected Const, found %v", p.cur()) 396 return 397 } 398 f = Const(p.cur() == tokenTrue) 399 p.advance() 400 return 401 } 402 403 // parseConst parses a Const with optional outer parens. 404 func (p *parser) parseConst() (f Const, err error) { 405 n := p.skipOpenParens() 406 f, err = p.expectConst() 407 if err != nil { 408 return 409 } 410 err = p.expectCloseParens(n) 411 return 412 } 413 414 // expectQuantification expects a Forall or an Exists. 415 func (p *parser) expectQuantification(greedy bool) (f Form, err error) { 416 typ := p.cur() 417 if typ != tokenForall && typ != tokenExists { 418 err = fmt.Errorf(`expected "forall" or "exists", found %v`, p.cur()) 419 return 420 } 421 p.advance() 422 if p.cur().typ != itemIdentifier { 423 return nil, fmt.Errorf("expected identifier, found %v", p.cur()) 424 } 425 name := p.cur().val.(string) 426 p.advance() 427 err = p.expect(tokenColon) 428 if err != nil { 429 return 430 } 431 body, err := p.parseForm(greedy) 432 if err != nil { 433 return 434 } 435 if typ == tokenForall { 436 return Forall{name, body}, nil 437 } 438 return Exists{name, body}, nil 439 } 440 441 // expectOptionalTime optionally expects a "(from|until) int" clause for a says formula. 442 func (p *parser) expectOptionalTime(t token) (*int64, error) { 443 if p.cur() != t { 444 return nil, nil 445 } 446 p.advance() 447 i, err := p.parseInt() 448 if err != nil { 449 return nil, err 450 } 451 val := int64(i) 452 return &val, nil 453 } 454 455 // expectTermOperation expects a formula involving a term, i.e. a predicate, a 456 // says, or a speaksfor formula. If greedy is true, this will parse as much 457 // input as possible. Otherwise, it will take only as much input as needed to 458 // make a valid formula. 459 func (p *parser) expectTermOperation(greedy bool) (Form, error) { 460 // Identifier(Term...) 461 // Term [from Time] [until Time] says Form 462 // Term speaksfor Term 463 var t Term 464 var err error 465 switch p.cur().typ { 466 case itemStr, itemBytes, itemInt, itemKeyword: 467 t, err = p.expectTerm() 468 if err != nil { 469 return nil, err 470 } 471 case itemIdentifier: 472 name, hadParen, args, err := p.expectIdentifierOrNameAndArgs() 473 if err != nil { 474 return nil, err 475 } 476 if hadParen { 477 return Pred{name, args}, nil 478 } 479 t = TermVar(name) 480 } 481 switch p.cur() { 482 case tokenSpeaksfor: 483 p.advance() 484 d, err := p.parseTerm() 485 if err != nil { 486 return nil, err 487 } 488 return Speaksfor{t, d}, nil 489 case tokenFrom, tokenUntil, tokenSays: 490 from, err := p.expectOptionalTime(tokenFrom) 491 if err != nil { 492 return nil, err 493 } 494 until, err := p.expectOptionalTime(tokenUntil) 495 if err != nil { 496 return nil, err 497 } 498 if from == nil { 499 from, err = p.expectOptionalTime(tokenFrom) 500 if err != nil { 501 return nil, err 502 } 503 } 504 if p.cur() != tokenSays { 505 if from == nil && until == nil { 506 return nil, fmt.Errorf(`expected "from", "until" or "says", found %v`, p.cur()) 507 } else if until == nil { 508 return nil, fmt.Errorf(`expected "until" or "says", found %v`, p.cur()) 509 } else if from == nil { 510 return nil, fmt.Errorf(`expected "from" or "says", found %v`, p.cur()) 511 } 512 return nil, fmt.Errorf(`expected "says", found %v`, p.cur()) 513 } 514 p.advance() 515 msg, err := p.parseForm(greedy) 516 if err != nil { 517 return nil, err 518 } 519 return Says{t, from, until, msg}, nil 520 default: 521 return nil, fmt.Errorf(`expected "speaksfor", "from", "until", or "says", found %v`, p.cur()) 522 } 523 } 524 525 // The functions follow normal precedence rules, e.g. roughly: 526 // L = quant V : L | I 527 // I = O imp I | I 528 // O = A or A or A or ... or A | A 529 // A = H and H and H ... and H | H 530 // H = not N | ( L ) | P(x) | true | false | T says L | T speaksfor T 531 532 // parseFormAtHigh parses a Form, but stops at any binary Form operator. If 533 // greedy is true, this will parse as much input as possible. Otherwise, it will 534 // parse only as much input as needed to make a valid formula. 535 func (p *parser) parseFormAtHigh(greedy bool) (Form, error) { 536 switch p.cur() { 537 case tokenLP: 538 p.advance() 539 f, err := p.parseForm(true) 540 if err != nil { 541 return nil, err 542 } 543 err = p.expect(tokenRP) 544 if err != nil { 545 return nil, err 546 } 547 return f, nil 548 case tokenTrue, tokenFalse: 549 return p.expectConst() 550 case tokenNot: 551 p.advance() 552 f, err := p.parseFormAtHigh(greedy) 553 if err != nil { 554 return nil, err 555 } 556 return Not{f}, nil 557 case tokenForall, tokenExists: 558 return p.expectQuantification(greedy) 559 case tokenExt: 560 return p.expectTermOperation(greedy) 561 } 562 if isPrinToken(p.cur()) { 563 return p.expectTermOperation(greedy) 564 } 565 switch p.cur().typ { 566 case itemStr, itemBytes, itemInt, itemIdentifier: 567 return p.expectTermOperation(greedy) 568 } 569 return nil, fmt.Errorf("expected Form, found %v", p.cur()) 570 } 571 572 // parseFormAtAnd parses a Form, but stops when it reaches a binary Form 573 // operator of lower precedence than "and". 574 func (p *parser) parseFormAtAnd() (Form, error) { 575 f, err := p.parseFormAtHigh(true) 576 if err != nil { 577 return nil, err 578 } 579 if p.cur() != tokenAnd { 580 return f, nil 581 } 582 and, ok := f.(And) 583 if !ok { 584 and = And{Conjunct: []Form{f}} 585 } 586 for p.cur() == tokenAnd { 587 p.advance() 588 g, err := p.parseFormAtHigh(true) 589 if err != nil { 590 return nil, err 591 } 592 and.Conjunct = append(and.Conjunct, g) 593 } 594 return and, nil 595 } 596 597 // parseFormAtOr parses a Form, but stops when it reaches a binary Form operator 598 // of lower precedence than "or". 599 func (p *parser) parseFormAtOr() (Form, error) { 600 f, err := p.parseFormAtAnd() 601 if err != nil { 602 return nil, err 603 } 604 if p.cur() != tokenOr { 605 return f, nil 606 } 607 or, ok := f.(Or) 608 if !ok { 609 or = Or{Disjunct: []Form{f}} 610 } 611 for p.cur() == tokenOr { 612 p.advance() 613 g, err := p.parseFormAtAnd() 614 if err != nil { 615 return nil, err 616 } 617 or.Disjunct = append(or.Disjunct, g) 618 } 619 return or, nil 620 } 621 622 // parseForm parses a Form. If greedy=true, this consumes as much input as 623 // possible until either an error or EOF is encountered. Otherwise, this 624 // consumes only as much input as necessary to obtain a valid formula. For 625 // example, "(p says a and b ...)" and "p says (a and b ...) will always be 626 // parsed in their entirety, but given "p says a and b ... " and greedy=false, 627 // only "p says a" will be parsed. 628 func (p *parser) parseForm(greedy bool) (Form, error) { 629 if !greedy { 630 return p.parseFormAtHigh(false) 631 } 632 if p.cur() == tokenForall || p.cur() == tokenExists { 633 return p.expectQuantification(true) 634 } 635 f, err := p.parseFormAtOr() 636 if err != nil { 637 return nil, err 638 } 639 if p.cur() != tokenImplies { 640 return f, nil 641 } 642 p.advance() 643 g, err := p.parseForm(greedy) 644 if err != nil { 645 return nil, err 646 } 647 return Implies{f, g}, nil 648 } 649 650 func newParser(input reader) *parser { 651 lex := lex(input) 652 return &parser{lex: lex} 653 }