Skip to content

Farkle fails to parse input when grammar contains certain possibly empty non-terminal #301

@bavibi

Description

@bavibi

Describe the bug

Grammar can contain optional non-terminal, but Farkle will treat it as required and fail to match empty string.

To Reproduce

Run following F# script:

#r "nuget: Farkle, 6.5.1"
open Farkle
open Farkle.Builder

let A = literal "a"
let B = literal "b"
let C = literal "c"
let D = literal "d"
let E = literal "e"

let opt_D = "opt_D" ||= [
    empty =% "empty D"
    !% D =% "D"
]

let opt_CD = "opt_CD" ||= [
    !% C =% "C"
    !@ opt_D |> asIs
]

let opt_B = "opt_B" ||= [
    empty =% "empty B"
    !% B =% "B"
]

let root = "root" ||= [
    !% A .>>. opt_B .>>. opt_CD .>> E => (fun x y -> (x, y))
]

let parser = RuntimeFarkle.build root

let showResult (input: string) =
    printfn $"Result for '{input}'"
    match RuntimeFarkle.parseString parser input with
    | Ok b -> printfn $"Success: got {b}"
    | Error err -> printfn $"Error: {err}"
    printfn ""

showResult "ae"
showResult "abe"
showResult "ace"
showResult "ade"
showResult "abce"
showResult "abde"

The script outputs:

Result for 'ae'
Error: (1, 2) Found e while expecting one of the following tokens: b, c, d.

Result for 'abe'
Error: (1, 3) Found e while expecting one of the following tokens: c, d.

Result for 'ace'
Success: got (empty B, C)

Result for 'ade'
Success: got (empty B, D)

Result for 'abce'
Success: got (B, C)

Result for 'abde'
Success: got (B, D)

Expected behavior

Farkle should successfully parse strings 'ae' and 'abe'.

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions