我是Antlr的新手,我使用Antlr 3定义了基本语法。语法编译,ANTLRWorks生成Parser和Lexer代码,没有任何问题。
语法如下:
grammar i;
@header {
package i;
}
module : 'Module1'| 'Module2';
object : 'I';
objectType : 'Name';
filters : EMPTY | 'WHERE' module;
table : module object objectType;
STRING : ('a'..'z'|'A'..'Z')+;
EMPTY : ' ';
问题是当我解释表Parser时,我得到一个MismatchedSetException。这是因为拥有EMPTY。一旦我从语法中删除EMPTY,解释就会起作用。我查看了Antlr网站和其他一些例子,空格是''。我不知道该怎么做。我需要这个EMPTY。
当它解释时,我得到以下例外:
Interpreting...
[11:02:14] problem matching token at 1:4 NoViableAltException(' '@[1:1: Tokens : ( T__4 | T__5 | T__6 | T__7 | T__8 | T__9 | T__10 | T__11 | T__12 | T__13 | T__14 | T__15 );])
[11:02:14] problem matching token at 1:9 NoViableAltException(' '@[1:1: Tokens : ( T__4 | T__5 | T__6 | T__7 | T__8 | T__9 | T__10 | T__11 | T__12 | T__13 | T__14 | T__15 );])
我将EMPTY更改为以下内容:
EMPTY : '';
而不是:
EMPTY : ' ';
它实际上解释了它。但是,我得到以下例外:
Interpreting...
[10:57:23] problem matching token at 1:4 NoViableAltException(' '@[1:1: Tokens : ( T__4 | T__5 | T__6 | T__7 | T__8 | T__9 | T__10 | T__11 | T__12 | T__13 | T__14 | T__15 | T__16 );])
[10:57:23] problem matching token at 1:9 NoViableAltException(' '@[1:1: Tokens : ( T__4 | T__5 | T__6 | T__7 | T__8 | T__9 | T__10 | T__11 | T__12 | T__13 | T__14 | T__15 | T__16 );])
但是,ANLTWorks仍会生成Lexer和Parser代码。
我希望你能提供帮助。
编辑:
grammar i;
@header {
package i;
}
select : 'SELECT *' 'FROM' table filters';';
filters : EMPTY | 'WHERE' conditions;
conditions : STRING operator value;
operator : '=' | '!=';
true : 'true';
value : true;
STRING : ('a'..'z'|'A'..'Z')+;
EMPTY : ' ';
答案 0 :(得分:1)
我仍然对使用情况有点不确定,但我认为当我们说“空输入”时,我们正在谈论同样的事情。这是一个让球滚动的答案,从修改后的语法开始。
grammar i;
@header {
package i;
}
module : 'Module1'| 'Module2';
object : 'I';
objectType : 'Name';
filters : | 'WHERE' module;
table : module object objectType filters;
STRING : ('a'..'z'|'A'..'Z')+;
WS : (' '|'\t'|'\f'|'\n'|'\r')+ {skip();}; //ignore whitespace
请注意,我在filters
规则的末尾添加table
来解释我在说什么。
该语法接受以下输入(从规则table
开始),如前所述:
Module1 I Name
它有效,因为filters
匹配,即使文本Name
后面没有任何内容:它使用第一个备选方案匹配空输入。
语法也接受这个:
Module1 I Name WHERE Module2
filters
规则对匹配第二个备选项(在语法中定义为WHERE Module2
)的文本'WHERE' module
感到满意。
更简洁的做法是将filters
和table
更改为以下规则(当然,我认识到我首先更改了table
。)
filters : 'WHERE' module; //no more '|'
table : module object objectType filters?; //added '?'
语法匹配与之前相同的输入,但条款更清晰:我们现在说filters
和table
匹配“filters
,而不是”filters
“table
在filters
中是可选的,foo: | etc;
在空”上不匹配“。
在这种情况下,这相同。在空(foo?
)上匹配是完全有效的,但是我使用它时遇到的问题比匹配可选(grammar i;
@header {
package i;
}
selects : ( //test rule to allow processing multiple select calls. Don't worry about the details.
{System.out.println(">>select");}
select
{System.out.println("<<select");}
)+
;
select : 'SELECT *' 'FROM' table filters? ';'
{System.out.println("\tFinished select.");} //test output
;
module : 'Module1'| 'Module2';
object : 'I';
objectType : 'Name';
filters : 'WHERE' conditions
{System.out.println("\tFinished filters.");} //test output
;
table : module object objectType
{System.out.println("\tFinished table.");} //test output
;
conditions : STRING operator value
{System.out.println("\tCondition test on " + $STRING.text);}
;
operator : '=' | '!=';
true_ : 'true'; //changed so that Java code could be generated
value : true_;
STRING : ('a'..'z'|'A'..'Z')+;
WS : (' '|'\t'|'\f'|'\n'|'\r')+ {skip();}; //ignore whitespace
)规则时遇到的问题更多。
更新后更新。
我在这里退后一步,让我们脱离理论,进入实践。这是一个更新的语法,调用它的Java测试代码,测试输入和测试输出。请试一试。
<强>语法强> 改进测试但遵循与以前相同的想法。
package i;
import java.io.InputStream;
import org.antlr.runtime.ANTLRInputStream;
import org.antlr.runtime.CharStream;
import org.antlr.runtime.CommonTokenStream;
public class TestiGrammar {
public static void main(String[] args) throws Exception {
InputStream resource = TestiGrammar.class.getResourceAsStream("itest.txt");
CharStream input = new ANTLRInputStream(resource);
resource.close();
iLexer lexer = new iLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
iParser parser = new iParser(tokens);
parser.selects();
}
}
<强> TestiGrammar.java 强>
SELECT * FROM Module2 I Name;
SELECT * FROM Module2 I Name WHERE foobar = true;
SELECT * FROM Module2 I Name WHERE dingdong != true;
itest.txt 测试输入文件
>>select
Finished table.
Finished select.
<<select
>>select
Finished table.
Condition test on foobar
Finished filters.
Finished select.
<<select
>>select
Finished table.
Condition test on dingdong
Finished filters.
Finished select.
<<select
测试输出
{{1}}