English 中文(简体)
我如何从违约和隐蔽的渠道读到Antl Parser规则
原标题:How do I get an Antlr Parser rule to read from both default AND hidden channel

我将正常的白天空间分离到隐蔽的渠道,但我有一项规则,即我要将任何白天空间纳入以后的处理,但我发现的任何例子都需要一些非常奇怪的手工编码。

从多种渠道来看,如从一开始就把白天空放在别处。

例如,《白天航天法》规则。

WS  :   (    
        |  	 
        |  
 
        |  
 
        ) {$channel=HIDDEN;}
    ;

这也是我的规则,我想包括白色空间。

raw :    { ? (~( { ))*;

基本上,它符合一条规则,以涵盖任何不符合其他规则的内容,以另一种方式处理,因此,我需要原始流。

我希望有一个<代码>。 « channel=HIDDEN} syntax example,但找不到。

我的目标将是C#,但我可以在必要时重写 Java例子。

最佳回答

AFAIK是不可能的。 但是,您可以延长<代码>。 Unbuffered TokenStream to change thecode>channel during parsing. 页: 1 Common TokenStream 因为它缓冲了数量可变的象征性物(而且缓冲区内可能会有象征性的症状!) 请注意:至少需要《公约》第三条第3款:在以前的版本中,<代码> Unbuffered TokenStream wasn t included yet.

请允许我说,你想要打平(和显示)低级或高级案件信。 上一份个案信载于<编码>HIDDEN。 渠道,如聋.,只有少发的个案信才会平价。 然而,当主人对一个较低案例(q>>) st时,我们要改写。 HIDDEN 频道。 在<代码>上一栏 频道,我们希望<代码>Q>使我们回到<代码>。 DEFAULT_CHANNEL/code>。

因此,如果将源代码<>aAbBcqCdDQeE>、1a>、b>c>印刷,那么该频道就会发生变化,然后改为C>D>>>,则该频道将再次变更,最后<代码>e><<>_>><>e>><>>><>>><>>

Here s an ANTLR grammar that does this:

ChannelDemo.g

grammar ChannelDemo;

@parser::members {
  private void handle(String letter) {
    if("Q".equals(letter)) {
      ((ChangeableChannelTokenStream)input).setChannel(Token.DEFAULT_CHANNEL);
    }
    else if("q".equals(letter)) {
      ((ChangeableChannelTokenStream)input).setChannel(HIDDEN);
    }
    else {
      System.out.println(letter);
    }
  }
}

parse
  :  any* EOF
  ;

any
  :  letter=(LOWER | UPPER) {handle($letter.getText());}
  ;

LOWER
  :   a .. z 
  ;

UPPER
  :   A .. Z  {$channel=HIDDEN;}
  ;

这里的习惯是:

ChangeableChannelTokenStream.java

import org.antlr.runtime.*;

public class ChangeableChannelTokenStream extends UnbufferedTokenStream {

    public ChangeableChannelTokenStream(TokenSource source) {
        super(source);
    }

    public Token nextElement() {
        Token t = null;
        while(true) {
            t = super.tokenSource.nextToken();
            t.setTokenIndex(tokenIndex++);
            if(t.getChannel() == super.channel) break;
        }
        return t;
    }

    public void setChannel(int ch) {
        super.channel = ch;
    }
}

And a small Main class to test it all:

Main.java

import org.antlr.runtime.*;

public class Main {
    public static void main(String[] args) throws Exception {
        ANTLRStringStream in = new ANTLRStringStream("aAbBcqCdDQeE");
        ChannelDemoLexer lexer = new ChannelDemoLexer(in);
        ChangeableChannelTokenStream tokens = new ChangeableChannelTokenStream(lexer);
        ChannelDemoParser parser = new ChannelDemoParser(tokens);
        parser.parse();
    }
}

最后,产生备选案文/备选案文(1),汇编所有来源档案(2),管理主类(3):

1

java -cp antlr-3.3.jar org.antlr.Tool ChannelDemo.g

2

javac -cp antlr-3.3.jar *.java

3 (*nix)

java -cp .:antlr-3.3.jar Main

3 (Windows)

java -cp .;antlr-3.3.jar Main

将向议会印发以下文件:

a
b
c
C
D
e

EDIT

You can include the class in your grammar file like this:

grammar ChannelDemo;

@parser::members {
  private void handle(String letter) {
    if("Q".equals(letter)) {
      ((ChangeableChannelTokenStream)input).setChannel(Token.DEFAULT_CHANNEL);
    }
    else if("q".equals(letter)) {
      ((ChangeableChannelTokenStream)input).setChannel(HIDDEN);
    }
    else {
      System.out.println(letter);
    }
  }

  public static class ChangeableChannelTokenStream extends UnbufferedTokenStream {

    private boolean anyChannel;

    public ChangeableChannelTokenStream(TokenSource source) {
      super(source);
      anyChannel = false;
    }

    @Override
    public Token nextElement() {
      Token t = null;
      while(true) {
        t = super.tokenSource.nextToken();
        t.setTokenIndex(tokenIndex++);
        if(t.getChannel() == super.channel || anyChannel) break;
      }
      return t;
    }

    public void setAnyChannel(boolean enable) {
      anyChannel = enable;
    }

    public void setChannel(int ch) {
      super.channel = ch;
    }
  }
}

parse
  :  any* EOF
  ;

any
  :  letter=(LOWER | UPPER) {handle($letter.getText());}
  |  STAR                   {((ChangeableChannelTokenStream)input).setAnyChannel(true);}
  ;

STAR
  :   * 
  ;

LOWER
  :   a .. z 
  ;

UPPER
  :   A .. Z  {$channel=HIDDEN;}
  ;

上文图表中产生的教区将可在所有渠道查阅>*。 ∗∗∗∗∗∗∗

import org.antlr.runtime.*;

public class Main {
  public static void main(String[] args) throws Exception {
    ANTLRStringStream in = new ANTLRStringStream("aAbB*cCdDeE");
    ChannelDemoLexer lexer = new ChannelDemoLexer(in);
    ChannelDemoParser.ChangeableChannelTokenStream tokens =
        new ChannelDemoParser.ChangeableChannelTokenStream(lexer);
    ChannelDemoParser parser = new ChannelDemoParser(tokens);
    parser.parse();
  }
}

原文如下:

a
b
c
C
d
D
e
E
问题回答

也许你们应当考虑把白天变成你那克语的一部分。 但是,为什么用这种不重要的信息来填写你的图表? 其实,这是无进口的。 这条新路线在某些背景下是 me的。 当你希望通过视频演播室语言服务器等网络提供支持时,你需要具体说明一种语言图表,而没有使用低水平的《国家航空航天公约》定制的所有信条。

在<代码>Antler 4上 采用简单的解决办法。 我在<代码>上进行了这种测试。 Antlr 3。 它是C#,但你可以很容易地将其翻译成 Java。

  1. Change parser1.g4 as next:

    parser grammar Parser1;
    
    options { tokenVocab=Lexer1; }
    
    startRule
    @init { SetWhiteSpacesAcceptence(false); } 
        : (componentWithWhiteSpaces | componentWithoutWhiteSpaces)* EOF
    ;
    
    componentWithWhiteSpaces : { SetWhiteSpacesAcceptence(true); } 
                                component1 component2 component3 
                                { SetWhiteSpacesAcceptence(false); } 
    ;
    
    componentWithoutWhiteSpaces : component4 component5 component6 
    
  2. 更改<代码>lexer1.g4如下:

    lexer grammar Lexer1;
    WS : [ 	
    ] { if( this.IsWhiteSpacesAccepted() ) Skip(); };
    
  3. 扩大<条码> 下面的班级:

    class MyParser : Parser1
    {
        public void SetWhiteSpacesAcceptence(bool isAccept)
        {
            if (_input != null && _input.TokenSource != null)
            {
                if (_input.TokenSource is MyLexer)
                {
                    MyLexer lexer = _input.TokenSource as MyLexer;
                    if (lexer != null)
                        lexer.SetWhiteSpacesAcceptence(isAccept);
                }
            }
        }
    
        public bool IsWhiteSpacesAccepted()
        {
            if (_input != null && _input.TokenSource != null)
            {
                if (_input.TokenSource is MyLexer)
                {
                    MyLexer lexer = _input.TokenSource as MyLexer;
                    if (lexer != null)
                        return lexer.IsWhiteSpacesAccepted();
                }
            }
    
            return false;
        }
    }
    
  4. 扩大<条码> 下面的班级:

    class MyLexer : Lexer1
    {
        private bool isWhiteSpacesAccepted;
    
        public void SetWhiteSpacesAcceptence(bool isAccept) { isWhiteSpacesAccepted = isAccept }
    
        public bool IsWhiteSpacesAccepted() { return isWhiteSpacesAccepted; }
    }
    
  5. 现有<代码>Main如下:

    static void Main()
    {
        AntlrFileStream input = new AntlrFileStream("pathToInputFile");
        MyLexer lexer = new MyLexer(input);
        UnbufferedTokenStream tokens = new UnbufferedTokenStream(lexer);
        MyParser parser = new MyParser(tokens);
    
        parser.startRule();
    }
    




相关问题
ANTLR parser hanging at proxy.handshake call

I am attempting to get a basic ECMAScript parser working, and found a complete ANTLR grammar for ECMAScript 3, which appears to compile ok and produces the appropriate Lexer/Parser/Walker Java files. (...

Will ANTLR Help? Different Suggestion?

Before I dive into ANTLR (because it is apparently not for the faint of heart), I just want to make sure I have made the right decision regarding its usage. I want to create a grammar that will parse ...

How to use ANTLR to parse xml document

can anybody tell how to use ANTLR tool(in java) to create our own grammar for xml documents and how to parse those documents using ANTLR tool(in java)?

JavaCC Problem - Generated code doesn t find all parse errors

Just started with JavaCC. But I have a strange behaviour with it. I want to verify input int the form of tokens (letters and numbers) wich are concatenated with signs (+, -, /) and wich can contain ...

How to generate introductory recognizer using ANTLR3C?

The Definitive ANTLR Guide starts with a simple recognizer. Using grammar verbatim to target C-runtime fails because %s means something to ANTLR: $ cat T.g grammar T; options { language = ...

What s the matter with this Grammar?

grammar Test; IDHEAD: ( a .. z | A .. Z | _ ); IDTAIL: (IDHEAD | 0 .. 9 ); ID: (IDHEAD IDTAIL*); fragment TYPE: ( text | number | bool ); define: define ID as TYPE; The problem ...

热门标签