Parsing 简洁语法,用于分析交替字符的字符串,如;“亚贝巴”;或;“爸爸”;

Parsing 简洁语法,用于分析交替字符的字符串,如;“亚贝巴”;或;“爸爸”;,parsing,go,Parsing,Go,我正在制作一个玩具,只是为了学习语言。我添加了一个包含语法的测试用例,包括以下用例: Valid: a, ab, aba, ababababababa, ababababab b, ba, bab, babababababab, bababababa Invalid: abb, baa a后面总是跟着b,反之亦然 现在,我的解析器中的语法如下所示(为了简洁起见,我省略了周围的代码): 在哪里 我想这不是描述这种语法的最简洁的方式。如何使它更紧凑 相关的: 编辑: BNF可以用我的语法

我正在制作一个玩具,只是为了学习语言。我添加了一个包含语法的测试用例,包括以下用例:

Valid:
a, ab, aba, ababababababa, ababababab
b, ba, bab, babababababab, bababababa

Invalid:
abb, baa
a
后面总是跟着
b
,反之亦然

现在,我的解析器中的语法如下所示(为了简洁起见,我省略了周围的代码):

在哪里

我想这不是描述这种语法的最简洁的方式。如何使它更紧凑

相关的:


编辑:

BNF可以用我的语法写成:

    "expr": Or(Ref("A"), Ref("B")),
    "A":    Or(And(a, Ref("B")), a),
    "B":    Or(And(b, Ref("A")), b)

您拥有的BNF语法如下:

expr ::= A | B
A ::= "a" B | "a"
B ::= "b" A | "b"
我想这可以用你的语法来解释:

"expr": Or(Ref("A"), Ref("B")),
"A": And(
    a,
    Optional(Ref("B"))),
"B": And(
    b,
    Optional(Ref("A")))

请注意,在非终端(
Ref(x)
)之前检查终端(
“a”
“b”
)非常重要,否则将得到一个无限循环。它总是试图看看它是否可以将另一个
A
B
匹配到字符串的末尾,然后再匹配另一个,再匹配另一个,从而导致一个永无止境的递归。

@DenysSéguret:不确定。这并不是关于golang的,而是关于解析器和语法的。@DenysSéguret如果是关于这个主题的,就让它留在这里吧。如果它也在这里的主题上,那么移动它是没有意义的。@DenysSéguret在这个问题中没有代码可以查看。作为正则表达式,这种语言是
a?(ba)*b?
,但我认为这无助于用RDP解析它。(是的,它也是
b?(ab)*a?
奇怪的是,这两个正则表达式是等价的。)如果我删除额外的`|“a”`案例,它将如何终止?(为什么`|“a”`不呈现为代码片段?@Filip:在注释中,'只有在后面没有空格时才特别。@FilipHaglund:你的回答在我的语法和BNF中都是有效的,我编辑了我的文章,将你的BNF翻译成我的语法
expr ::= A | B
A ::= "a" B | "a"
B ::= "b" A | "b"
"expr": Or(Ref("A"), Ref("B")),
"A": And(
    a,
    Optional(Ref("B"))),
"B": And(
    b,
    Optional(Ref("A")))