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  }