2

我需要解析一种不是我设计的简单语言,所以我无法更改语言。我需要 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关键字。

所以,这是我的问题:

  1. 对于 LL(1) 解析,此语法是否模棱两可或错误?或者这是 TinyPG 中的错误?

  2. 有什么方法可以重新设计语法以TinyPG正确解析示例行?

  3. C#对于输出代码且不需要额外库的简单解析器,还有其他建议吗?我看过LLLPGand ANTLR4,但发现它们比TinyPG.

4

1 回答 1

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)";

希望有帮助。

(链接到原帖)

于 2016-08-16T15:39:15.027 回答