ANTLRv3不读取选项

| 我是ANTLR的新手,正在尝试了解Lexer和Parser规则的工作方式。我遇到的语法问题似乎与词法分析器令牌相关,即使只有前几个字符实际匹配,多个字符也被视为\“ matches \”。为了证明这一点,我编写了一个简单的ANTLR 3语法:
grammar test;
options {
    k=3;
}

@lexer::header { package test;}
@header {package test;}

sentence    :   (CHARACTER)*;

CHARACTER   :   \'a\'..\'z\'|\' \';
SPECIAL     :   \'special\';
我正在使用AntlrWorks解析以下测试输入:
apple basic say sponsor speeds speckled specific wonder
我得到的输出是:
apple basic say nsor ds led ic wonder
在我看来,LEXER使用k = 1,因此将我的SPECIAL令牌与包含两个字母'sp'的任何事物进行匹配。一旦遇到字母\'sp \',它将匹配SPECIAL文字中的连续字符,直到实际输入与期望的标记不匹配为止-这时它将引发错误(消耗该字符),然后继续其余的操作这句话。每个错误的形式为:
  line 1:18 mismatched chracter \'o\' expecting \'e\'
但是,这不是我要尝试创建的行为。我希望创建一个与关键字(\'special \')匹配的词法分析器标记-供在此测试示例中未包括的其他解析器规则中使用。但是,我不希望其他恰好包含相同初始字符的规则/输入受到影响 总结一下: 如何实际设置antlr 3选项(例如k = 2或k = 3等)?至少在我看来,我要在此处使用的选项没有设置。 有没有更好的方法来创建解析器或词法分析器规则,以匹配我输入中的特定关键字,而又不影响输入中不包含完全匹配项的其他部分的处理?     
已邀请:
“ 5”部分中的“ 4”定义了解析器(而不是词法分析器)之前的外观。 注意语法
CHARACTER   :   \'a\'..\'z\'|\' \';
SPECIAL     :   \'special\';
含糊不清:您的ѭ7also也可以视为7
\'a\'..\'z\'
\。通常,它的词法如下:
grammar Test;

sentence : (special | word | space)+ EOF;
special  : SPECIAL;
word     : WORD;
space    : SPACE;

SPECIAL  : \'special\';
WORD     : \'a\'..\'z\'+;
SPACE    : \' \';
它将解析输入:
specia special specials
如下: 即它(或多或少)被标记为LL(1)和“最长匹配”的组合。抱歉,我意识到这有点含糊,但是《权威ANTLR参考》并没有明确阐明这一点(至少,我找不到它……)。但是我意识到这可能不是您想要的。 AFAIK是产生单个字符令牌并定义由这些单个字符令牌组成的关键字的唯一方法,它是通过将这两个令牌合并到一条规则中并使用谓词和手动先行查看它们是否符合来完成的设置为关键字,如果没有,则在“ fallthrough”子规则中更改令牌的类型。演示:
grammar test;

tokens {
  LETTER;
}

@lexer::members {
  // manual look ahead
  private boolean ahead(String text) {
    for(int i = 0; i < text.length(); i++) {
      if(input.LA(i+1) != text.charAt(i)) {
        return false;
      }
    }
    return true;
  }
}

sentence
  :  (t=. {System.out.printf(\"\\%-7s :: \'\\%s\'\\n\", tokenNames[$t.type], $t.text);})+ EOF
  ;

SPECIAL 
  :  {ahead(\"special\")}?=> \'special\'
  |  {ahead(\"keyword\")}?=> \'keyword\'
  |  \'a\'..\'z\' {$type = LETTER;} // Last option and no keyword is found: 
                                // change the type of this token
  ;

SPACE
  :  \' \'
  ;
可以使用以下类测试由上述语法生成的解析器:
import org.antlr.runtime.*;

public class Main {
    public static void main(String[] args) throws Exception {
        ANTLRStringStream in = new ANTLRStringStream(\"apple basic special speckled keyword keywor\");
        testLexer lexer = new testLexer(in);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        testParser parser = new testParser(tokens);
        parser.sentence();
    }
}
如您所见,在解析输入时:
apple basic special speckled keyword keywor
生成以下输出:
LETTER  :: \'a\'
LETTER  :: \'p\'
LETTER  :: \'p\'
LETTER  :: \'l\'
LETTER  :: \'e\'
SPACE   :: \' \'
LETTER  :: \'b\'
LETTER  :: \'a\'
LETTER  :: \'s\'
LETTER  :: \'i\'
LETTER  :: \'c\'
SPACE   :: \' \'
SPECIAL :: \'special\'
SPACE   :: \' \'
LETTER  :: \'s\'
LETTER  :: \'p\'
LETTER  :: \'e\'
LETTER  :: \'c\'
LETTER  :: \'k\'
LETTER  :: \'l\'
LETTER  :: \'e\'
LETTER  :: \'d\'
SPACE   :: \' \'
SPECIAL :: \'keyword\'
SPACE   :: \' \'
LETTER  :: \'k\'
LETTER  :: \'e\'
LETTER  :: \'y\'
LETTER  :: \'w\'
LETTER  :: \'o\'
LETTER  :: \'r\'
请参阅问答。ANTLR中的“语义谓词”是什么?进一步了解ANTLR中的谓词。     

要回复问题请先登录注册