Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Parsing 语法不完全的句法分析_Parsing_Antlr_Grammar_Parser Generator_Antlrworks - Fatal编程技术网

Parsing 语法不完全的句法分析

Parsing 语法不完全的句法分析,parsing,antlr,grammar,parser-generator,antlrworks,Parsing,Antlr,Grammar,Parser Generator,Antlrworks,如何使用不完整的语法,有什么共同的解决方案吗?在我的例子中,我只想检测Delphi(Pascal)文件中的方法,这意味着过程和函数。以下第一次尝试正在运行 methods : ( procedure | function | . )+ ; 但这是一个解决方案吗?有没有更好的解决办法?是否可以使用操作停止解析(例如,在检测到实现之后)。使用预处理器有意义吗?如果是,怎么做?如果你只是在寻找名字,那么简单如下: 语法PascalFuncProc; 作语法分析 :(程

如何使用不完整的语法,有什么共同的解决方案吗?在我的例子中,我只想检测Delphi(Pascal)文件中的方法,这意味着
过程
函数
。以下第一次尝试正在运行

    methods
      : ( procedure | function | . )+
      ;

但这是一个解决方案吗?有没有更好的解决办法?是否可以使用操作停止解析(例如,在检测到
实现之后)。使用预处理器有意义吗?如果是,怎么做?

如果你只是在寻找名字,那么简单如下:

语法PascalFuncProc; 作语法分析 :(程序|功能)*EOF ; 程序 :“过程”空间标识符 ; 作用 :“函数”空间标识符 ; 忽略 :(strlateral | Comment |){skip();} ; 片段空间:(“”|’\t’|’\r’|’\n’+; 片段标识符:('a'..'z'|'a'..'z'|'|'|')('a'..'z'|'a'..'z'|'|'|'0'..'9')*; 片段结构:'\''.''.'.'.'.*''.'''''.''; 片段注释:'{'~'}'*'}';
我会成功的。注意,我对Delhpi/Pascal不是很熟悉,所以我肯定是在搞砸
strlateral
s和/或
Comment
s,但这很容易解决

根据上述语法生成的lexer将只生成两种类型的标记(
过程
s和
函数
s),其余的输入(字符串文本、注释或如果没有匹配,一个字符:
)将立即从lexer中丢弃(
跳过()
方法)

对于这样的输入:

一些有效的源代码
{ 
函数nota函数。。。
}
程序过程
开始
...
结束;
程序函数
开始
s='函数notaffunction!!!'
结束;
将创建以下解析树:


你所问的问题被称为。其概念是为您关心的语言部分(即“岛”)定义一个解析器,该部分包含该部分所需的所有经典标记化,并定义一个非常松散的解析器来跳过其余部分(即嵌入岛的“海洋”)。这样做的一个常见技巧是定义相应的草率lexer,它会收集大量的内容(例如,要跳过HTML到嵌入式代码,您可以尝试跳过任何看起来不像lexer中的脚本标记的内容)

ANTLR网站甚至特别指出,ANTLR中包含了一些例子。我没有使用ANTLR的经验,所以我不知道这些具体信息有多有用


在构建了许多使用解析器分析/转换代码的工具(查看我的简历)之后,我对island Grammars的通用性有点悲观。除非您的目标是对已解析的孤岛执行一些非常琐碎的操作,否则您将需要收集它直接或间接使用的所有标识符的含义。。。不幸的是,它们中的大多数都是在海洋中定义的。因此,我认为你也必须解析海洋才能完成琐碎的任务。你也会有其他麻烦,确保你真的跳过岛上的东西;这几乎意味着您的ocean lexer已经了解了空格、注释和字符串的所有挑剔语法(这比现代语言看起来更难),因此可以正确地跳过它们。YMMV.

我不确定使用antlr和类似的工具是否可行,但使用基于PEG的解析器则非常简单-只需定义一个规则,如
(!methods.)+/methods
,它将解析整个流,检测所有看起来像
方法的东西。您可能也希望在这里处理注释和字符串文本。是否希望所有内容都位于
开始
结束之间?还是你只对它们的名字感兴趣?@Bart:首先,只有名字…@SK logic:非常感谢你的回答,我们也会看看基于PEG的解析器。对不起,规则应该是:
(!methods.)/methods)+
。这里,
解析任何字符。Ira,非常感谢链接和答案。真有价值!巴特对ANTLR的东西很在行,因此他的即时岛语法。但是它有问题(不是巴特的错)。如果您的语言允许文本字符串或注释,这将错误地将/*过程Proc is foobarred*/作为过程声明。这是岛屿语法的问题之一:它们必须足够准确,以满足您的需要。也许你不在乎,但请确保你不在乎,否则你会大吃一惊。@Ira,呃,我确实在lexer中定义了将被跳过的字符串文字和注释规则(请参阅规则
strlateral
comment
)。还是我误解了?巴特:不,我没有在你回答的密码中看到它们;如果你确信自己知道某件事的意思,那么你所看不到的东西是令人惊讶的。我想我得学着更仔细地阅读:-{干得好,巴特(在评论中得到了饼干)。你加上它们的事实也说明了我的观点:-}@Ira,啊,很好。当像你这样的人(意思是:一个更有经验的w.r.t.解析)评论我的一个答案时,我总是保持警惕。尤其是如果有人最近承诺……;)