我需要解析一个我没有设计的简单语言,因此我无法改变语言。我需要在C#中使用结果,因此我一直在使用TinyPG,因为它非常易于使用,并且不需要外部库来运行解析器。
事情进展顺利,直到我用语言遇到这个结构。 (这是一个简化版本,但确实显示了问题):
EOF -> @"^\s*$";
[Skip] WHITESPACE -> @"\s+";
LIST -> "LIST";
END -> "END";
IDENTIFIER -> @"[a-zA-Z_][a-zA-Z0-9_]*";
Expr -> LIST IDENTIFIER+ END;
Start -> (Expr)+ EOF;
生成的解析器无法解析此:
LIST foo BAR Baz END
因为贪婪地将END作为IDENTIFIER
,而不是END
关键字。
所以,这是我的问题:
这个语法对LL(1)解析是不明确的还是错误的?或者这是TinyPG中的错误?
有没有办法重新设计语法,以便TinyPG
能够正确解析示例行?
对于在C#
中输出代码并且不需要其他库的简单解析器,是否还有其他建议?我查看了LLLPG
和ANTLR4
,但发现它们比TinyPG
麻烦得多。
答案 0 :(得分:0)
你可能是同一个人,因为这个问题看起来很相似,就像我在GitHub上回答的一样,但是对于谷歌这个问题的人来说也是如此。
这是Simple-CIL-compiler项目的一个例子, 标识符必须捕获除列出的单词之外的单个单词,这意味着您必须将异常标记包含在标识符中
IDENTIFIER-> @"[a-zA-Z_][a-zA-Z0-9_]*(?<!(^)(end|else|do|while|for|true|false|return|to|incby|global|or|and|not|write|readnum|readstr|call))(?!\w)";
希望有所帮助。