Commit 9e900a66 authored by Nadim Kobeissi's avatar Nadim Kobeissi 💾
Browse files

Use interfaces for values (contributed by Fabian Drinck)

parent f51ab2fc
Pipeline #807 failed with stages
in 42 seconds
......@@ -26,7 +26,7 @@ func attackerStateInit(active bool) {
func attackerStateAbsorbPhaseValues(valPrincipalState *PrincipalState) error {
attackerStateMutex.Lock()
for i, c := range valPrincipalState.Constants {
cc := &Value{Kind: typesEnumConstant, Constant: c}
cc := &Value{Kind: typesEnumConstant, Data: c}
if c.Qualifier != typesEnumPublic {
continue
}
......@@ -43,7 +43,7 @@ func attackerStateAbsorbPhaseValues(valPrincipalState *PrincipalState) error {
}
}
for i, c := range valPrincipalState.Constants {
cc := &Value{Kind: typesEnumConstant, Constant: c}
cc := &Value{Kind: typesEnumConstant, Data: c}
a := valPrincipalState.Assigned[i]
if len(valPrincipalState.Wire[i]) == 0 && !valPrincipalState.Constants[i].Leaked {
continue
......
......@@ -24,7 +24,7 @@ func constructKnowledgeMap(m Model, principals []string, principalIDs []principa
}
declaredAt := 0
currentPhase := 0
valKnowledgeMap.Constants = append(valKnowledgeMap.Constants, valueG.Constant)
valKnowledgeMap.Constants = append(valKnowledgeMap.Constants, valueG.Data.(*Constant))
valKnowledgeMap.Assigned = append(valKnowledgeMap.Assigned, valueG)
valKnowledgeMap.Creator = append(valKnowledgeMap.Creator, principalNamesMap["Attacker"])
valKnowledgeMap.KnownBy = append(valKnowledgeMap.KnownBy, []map[principalEnum]principalEnum{})
......@@ -36,7 +36,7 @@ func constructKnowledgeMap(m Model, principals []string, principalIDs []principa
map[principalEnum]principalEnum{principalID: principalID},
)
}
valKnowledgeMap.Constants = append(valKnowledgeMap.Constants, valueNil.Constant)
valKnowledgeMap.Constants = append(valKnowledgeMap.Constants, valueNil.Data.(*Constant))
valKnowledgeMap.Assigned = append(valKnowledgeMap.Assigned, valueNil)
valKnowledgeMap.Creator = append(valKnowledgeMap.Creator, principalNamesMap["Attacker"])
valKnowledgeMap.KnownBy = append(valKnowledgeMap.KnownBy, []map[principalEnum]principalEnum{})
......@@ -148,8 +148,8 @@ func constructKnowledgeMapRenderKnows(
}
valKnowledgeMap.Constants = append(valKnowledgeMap.Constants, c)
valKnowledgeMap.Assigned = append(valKnowledgeMap.Assigned, &Value{
Kind: typesEnumConstant,
Constant: c,
Kind: typesEnumConstant,
Data: c,
})
valKnowledgeMap.Creator = append(valKnowledgeMap.Creator, blck.Principal.ID)
valKnowledgeMap.KnownBy = append(valKnowledgeMap.KnownBy, []map[principalEnum]principalEnum{})
......@@ -193,8 +193,8 @@ func constructKnowledgeMapRenderGenerates(
}
valKnowledgeMap.Constants = append(valKnowledgeMap.Constants, c)
valKnowledgeMap.Assigned = append(valKnowledgeMap.Assigned, &Value{
Kind: typesEnumConstant,
Constant: c,
Kind: typesEnumConstant,
Data: c,
})
valKnowledgeMap.Creator = append(valKnowledgeMap.Creator, blck.Principal.ID)
valKnowledgeMap.KnownBy = append(valKnowledgeMap.KnownBy, []map[principalEnum]principalEnum{{}})
......@@ -213,7 +213,7 @@ func constructKnowledgeMapRenderAssignment(
}
switch expr.Assigned.Kind {
case typesEnumPrimitive:
err := sanityPrimitive(expr.Assigned.Primitive, expr.Constants)
err := sanityPrimitive(expr.Assigned.Data.(*Primitive), expr.Constants)
if err != nil {
return &KnowledgeMap{}, err
}
......@@ -261,7 +261,7 @@ func constructKnowledgeMapRenderAssignment(
a := valueDeepCopy(expr.Assigned)
switch a.Kind {
case typesEnumPrimitive:
a.Primitive.Output = i
a.Data.(*Primitive).Output = i
}
valKnowledgeMap.Constants = append(valKnowledgeMap.Constants, c)
valKnowledgeMap.Assigned = append(valKnowledgeMap.Assigned, &a)
......
......@@ -199,7 +199,7 @@ func coqAssignmentExpression(expression Expression, valKnowledgeMap *KnowledgeMa
expressions := []string{}
switch expression.Assigned.Kind {
case typesEnumEquation:
cre, err := coqResolveEquation(expression.Assigned.Equation, valKnowledgeMap)
cre, err := coqResolveEquation(expression.Assigned.Data.(*Equation), valKnowledgeMap)
if err != nil {
return []string{}, err
}
......@@ -208,19 +208,19 @@ func coqAssignmentExpression(expression Expression, valKnowledgeMap *KnowledgeMa
))
case typesEnumPrimitive:
primitiveStringName := ""
if primitiveIsCorePrim(expression.Assigned.Primitive.ID) {
prim, _ := primitiveCoreGet(expression.Assigned.Primitive.ID)
if primitiveIsCorePrim(expression.Assigned.Data.(*Primitive).ID) {
prim, _ := primitiveCoreGet(expression.Assigned.Data.(*Primitive).ID)
primitiveStringName = prim.Name
} else {
prim, _ := primitiveGet(expression.Assigned.Primitive.ID)
prim, _ := primitiveGet(expression.Assigned.Data.(*Primitive).ID)
primitiveStringName = prim.Name
}
switch expression.Assigned.Primitive.ID {
switch expression.Assigned.Data.(*Primitive).ID {
case primitiveEnumHASH, primitiveEnumPWHASH, primitiveEnumCONCAT:
exp := fmt.Sprintf(
"EXP assignment private (prim(%s%d ", primitiveStringName,
len(expression.Assigned.Primitive.Arguments))
for _, argument := range expression.Assigned.Primitive.Arguments {
len(expression.Assigned.Data.(*Primitive).Arguments))
for _, argument := range expression.Assigned.Data.(*Primitive).Arguments {
crv, err := coqResolveValue(argument, valKnowledgeMap)
if err != nil {
return []string{}, err
......@@ -235,7 +235,7 @@ func coqAssignmentExpression(expression Expression, valKnowledgeMap *KnowledgeMa
} else {
exp := fmt.Sprintf(
"EXP assignment private (prim(%s%d ", primitiveStringName, (i + 1))
for _, argument := range expression.Assigned.Primitive.Arguments {
for _, argument := range expression.Assigned.Data.(*Primitive).Arguments {
crv, err := coqResolveValue(argument, valKnowledgeMap)
if err != nil {
return []string{}, err
......@@ -246,7 +246,7 @@ func coqAssignmentExpression(expression Expression, valKnowledgeMap *KnowledgeMa
}
}
default:
crp, err := coqResolvePrimitive(expression.Assigned.Primitive, valKnowledgeMap)
crp, err := coqResolvePrimitive(expression.Assigned.Data.(*Primitive), valKnowledgeMap)
if err != nil {
return nil, err
}
......@@ -267,24 +267,24 @@ func coqGuard(guard bool) string {
func coqResolveConstant(c *Constant, valKnowledgeMap *KnowledgeMap) (string, error) {
a, _ := valueResolveValueInternalValuesFromKnowledgeMap(&Value{
Kind: typesEnumConstant,
Constant: c,
Kind: typesEnumConstant,
Data: c,
}, valKnowledgeMap)
return coqPrintValue(a)
}
func coqResolvePrimitive(p *Primitive, valKnowledgeMap *KnowledgeMap) (string, error) {
a, _ := valueResolveValueInternalValuesFromKnowledgeMap(&Value{
Kind: typesEnumPrimitive,
Primitive: p,
Kind: typesEnumPrimitive,
Data: p,
}, valKnowledgeMap)
return coqPrintValue(a)
}
func coqResolveEquation(e *Equation, valKnowledgeMap *KnowledgeMap) (string, error) {
a, _ := valueResolveValueInternalValuesFromKnowledgeMap(&Value{
Kind: typesEnumEquation,
Equation: e,
Kind: typesEnumEquation,
Data: e,
}, valKnowledgeMap)
return coqPrintValue(a)
}
......@@ -292,11 +292,11 @@ func coqResolveEquation(e *Equation, valKnowledgeMap *KnowledgeMap) (string, err
func coqResolveValue(v *Value, valKnowledgeMap *KnowledgeMap) (string, error) {
switch v.Kind {
case typesEnumConstant:
return coqResolveConstant(v.Constant, valKnowledgeMap)
return coqResolveConstant(v.Data.(*Constant), valKnowledgeMap)
case typesEnumPrimitive:
return coqResolvePrimitive(v.Primitive, valKnowledgeMap)
return coqResolvePrimitive(v.Data.(*Primitive), valKnowledgeMap)
case typesEnumEquation:
return coqResolveEquation(v.Equation, valKnowledgeMap)
return coqResolveEquation(v.Data.(*Equation), valKnowledgeMap)
}
return "", fmt.Errorf("invalid value kind")
}
......@@ -304,11 +304,11 @@ func coqResolveValue(v *Value, valKnowledgeMap *KnowledgeMap) (string, error) {
func coqPrintValue(a *Value) (string, error) {
switch a.Kind {
case typesEnumConstant:
return coqPrintConstant(a.Constant)
return coqPrintConstant(a.Data.(*Constant))
case typesEnumPrimitive:
return coqPrintPrimitive(a.Primitive)
return coqPrintPrimitive(a.Data.(*Primitive))
case typesEnumEquation:
return coqPrintEquation(a.Equation)
return coqPrintEquation(a.Data.(*Equation))
}
return "", fmt.Errorf("invalid value kind")
}
......
......@@ -204,18 +204,18 @@ func infoOutputText(revealed *Value) string {
return outputText
case typesEnumPrimitive:
oneOutput := false
if primitiveIsCorePrim(revealed.Primitive.ID) {
prim, _ := primitiveCoreGet(revealed.Primitive.ID)
if primitiveIsCorePrim(revealed.Data.(*Primitive).ID) {
prim, _ := primitiveCoreGet(revealed.Data.(*Primitive).ID)
oneOutput = len(prim.Output) == 1 && prim.Output[0] == 1
} else {
prim, _ := primitiveGet(revealed.Primitive.ID)
prim, _ := primitiveGet(revealed.Data.(*Primitive).ID)
oneOutput = len(prim.Output) == 1 && prim.Output[0] == 1
}
if oneOutput {
return fmt.Sprintf("Output of %s", outputText)
}
prefix := fmt.Sprintf("%s output",
strings.Title(infoLiteralNumber(revealed.Primitive.Output)),
strings.Title(infoLiteralNumber(revealed.Data.(*Primitive).Output)),
)
return fmt.Sprintf("%s of %s", prefix, outputText)
case typesEnumEquation:
......
......@@ -36,11 +36,11 @@ func injectValueRules(
) bool {
switch k.Kind {
case typesEnumConstant:
return injectConstantRules(k.Constant, arg, p)
return injectConstantRules(k.Data.(*Constant), arg, p)
case typesEnumPrimitive:
return injectPrimitiveRules(k.Primitive, arg, p, stage)
return injectPrimitiveRules(k.Data.(*Primitive), arg, p, stage)
case typesEnumEquation:
return injectEquationRules(k.Equation, arg, p)
return injectEquationRules(k.Data.(*Equation), arg, p)
}
return true
}
......@@ -49,7 +49,7 @@ func injectConstantRules(c *Constant, arg int, p *Primitive) bool {
switch {
case p.Arguments[arg].Kind != typesEnumConstant:
return false
case c.ID == valueG.Constant.ID:
case c.ID == valueG.Data.(*Constant).ID:
return false
}
return true
......@@ -62,14 +62,14 @@ func injectPrimitiveRules(k *Primitive, arg int, p *Primitive, stage int) bool {
case injectPrimitiveStageRestricted(k, stage):
return false
}
return injectSkeletonNotDeeper(k, p.Arguments[arg].Primitive)
return injectSkeletonNotDeeper(k, p.Arguments[arg].Data.(*Primitive))
}
func injectEquationRules(e *Equation, arg int, p *Primitive) bool {
switch {
case p.Arguments[arg].Kind != typesEnumEquation:
return false
case len(e.Values) != len(p.Arguments[arg].Equation.Values):
case len(e.Values) != len(p.Arguments[arg].Data.(*Equation).Values):
return false
}
return true
......@@ -108,17 +108,17 @@ func injectPrimitiveSkeleton(p *Primitive, depth int) (*Primitive, int) {
case typesEnumConstant:
skeleton.Arguments[i] = valueNil
case typesEnumPrimitive:
pp, dd := injectPrimitiveSkeleton(a.Primitive, depth)
pp, dd := injectPrimitiveSkeleton(a.Data.(*Primitive), depth)
if dd > depth {
depth = dd
}
aa := &Value{
Kind: typesEnumPrimitive,
Primitive: pp,
Kind: typesEnumPrimitive,
Data: pp,
}
skeleton.Arguments[i] = aa
case typesEnumEquation:
switch len(a.Equation.Values) {
switch len(a.Data.(*Equation).Values) {
case 1:
skeleton.Arguments[i] = valueG
default:
......@@ -143,8 +143,8 @@ func injectMatchSkeletons(p *Primitive, skeleton *Primitive) bool {
return false
}
ps, _ := injectPrimitiveSkeleton(p, 0)
pv := Value{Kind: typesEnumPrimitive, Primitive: ps}
sv := Value{Kind: typesEnumPrimitive, Primitive: skeleton}
pv := Value{Kind: typesEnumPrimitive, Data: ps}
sv := Value{Kind: typesEnumPrimitive, Data: skeleton}
return valueEquivalentValues(&pv, &sv, true)
}
......@@ -155,7 +155,7 @@ SkeletonSearch:
for _, a := range valAttackerState.Known {
switch a.Kind {
case typesEnumPrimitive:
if injectMatchSkeletons(a.Primitive, skeleton) {
if injectMatchSkeletons(a.Data.(*Primitive), skeleton) {
matchingSkeleton = true
break SkeletonSearch
}
......@@ -163,8 +163,8 @@ SkeletonSearch:
}
if !matchingSkeleton {
known := &Value{
Kind: typesEnumPrimitive,
Primitive: skeleton,
Kind: typesEnumPrimitive,
Data: skeleton,
}
if attackerStatePutWrite(known, valPrincipalState) {
InfoMessage(fmt.Sprintf(
......@@ -176,7 +176,7 @@ SkeletonSearch:
for _, a := range p.Arguments {
switch a.Kind {
case typesEnumPrimitive:
injectMissingSkeletons(a.Primitive, valPrincipalState, valAttackerState)
injectMissingSkeletons(a.Data.(*Primitive), valPrincipalState, valAttackerState)
}
}
}
......@@ -194,7 +194,7 @@ func injectPrimitive(
for _, k := range valAttackerState.Known {
switch k.Kind {
case typesEnumConstant:
k, _ = valueResolveConstant(k.Constant, valPrincipalState)
k, _ = valueResolveConstant(k.Data.(*Constant), valPrincipalState)
}
if !injectValueRules(k, arg, p, stage) {
continue
......@@ -233,7 +233,7 @@ func injectPrimitiveRecursively(
injectDepth int, stage int,
) ([][]*Value, [][]*Value) {
kp := inject(
k.Primitive, injectDepth+1,
k.Data.(*Primitive), injectDepth+1,
valPrincipalState, valAttackerState, stage,
)
for _, kkp := range kp {
......@@ -272,7 +272,7 @@ func injectLoop1(p *Primitive, kinjectants [][]*Value) []*Value {
for i := range kinjectants[0] {
aa := &Value{
Kind: typesEnumPrimitive,
Primitive: &Primitive{
Data: &Primitive{
ID: p.ID,
Arguments: []*Value{
kinjectants[0][i],
......@@ -292,7 +292,7 @@ func injectLoop2(p *Primitive, kinjectants [][]*Value) []*Value {
for ii := range kinjectants[1] {
aa := &Value{
Kind: typesEnumPrimitive,
Primitive: &Primitive{
Data: &Primitive{
ID: p.ID,
Arguments: []*Value{
kinjectants[0][i],
......@@ -315,7 +315,7 @@ func injectLoop3(p *Primitive, kinjectants [][]*Value) []*Value {
for iii := range kinjectants[2] {
aa := &Value{
Kind: typesEnumPrimitive,
Primitive: &Primitive{
Data: &Primitive{
ID: p.ID,
Arguments: []*Value{
kinjectants[0][i],
......@@ -341,7 +341,7 @@ func injectLoop4(p *Primitive, kinjectants [][]*Value) []*Value {
for iiii := range kinjectants[3] {
aa := &Value{
Kind: typesEnumPrimitive,
Primitive: &Primitive{
Data: &Primitive{
ID: p.ID,
Arguments: []*Value{
kinjectants[0][i],
......@@ -370,7 +370,7 @@ func injectLoop5(p *Primitive, kinjectants [][]*Value) []*Value {
for iiiii := range kinjectants[4] {
aa := &Value{
Kind: typesEnumPrimitive,
Primitive: &Primitive{
Data: &Primitive{
ID: p.ID,
Arguments: []*Value{
kinjectants[0][i],
......
......@@ -507,53 +507,53 @@ var g = &grammar{
},
{
name: "Expression",
pos: position{line: 177, col: 1, offset: 4287},
pos: position{line: 177, col: 1, offset: 4295},
expr: &actionExpr{
pos: position{line: 177, col: 15, offset: 4301},
pos: position{line: 177, col: 15, offset: 4309},
run: (*parser).callonExpression1,
expr: &seqExpr{
pos: position{line: 177, col: 15, offset: 4301},
pos: position{line: 177, col: 15, offset: 4309},
exprs: []interface{}{
&zeroOrMoreExpr{
pos: position{line: 177, col: 15, offset: 4301},
pos: position{line: 177, col: 15, offset: 4309},
expr: &ruleRefExpr{
pos: position{line: 177, col: 15, offset: 4301},
pos: position{line: 177, col: 15, offset: 4309},
name: "Comment",
},
},
&labeledExpr{
pos: position{line: 177, col: 24, offset: 4310},
pos: position{line: 177, col: 24, offset: 4318},
label: "Expression",
expr: &choiceExpr{
pos: position{line: 177, col: 36, offset: 4322},
pos: position{line: 177, col: 36, offset: 4330},
alternatives: []interface{}{
&ruleRefExpr{
pos: position{line: 177, col: 36, offset: 4322},
pos: position{line: 177, col: 36, offset: 4330},
name: "Knows",
},
&ruleRefExpr{
pos: position{line: 177, col: 42, offset: 4328},
pos: position{line: 177, col: 42, offset: 4336},
name: "Generates",
},
&ruleRefExpr{
pos: position{line: 177, col: 52, offset: 4338},
pos: position{line: 177, col: 52, offset: 4346},
name: "Leaks",
},
&ruleRefExpr{
pos: position{line: 177, col: 58, offset: 4344},
pos: position{line: 177, col: 58, offset: 4352},
name: "Assignment",
},
},
},
},
&ruleRefExpr{
pos: position{line: 177, col: 70, offset: 4356},
pos: position{line: 177, col: 70, offset: 4364},
name: "_",
},
&zeroOrMoreExpr{
pos: position{line: 177, col: 72, offset: 4358},
pos: position{line: 177, col: 72, offset: 4366},
expr: &ruleRefExpr{
pos: position{line: 177, col: 72, offset: 4358},
pos: position{line: 177, col: 72, offset: 4366},
name: "Comment",
},
},
......@@ -563,44 +563,44 @@ var g = &grammar{
},
{
name: "Knows",
pos: position{line: 181, col: 1, offset: 4396},
pos: position{line: 181, col: 1, offset: 4404},
expr: &actionExpr{
pos: position{line: 181, col: 10, offset: 4405},
pos: position{line: 181, col: 10, offset: 4413},
run: (*parser).callonKnows1,
expr: &seqExpr{
pos: position{line: 181, col: 10, offset: 4405},
pos: position{line: 181, col: 10, offset: 4413},
exprs: []interface{}{
&litMatcher{
pos: position{line: 181, col: 10, offset: 4405},
pos: position{line: 181, col: 10, offset: 4413},
val: "knows",
ignoreCase: false,
},
&ruleRefExpr{
pos: position{line: 181, col: 18, offset: 4413},
pos: position{line: 181, col: 18, offset: 4421},
name: "_",
},
&labeledExpr{
pos: position{line: 181, col: 20, offset: 4415},
pos: position{line: 181, col: 20, offset: 4423},
label: "Qualifier",
expr: &zeroOrOneExpr{
pos: position{line: 181, col: 30, offset: 4425},
pos: position{line: 181, col: 30, offset: 4433},
expr: &ruleRefExpr{
pos: position{line: 181, col: 30, offset: 4425},
pos: position{line: 181, col: 30, offset: 4433},
name: "Qualifier",
},
},
},
&ruleRefExpr{
pos: position{line: 181, col: 41, offset: 4436},
pos: position{line: 181, col: 41, offset: 4444},
name: "_",
},
&labeledExpr{
pos: position{line: 181, col: 43, offset: 4438},
pos: position{line: 181, col: 43, offset: 4446},
label: "Constants",
expr: &zeroOrOneExpr{
pos: position{line: 181, col: 53, offset: 4448},
pos: position{line: 181, col: 53, offset: 4456},
expr: &ruleRefExpr{
pos: position{line: 181, col: 53, offset: 4448},
pos: position{line: 181, col: 53, offset: 4456},
name: "Constants",
},
},
......@@ -611,29 +611,29 @@ var g = &grammar{
},
{
name: "Generates",
pos: position{line: 195, col: 1, offset: 4800},
pos: position{line: 195, col: 1, offset: 4808},
expr: &actionExpr{
pos: position{line: 195, col: 14, offset: 4813},
pos: position{line: 195, col: 14, offset: 4821},
run: (*parser).callonGenerates1,
expr: &seqExpr{
pos: position{line: 195, col: 14, offset: 4813},
pos: position{line: 195, col: 14, offset: 4821},
exprs: []interface{}{
&litMatcher{
pos: position{line: 195, col: 14, offset: 4813},
pos: position{line: 195, col: 14, offset: 4821},
val: "generates",
ignoreCase: false,
},
&ruleRefExpr{
pos: position{line: 195, col: 26, offset: 4825},
pos: position{line: 195, col: 26, offset: 4833},
name: "_",
},
&labeledExpr{
pos: position{line: 195, col: 28, offset: 4827},
pos: position{line: 195, col: 28, offset: 4835},
label: "Constants",
expr: &zeroOrOneExpr{
pos: position{line: 195, col: 38, offset: 4837},
pos: position{line: 195, col: 38, offset: 4845},
expr: &ruleRefExpr{
pos: position{line: 195, col: 38, offset: 4837},
pos: position{line: 195, col: 38, offset: 4845},
name: "Constants",
},
},
......@@ -644,29 +644,29 @@ var g = &grammar{
},
{
name: "Leaks",
pos: position{line: 206, col: 1, offset: 5082},
pos: position{line: 206, col: 1, offset: 5090},
expr: &actionExpr{
pos: position{line: 206, col: 10, offset: 5091},
pos: position{line: 206, col: 10, offset: 5099},
run: (*parser).callonLeaks1,
expr: &seqExpr{
pos: position{line: 206, col: 10, offset: 5091},
pos: position{line: 206, col: 10, offset: 5099},
exprs: []interface{}{
&litMatcher{
pos: position{line: 206, col: 10, offset: 5091},
pos: position{line: 206, col: 10, offset: 5099},
val: "leaks",
ignoreCase: false,
},
&ruleRefExpr{
pos: position{line: 206, col: 18, offset: 5099},
pos: position{line: 206, col: 18, offset: 5107},
name: "_",
},
&labeledExpr{
pos: position{line: 206, col: 20, offset: 5101},
pos: position{line: 206, col: 20, offset: 5109},
label: "Constants",
expr: &zeroOrOneExpr{
pos: position{line: 206, col: 30, offset: 5111},
pos: position{line: 206, col: 30, offset: 5119},
expr: &ruleRefExpr{
pos: position{line: 206, col: 30, offset: 5111},
pos: position{line: 206, col: 30, offset: 5119},
name: "Constants",
},
},
......@@ -677,44 +677,44 @@ var g = &grammar{
},
{
name: "Assignment",
pos: position{line: 217, col: 1, offset: 5348},
pos: position{line: 217, col: 1, offset: 5356},
expr: &actionExpr{
pos: position{line: 217, col: 15, offset: 5362},
pos: position{line: 217, col: 15, offset: 5370},
run: (*parser).callonAssignment1,
expr: &seqExpr{
pos: position{line: 217, col: 15, offset: 5362},
pos: position{line: 217, col: 15, offset: 5370},
exprs: []interface{}{
&labeledExpr{
pos: position{line: 217, col: 15, offset: 5362},
pos: position{line: 217, col: 15, offset: 5370},
label: "Left",
expr: &zeroOrOneExpr{
pos: position{line: 217, col: 20, offset: 5367},
pos: position{line: 217, col: 20, offset: 5375},
expr: &ruleRefExpr{
pos: position{line: 217, col: 20, offset: 5367},
pos: position{line: 217, col: 20, offset: 5375},