github.com/cloudflare/circl@v1.5.0/abe/cpabe/tkn20/internal/dsl/parser.go (about) 1 package dsl 2 3 import ( 4 "fmt" 5 ) 6 7 type Parser struct { 8 tokens []Token 9 curr int 10 wires map[attr]attrValue 11 gates []gate 12 negative bool 13 } 14 15 func newParser(tokens []Token) Parser { 16 return Parser{ 17 tokens: tokens, 18 curr: 0, 19 wires: make(map[attr]attrValue), 20 gates: make([]gate, 0), 21 negative: false, 22 } 23 } 24 25 func (p *Parser) parse() (Ast, error) { 26 _, err := p.expression() 27 if err != nil { 28 return Ast{}, err 29 } 30 return Ast{ 31 wires: p.wires, 32 gates: p.gates, 33 }, nil 34 } 35 36 func (p *Parser) expression() (Expr, error) { 37 return p.or() 38 } 39 40 func (p *Parser) or() (Expr, error) { 41 expr, err := p.and() 42 if err != nil { 43 return nil, err 44 } 45 46 for p.tokens[p.curr].Type == Or { 47 orToken := p.tokens[p.curr] 48 p.curr++ 49 right, err := p.and() 50 if err != nil { 51 return nil, err 52 } 53 in1 := extractAttr(expr) 54 in2 := extractAttr(right) 55 newGate := gate{ 56 op: Or, 57 in1: in1, 58 in2: in2, 59 out: attr{ 60 key: "", 61 id: -(len(p.gates) + 1), 62 }, 63 } 64 if p.negative { 65 newGate.op = And 66 } 67 p.gates = append(p.gates, newGate) 68 69 expr = Binary{ 70 Left: expr, 71 Operator: orToken, 72 Right: right, 73 Output: p.gates[len(p.gates)-1].out, 74 } 75 } 76 return expr, nil 77 } 78 79 func (p *Parser) and() (Expr, error) { 80 expr, err := p.not() 81 if err != nil { 82 return nil, err 83 } 84 85 for p.tokens[p.curr].Type == And { 86 andToken := p.tokens[p.curr] 87 p.curr++ 88 right, err := p.not() 89 if err != nil { 90 return nil, err 91 } 92 in1 := extractAttr(expr) 93 in2 := extractAttr(right) 94 newGate := gate{ 95 op: And, 96 in1: in1, 97 in2: in2, 98 out: attr{ 99 key: "", 100 id: -(len(p.gates) + 1), 101 }, 102 } 103 if p.negative { 104 newGate.op = Or 105 } 106 p.gates = append(p.gates, newGate) 107 108 expr = Binary{ 109 Left: expr, 110 Operator: andToken, 111 Right: right, 112 Output: p.gates[len(p.gates)-1].out, 113 } 114 } 115 return expr, nil 116 } 117 118 func (p *Parser) not() (Expr, error) { 119 if p.tokens[p.curr].Type == Not { 120 p.curr++ 121 currWires := make(map[attr]int) 122 for wire := range p.wires { 123 currWires[wire] = 1 124 } 125 p.negative = !p.negative 126 right, err := p.not() 127 p.negative = !p.negative 128 if err != nil { 129 return nil, err 130 } 131 for k, v := range p.wires { 132 _, ok := currWires[k] 133 if !ok { 134 v.positive = !v.positive 135 p.wires[k] = v 136 } 137 } 138 return Unary{ 139 Operator: p.tokens[p.curr-1], 140 Right: right, 141 }, nil 142 } 143 144 return p.primary() 145 } 146 147 func (p *Parser) primary() (Expr, error) { 148 if p.tokens[p.curr].Type == LeftParen { 149 p.curr++ 150 expr, err := p.expression() 151 if err != nil { 152 return nil, err 153 } 154 if !(p.tokens[p.curr].Type == RightParen) { 155 return nil, fmt.Errorf("expected ')' after expression") 156 } 157 p.curr++ 158 return Grouping{ 159 Expr: expr, 160 }, nil 161 } 162 163 if p.tokens[p.curr].Type == Identifier { 164 if p.tokens[p.curr+1].Type == Colon { 165 if p.tokens[p.curr+2].Type == Identifier { 166 nextToken := p.tokens[p.curr+3].Type 167 if (nextToken == Identifier) || 168 (nextToken == Colon) || 169 (nextToken == LeftParen) || 170 (nextToken == Not) { 171 return nil, fmt.Errorf( 172 "unexpected token %s, expected logical operator \"and\" or \"or\"", 173 p.tokens[p.curr+3].Lexeme) 174 } 175 key := p.tokens[p.curr] 176 value := p.tokens[p.curr+2] 177 currAttr := attr{ 178 key: key.Lexeme, 179 id: len(p.wires), 180 } 181 attrVal := attrValue{ 182 value: value.Lexeme, 183 positive: true, 184 } 185 p.wires[currAttr] = attrVal 186 p.curr += 3 187 return Literal{ 188 Key: currAttr, 189 Value: attrVal, 190 }, nil 191 } 192 } 193 } 194 return nil, fmt.Errorf("expected parentheses or literal") 195 } 196 197 func extractAttr(expr Expr) attr { 198 i := Interpreter{} 199 expr.Accept(&i) 200 return i.Literal.Key 201 }