java - 解释期间 Antlr MismatchedSetException

标签 java antlr

我是 Antlr 的新手,我使用 Antlr 3 定义了基本语法。语法编译并且 ANTLRWorks 生成解析器和词法分析器代码没有任何问题。

语法如下:

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           : ' ';

问题是,当我解释表解析器时,我得到了 MismatchedSetException。这是因为有 EMPTY。一旦我从语法中删除 EMPTY,解释就会起作用。我查看了 Antlr 网站和其他一些示例,空白区域是“”。我不知道该怎么办。我需要这个空的。

当它解释时,我得到以下异常:

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           : ' ';

最佳答案

我对用法仍然有点不确定,但我认为当我们说“空输入”时我们正在谈论同一件事。这是一个让事情开始的答案,从修改后的语法开始。

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

它之所以有效,是因为即使文本 Name 后面没有任何内容,filters 也会匹配:它使用第一个替代方案匹配空输入。

语法也接受这个:

Module1 I Name WHERE Module2

filters 规则满足与第二个替代项匹配的文本 WHERE Module2(在语法中定义为 'WHERE' module)。

更简洁的方法是将 filterstable 更改为以下规则(当然,要认识到我在第一名)。

filters     : 'WHERE' module; //no more '|' 
table       : module object objectType filters?; //added '?'

语法匹配与之前相同的输入,但术语更清晰一些:而不是说“filters is required in table and filters” > 匹配空”,我们现在说“filterstable 中是可选的,而 filters 不匹配空”。

在这种情况下,这相当于同样的事情。匹配空 (foo: | etc;) 是完全有效的,但使用它时遇到的问题比匹配可选 (foo?) 规则时遇到的问题更多。

<小时/>

Update following your update.

我在这里退一步,让我们脱离理论,进入实践。下面是更新的语法、调用它的 Java 测试代码、测试输入和测试输出。请运行一下。

语法 为了测试而进行了更改,但遵循与之前相同的想法。

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

TestiGrammar.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();
  }
}

itest.txt测试输入文件

SELECT * FROM Module2 I Name;
SELECT * FROM Module2 I Name WHERE foobar = true; 
SELECT * FROM Module2 I Name WHERE dingdong != true;

测试输出

>>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

关于java - 解释期间 Antlr MismatchedSetException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13510880/

相关文章:

java - 如何改进我的 Tic Tac Toe 游戏设计?

java - 修改颜色选择器面板

ANTLR : expression evaluator, split 和战俘

r - R是否存在现有的ANTLR或IRONY语法?

java - Antlr4 : Evaluate math functions f(x)

java - 如何设置CameraX(Android)5秒后停止录制?

java - 嵌套数组引用

c# - ANTLR 可与 C# 一起使用

java - 键绑定(bind)问题

antlr - ANTLR 入门并避免常见错误