VisitLiteralOrFml visits a parse tree produced by literalOrFml
(ctx *gen.LiteralOrFmlContext)
| 396 | |
| 397 | // VisitLiteralOrFml visits a parse tree produced by literalOrFml |
| 398 | func (p Parser) VisitLiteralOrFml(ctx *gen.LiteralOrFmlContext) any { |
| 399 | term := p.Visit(ctx.Term(0)).(ast.Term) |
| 400 | atom, ok := term.(ast.Atom) |
| 401 | |
| 402 | // Handle negation |
| 403 | if ctx.BANG() != nil { |
| 404 | if !ok { |
| 405 | p.errors.Add(fmt.Sprintf("not a literal or fml: %v", ctx.Term(0).GetText()), ctx.Term(0).GetStart().GetLine(), ctx.Term(0).GetStart().GetColumn()) |
| 406 | } |
| 407 | return ast.NegAtom{atom} |
| 408 | } |
| 409 | |
| 410 | // Check for temporal operator |
| 411 | var tempOp *ast.TemporalOperator |
| 412 | if tempOpCtx := ctx.TemporalOperator(); tempOpCtx != nil { |
| 413 | tempOp = p.Visit(tempOpCtx).(*ast.TemporalOperator) |
| 414 | } |
| 415 | |
| 416 | // Check for temporal annotation |
| 417 | var tempAnnot *ast.Interval |
| 418 | if tempAnnotCtx := ctx.TemporalAnnotation(); tempAnnotCtx != nil { |
| 419 | tempAnnot = p.Visit(tempAnnotCtx).(*ast.Interval) |
| 420 | } |
| 421 | |
| 422 | // If no comparison operator, it's a simple literal (possibly with temporal annotations) |
| 423 | if ctx.EQ() == nil && ctx.BANGEQ() == nil && ctx.LESS() == nil && ctx.LESSEQ() == nil && ctx.GREATER() == nil && ctx.GREATEREQ() == nil { |
| 424 | if ok { |
| 425 | // If there's a temporal operator or annotation, wrap in TemporalLiteral |
| 426 | if tempOp != nil || tempAnnot != nil { |
| 427 | return ast.TemporalLiteral{ |
| 428 | Literal: atom, |
| 429 | Operator: tempOp, |
| 430 | Interval: tempAnnot, |
| 431 | } |
| 432 | } |
| 433 | return atom |
| 434 | } |
| 435 | p.errors.Add(fmt.Sprintf("parse error: %v", ctx.GetText()), ctx.GetStart().GetLine(), ctx.GetStart().GetColumn()) |
| 436 | return ast.NewAtom("br0ken") |
| 437 | } |
| 438 | |
| 439 | // Handle comparison operators |
| 440 | left := p.Visit(ctx.Term(0)).(ast.Term) |
| 441 | leftBase, ok := left.(ast.BaseTerm) |
| 442 | if !ok { |
| 443 | p.errors.Add(fmt.Sprintf("not a base term: %v", ctx.Term(0).GetText()), ctx.Term(0).GetStart().GetLine(), ctx.Term(0).GetStart().GetColumn()) |
| 444 | } |
| 445 | right := p.Visit(ctx.Term(1)).(ast.Term) |
| 446 | rightBase, ok := right.(ast.BaseTerm) |
| 447 | if !ok { |
| 448 | p.errors.Add(fmt.Sprintf("not a base term: %v", ctx.Term(1).GetText()), ctx.Term(1).GetStart().GetLine(), ctx.Term(1).GetStart().GetColumn()) |
| 449 | } |
| 450 | |
| 451 | if ctx.EQ() != nil { |
| 452 | return ast.Eq{leftBase, rightBase} |
| 453 | } |
| 454 | if ctx.BANGEQ() != nil { |
| 455 | return ast.Ineq{leftBase, rightBase} |
no test coverage detected