2

次の samba 構成ファイルに非常によく似たドキュメントのパーサーを作成したいと考えています。多くのセクションがあり、各セクションにはヘッダー行があり、[ で始まり、global、share_name などのキーワード セクション名が行末まで続きます。セクション ヘッダー行に続く は、このセクションのパラメーターです。別のセクションの新しい行の先頭に到達するまで、セクションの終わりはわかりません [..、この種のドキュメントのルールを作成するにはどうすればよいですか? 私が見つけたすべてのantlrの例は、いつセクションを開始し、いつセクションを終了するかを正確に知っています。どうもありがとう!

[global]
    netbios name = NETBIOS_NAME
    workgroup = WORKGROUP
    security = user
[SHARE_NAME]
    comment = COMMENT
    force create mode = 0770
    locking = yes
[printers]
    comment = COMMENT
    path = /var/spool/samba
    browseable = No

これが私の文法です:

grammar SambaConfiguration;

file    :   global_section
    share_name_section
    printer_section
    EOF
;

global_section 
    :   SECTION_TAG_START GLOBAL_SECTION_TAG (.)* SECTION_TAG_END NEW_LINE
    (~SECTION_TAG_START (.)* NEW_LINE)*
    ;

share_name_section 
    :   SECTION_TAG_START SHARE_NAME_SECTION_TAG (.)*  SECTION_TAG_END NEW_LINE
    ((~SECTION_TAG_START) (.)* NEW_LINE)*
    ;

printer_section
    :   SECTION_TAG_START PRINTER_SECTION_TAG (.)* SECTION_TAG_END NEW_LINE
    ((~SECTION_TAG_START) (.)* NEW_LINE)*
    ;

SECTION_TAG_START 
    :   '['
    ;

SECTION_TAG_END
    :   ']'
    ;

GLOBAL_SECTION_TAG
    :   'global' 
    ;

SHARE_NAME_SECTION_TAG 
    :   'SHARE_NAME' 
    ;

PRINTER_SECTION_TAG 
    :   'printer'
    ;   


NEW_LINE :
    '\r' ? '\n' | '\r'
    ;
WHITE_SPACE 
    :   ' ' | '\t'
    ;

どういうわけか、それは正しく動作しません。Antlrworks で実行すると、次の例外が発生します。

12:19 のトークン一致の問題

ありがとう。

4

1 に答える 1

1

エラーメッセージ:

12:19 のトークン一致の問題

は、ANTLR が'o'トークンを作成できない文字 に遭遇したことを意味します。パーサー ルールの と一致すると思うかもしれ.ませんが、そうではありません。パーサー ルール内では、 は.任意のトークンに一致しますが、レクサー ルール内でのみ任意の文字に一致します。

lexer は次のトークンのみを作成します: SECTION_TAG_STARTSECTION_TAG_ENDGLOBAL_SECTION_TAGSHARE_NAME_SECTION_TAGPRINTER_SECTION_TAGおよび。したがって、パーサー内のルールは、これらのトークンのいずれかと一致しますが、それ以上は一致しません。NEW_LINEWHITE_SPACE.

ANTLR を学ぶためにこれを行っているのでない限り、このタスクに ANTLR を使用することを躊躇します。いくつかの組み込みの文字列操作と入力を行ごとに読み取ることで、これをより簡単に行うことができます。

ANTLR を使用すると、次のようなことができます。

grammar T;

parse
 : section* EOF
 ;

section
 : header line*
 ;

header
 : SECTION_TAG_START name=text SECTION_TAG_END NEW_LINE
   {
     System.out.println("name=" + $name.text);
   }
 ;

line
 : key=text ASSIGN value=text (NEW_LINE | EOF)
   {
     System.out.println("  key=`" + $key.text.trim() + 
         "`, value=`" + $value.text.trim() + "`");
   }
 ;

text
 : OTHER+
 ;

SECTION_TAG_START : '[';
SECTION_TAG_END   : ']';
ASSIGN            : '=';
NEW_LINE          : '\r'? '\n';
OTHER             : . /* any other char: must be the last rule! */;

入力例を解析すると、コンソールに次のように出力されます。

名前=グローバル
  key=`netbios 名`, value=`NETBIOS_NAME`
  key=`workgroup`, value=`WORKGROUP`
  キー=`セキュリティ`、値=`ユーザー`
名前=SHARE_NAME
  キー=`コメント`, 値=`コメント`
  key=`強制作成モード`, value=`0770`
  キー=`ロック`, 値=`はい`
名前=プリンター
  キー=`コメント`, 値=`コメント`
  キー=`パス`、値=`/var/spool/samba`
  キー=`参照可能`、値=`いいえ`
于 2013-01-25T18:38:39.667 に答える