1

SRT形式の文法を作成しようとしています。

srtファイルの例を次に示します。

1
00:00:02,218 --> 00:00:04,209
[SHELDON SPEAKING IN MANDARIN]

2
00:00:04,721 --> 00:00:05,745
No, it's:

3
00:00:05,922 --> 00:00:07,913
[SPEAKING IN MANDARIN]

4
00:00:09,392 --> 00:00:11,383
[SPEAKING IN MANDARIN]

5
00:00:13,430 --> 00:00:15,193
What's this?

6
00:00:16,266 --> 00:00:18,029
That's what you did.

7
00:00:18,201 --> 00:00:22,467
I assumed, as in a number of languages,
that the gesture was part of the phrase.

8
00:00:22,639 --> 00:00:25,233
- Well, it's not.
- Why am I supposed to know that?

9
00:00:25,408 --> 00:00:28,900
As teacher, it's your obligation
to separate your personal idiosyncrasies...

10
00:00:29,079 --> 00:00:30,512
...from the subject matter.

11
00:00:31,081 --> 00:00:33,845
- I'm glad you decided to learn Mandarin.
- Why?

326
00:18:56,818 --> 00:19:00,720
Actually, I've heard
far too much about Schrödinger's cat.

327
00:19:01,623 --> 00:19:03,022
Good.

328
00:19:09,131 --> 00:19:11,895
All right, the cat's alive.
Let's go to dinner.

329
00:19:12,000 --> 00:19:15,072
Download Movie Subtitles Searcher from www.OpenSubtitles.org

これがantlr(v。3.4)の私の文法です。

grammar Exp;


parse
    :  (SUBTITLE)+
    ;

SUBTITLE
    : i=ID NL 
      t1=Timestamp SPACE ARROW SPACE t2=Timestamp NL 
      txt1 = TEXT

        {
            System.out.println("id="+$i); 
            System.out.println("t1= "+$t1); 
            System.out.println("t2= "+$t2);
            System.out.println("txt1= "+$txt1);

        }
    ;

TEXT 
    : ((TextLine NL NL)|(TextLine NL TextLine NL NL))
    ;

ID
    : DIG+
    ;

ARROW
    : '-->'
    ;

Timestamp
    : DIG DIG ':' DIG DIG ':' DIG DIG ',' DIG DIG DIG
    ;

TextLine
  :  ~('\r' | '\n')*
  ;

NL
  :  '\r'? '\n'
  |  '\r'
  ;

fragment
DIG 
    : '0'..'9'
    ;

fragment
SPACE
    :   ' ' | '\t'
    ;

私の簡単なコード:

String input = IOUtils.toString(Test.class.getResourceAsStream("/subtitles.srt"));
ExpLexer lexer = new ExpLexer(new ANTLRStringStream(input));
CommonTokenStream stream = new CommonTokenStream(lexer);
ExpParser parser = new ExpParser(stream);
parser.parse();

そして、ファイルの最後に2つの新しい行がある場合、ほとんどすべてが完全に機能します。そうでない場合は、次のエラーが発生します。

line 1484:0 no viable alternative at character '<EOF>'

文法をより柔軟に変更する方法についてアドバイスはありますか?最後に1行、2行以上になることを受け入れます。

4

2 に答える 2

2

使用しているレクサールールが多すぎます。

次のようなものを試してください。

grammar T;

options {
  output=AST;
}

tokens {
  BLOCKS;
  BLOCK;
  TIME_RANGE;
  LINES;
  LINE;
  WORD;
}

parse
 : LineBreak* blocks LineBreak* EOF -> blocks
 ;

blocks
 : block (LineBreak LineBreak+ block)* -> ^(BLOCKS block+)
 ;

block 
 : Number Spaces? LineBreak time_range LineBreak text_lines -> ^(BLOCK Number time_range text_lines)
 ;

time_range
 : Time Spaces? Arrow Spaces? Time Spaces? -> ^(TIME_RANGE Time Time)
 ;

text_lines
 : line (LineBreak line)* -> ^(LINES line+)
 ;

line
 : Spaces? word (Spaces word)* Spaces? -> ^(LINE word+)
 ;

word
 : (Other | Number | Dashes | Arrow)+ -> WORD[$text]
 ;

Time      : Number ':' Number ':' Number ',' Number;
Arrow     : '-->';
Dashes    : '-'+;
Number    : '0'..'9'+;
LineBreak : '\r'? '\n' | '\r';
Spaces    : (' ' | '\t')+;
Other     : . ;

入力を解析します:

1
00:00:02,218-> 00:00:04,209
[ABC]

2
00:00:04,721-> 00:00:05,745
-  ライン1
-  2行目



3
00:00:05,922-> 00:00:07,913
mu-> MU

次のASTに:

ここに画像の説明を入力してください

(画像をクリックすると拡大します)

編集

テキストに数字とコロンがある場合、問題が発生します。「シーズン1エピソード15:」または「11:00に電話します。ビクトリア」'例を変更しようとしましたが、成功しませんでした。

テストされていませんが、これは機能するはずです。ルールの最初のコロンののすべてをオプションにします。Timeそして、ルールの最後に、最後NumberTime入力が一致するかどうかを確認します。そうでない場合は、トークンのタイプをに変更しますOther

Time      
 : Number ':' (Number (':' (Number (',' last=Number?)?)?)?)?
   {
     if($last.text == null) $type = Other;
   }
 ;
于 2013-01-02T19:07:09.267 に答える
2

その理由はTEXT、最後に2つの新しい行が必要になるためです。

末尾のNLを1つ削除してTEXT、代わりにの間の区切り文字にすることができSUBTITLEます。

何かのようなもの:

parse
    :  SUBTITLE (NL SUBTITLE)*
    ;

ところで、TEXTは1行か2行しか持てないということですか?

于 2013-01-02T14:46:00.140 に答える