将单个senerio与ANTLR匹配,并将其他所有内容作为噪音跳过

时间:2015-05-31 16:41:49

标签: java parsing coldfusion antlr

我使用ANTLR V4 Eclipse插件定义了一个简单的语法。我想解析包含Coldfusion cfscript代码的文件,并查找属性定义的每个实例。例如:

property name="productTypeID" ormtype="string" length="32" fieldtype="id" generator="uuid" unsavedvalue="" default="";

即,属性关键字后跟任意数量的属性,以分号结尾。

.g4文件

grammar CFProperty;
property  : 'property ' (ATR'='STRING)+EOL; // match keyword property followed by an attribute definition

ATR : [a-zA-Z]+;                            // match lower and upper-case identifiers name

STRING: '"' .*? '"';                        // match any string

WS : [ \t\r\n]+ -> skip;                    // skip spaces, tabs, newlines

EOL : ';';                                  // end of the property line

我整理了一个简单的java项目,它使用生成的解析器,tree-walker等打印出这些匹配的出现次数。

我测试的输入是:

"property id=\"actionID\" name=\"actionName\" attr=\"actionAttr\"    hbMethod=\"HBMethod\"; public function some funtion  {//some text} property name=\"actionID\" name=\"actionName\" attr=\"actionAttr\" hbMethod=\"HBMethod\"; \n more noise "

我的问题是这只是匹配:

property id="actionID" name="actionName" attr="actionAttr"    hbMethod="HBMethod";

并且因为它不能理解其他是噪声,所以它与属性定义的第二个实例不匹配。

如何匹配属性定义的多个实例,并匹配中间的所有其他实例作为要跳过的噪声?

1 个答案:

答案 0 :(得分:2)

您可以使用词法模式来执行您想要的操作。属性和东西的一种模式和噪声的一种模式。模式背后的想法是从一种模式(一种状态)转到我们在lexing操作期间发现的另一种标记。

要做到这一点,你必须在两个文件中剪切你的语法,一个文件中的解析器和另一个文件中的词法分析器。

这是词法分析器部分(在我的例子中名为TestLexer.g4

lexer grammar TestLexer;

// Normal mode

PROPERTY : 'property';
EQUALS : '=';
ATR : [a-zA-Z]+;                           // match lower and upper-case identifiers name
STRING: '"' .*? '"';                       // match any string
WS : [ \t\r\n]+        -> skip;            // skip spaces, tabs, newlines
EOL : ';'              -> pushMode(NOISE); // when ';' is found, go to noise mode where everything is skip

mode NOISE;

NOISE_PROPERTY : 'property' -> type(PROPERTY), popMode;   // when 'property' is found, we say it's a PROPERTY token and we go back to  normal mode
ALL :  .+?                  -> skip;                      // skip all other stuffs

这是解析器部分(在我的例子中名为Test.g4

grammar Test;

options { tokenVocab=TestLexer; }

root : property+;
property  : PROPERTY (ATR EQUALS STRING)+ EOL; // match keyword   property followed by an attribute definition

这应该做的工作:)