ANTLR:如何跳过多行注释 [英] ANTLR: How to skip multiline comments

查看:24
本文介绍了ANTLR:如何跳过多行注释的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定以下词法分析器:

lexer grammar CodeTableLexer;

@header {
    package ch.bsource.ice.parsers;
}

CodeTabHeader   : OBracket Code ' ' Table ' ' Version CBracket;
CodeTable       : Code ' '* Table;
EndCodeTable    : 'end' ' '* Code ' '* Table;
Code            : 'code';
Table           : 'table';
Version         : '1.0';
Row             : 'row';
Tabdef          : 'tabdef';
Override        : 'override' | 'no_override';
Obsolete        : 'obsolete';
Substitute      : 'substitute';
Status          : 'activ' | 'inactive';
Pkg             : 'include_pkg' | 'exclude_pkg';
Ddic            : 'include_ddic' | 'exclude_ddic';
Tab             : 'tab';
Naming          : 'naming';
Dfltlang        : 'dfltlang';
Language        : 'english' | 'german' | 'french' | 'italian' | 'spanish';
Null            : 'null';
Comma           : ',';
OBracket        : '[';
CBracket        : ']';

Boolean
    : 'true' 
    | 'false'
    ;

Number
    : Int* ('.' Digit*)?
    ;

Identifier
    : ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_' | '$' | '#' | '.' | Digit)*
    ;

String
@after {
    setText(getText().substring(1, getText().length() - 1).replaceAll("\\\\(.)", "$1"));
}
    : '"' (~('"'))* '"'
    ;

Comment
    : '--' ~('\r' | '\n')* { skip(); }
    | '/*' .* '*/' { skip(); }
    ;

Space
    : (' ' | '\t') { skip(); }
    ;

NewLine
    : ('\r' | '\n' | '\u000C') { skip(); }
    ;

fragment Int
    : '1'..'9'
    | '0'
    ;

fragment Digit 
    : '0'..'9'
    ;

... 和以下解析器:

... and the following parser:

parser grammar CodeTableParser;

options {
    tokenVocab = CodeTableLexer;
    backtrack = true;
    output = AST;
}

@header {
   package ch.bsource.ice.parsers;
}

parse
    : block EOF
    ;

block
    : CodeTabHeader^ codeTable endCodeTable
    ;

codeTable
    : CodeTable^ codeTableData
    ;

codeTableData
    : (Identifier^ obsolete?) (tabdef | row)*
    ;

endCodeTable
    : EndCodeTable
    ;

tabdef
    : Tabdef^ Identifier+
    ;

row
    : Row^ rowData
    ;

rowData
    : (Number^ | (Identifier^ (Comma Number)?))
        Override?
        obsolete?
        status?
        Pkg?
        Ddic?
        (tab | field)*
    ;

tab
    : Tab^ value+
    ;

field
    : (Identifier^ value) | naming
    ;

value
    : OBracket? (Identifier | String | Number | Boolean | Null) CBracket?
    ;

naming
    : Naming^ defaultNaming (l10nNaming)*
    ;

defaultNaming
    : Dfltlang^ String
    ;

l10nNaming
    : Language^ String?
    ;

obsolete
    : Obsolete^ Substitute String
    ;

status
    : Status^ Override?
    ;

...最后我的类使解析器不区分大小写:

... finally my class for making the parser case-insensitive:

package ch.bsource.ice.parsers;

import java.io.IOException;
import org.antlr.runtime.*;

public class ANTLRNoCaseFileStream extends ANTLRFileStream {

    public ANTLRNoCaseFileStream(String fileName) throws IOException {

        super (fileName, null);
    }

    public ANTLRNoCaseFileStream(String fileName, String encoding) throws IOException {

        super (fileName, null);
    }

    public int LA(int i) {

        if (i == 0) return 0;
        if (i < 0) i++;
        if ((p + 1 - 1) >= n) return CharStream.EOF
        return Character.toLowerCase(data[p + 1 - 1]);
    }
}

...按预期跳过单行注释,而多行注释不是...这是我收到的错误消息:

... single-line comments are skipped as expected, while multi-line comments aren't... here is the error message I get:

codetable_1.txt line 38:0 mismatched character '<EOF>' expecting '*'
codetable_1.txt line 38:0 mismatched input '<EOF>' expecting EndCodeTable
java.lang.NullPointerException
...

我错过了什么吗?有什么我应该注意的吗?我使用的是 antlr 3.4.

Am I missing something? Is there anything I should be aware of? I'm using antlr 3.4.

这也是我试图解析的示例源代码:

Here is also the example source code I'm trying to parse:

[code table 1.0]

/*
This is a multi-line comment
*/

code table my_table

-- this is a single-line comment
row 1
    id              "my_id_1"
    name            "my_name_1"
    descn           "my_description_1"
    naming
      dfltlang      "My description 1"
      english       "My description 1"
      german        "Meine Beschreibung 1"

-- this is another single-line comment
row 2
    id              "my_id_2"
    name            "my_name_2"
    descn           "my_description_2"
    naming
      dfltlang      "My description 2"
      english       "My description 2"
      german        "Meine Beschreibung 2"

end code table

任何帮助将不胜感激:-)

Any help would be really appreciated :-)

谢谢,j3d

推荐答案

Bart 给了我极大的支持,我想我们都非常感谢他 :-)

Bart gave me an amazing support and I think we all really appreciate him :-)

无论如何,问题是我用来将解析的字符流转换为小写的 FileStream 类中的一个错误.下面是正确的 Java 源代码:

Anyway, the problem was a bug in the FileStream class I use to convert parsed char stream to lowercase. Here below is the correct Java source code:

import java.io.IOException;
import org.antlr.runtime.*;

public class ANTLRNoCaseFileStream extends ANTLRFileStream {

    public ANTLRNoCaseFileStream(String fileName) throws IOException {

        super (fileName, null);
    }

    public ANTLRNoCaseFileStream(String fileName, String encoding) throws IOException {

        super (fileName, null);
    }

    public int LA(int i) {

        if (i == 0) return 0;
        if (i < 0) i++;
        if ((p + i - 1) >= n) return CharStream.EOF;
        return Character.toLowerCase(data[p + i - 1]);
    }
}

这篇关于ANTLR:如何跳过多行注释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆