是否有任何常见的解决方案如何使用不完整的语法?在我的情况下,我只想检测Delphi(Pascal)文件中的方法,这意味着procedures
和functions
。以下第一次尝试正在进行中
methods
: ( procedure | function | . )+
;
但这是一个解决方案吗?还有更好的解决方案吗?是否可以通过动作停止解析(例如,在检测到implementation
之后)。使用预处理器是否有意义?什么时候 - 如何?
答案 0 :(得分:4)
如果你只是在寻找名字,那就像这样简单:
grammar PascalFuncProc;
parse
: (Procedure | Function)* EOF
;
Procedure
: 'procedure' Spaces Identifier
;
Function
: 'function' Spaces Identifier
;
Ignore
: (StrLiteral | Comment | .) {skip();}
;
fragment Spaces : (' ' | '\t' | '\r' | '\n')+;
fragment Identifier : ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_' | '0'..'9')*;
fragment StrLiteral : '\'' ~'\''* '\'';
fragment Comment : '{' ~'}'* '}';
会做到这一点。请注意,我对Delhpi / Pascal不是很熟悉,因此我肯定会对StrLiteral
和/或Comment
进行调整,但这很容易解决。
从上面的语法生成的词法分析器只会生成两种类型的标记(Procedure
和Function
s),其余的输入(字符串文字,注释或者如果没有匹配,单个字符:.
)立即从词法分析器中丢弃(skip()
方法)。
对于这样的输入:
some valid source
{
function NotAFunction ...
}
procedure Proc
Begin
...
End;
procedure Func
Begin
s = 'function NotAFunction!!!'
End;
创建了以下解析树:
答案 1 :(得分:4)
你问的是island grammars。这个概念是你为你所关心的语言部分(“岛”)定义了一个解析器,其中包含了该部分所需的所有经典标记,并且你定义了一个非常草率的解析器来跳过其余部分(“海洋”)其中嵌入岛屿)。这样做的一个常见技巧是定义相应的草率词法分析器,它们可以获取大量的东西(为了跳过HTML到嵌入式代码,你可以尝试跳过任何看起来像词法分析器中的脚本标记的东西,因为例子)。
ANTLR网站甚至discusses some related issues,但值得注意的是,ANTLR中包含了一些示例。我没有使用ANTLR的经验,因此我不知道这些具体信息有多么有用。
已经构建了许多工具,使用解析器来分析/转换代码(检查我的生物)我对岛屿grammmars的一般效用有点悲观。除非你的目标是使用解析岛做一些非常微不足道的事情,否则你需要直接或间接地收集它所使用的所有标识符的含义......并且很遗憾,对于你在海洋中定义的大多数标识符。所以恕我直言,你几乎必须解析海洋,以完成琐碎的任务。你也会有其他麻烦,确保你真的跳过岛上的东西;这几乎意味着你的海洋词法分析器已经知道空格,注释以及字符串的所有挑剔语法(这比现代语言看起来更难),以便正确地跳过它们。 YMMV。