2011-01-26 10 views
2

私はANTLR 3でwikitext-to-HTMLトランスレータを完成させようとしています。ANTLRのwikitext-to-HTMLの実例3

私が検査できる実例を知っていますか?私はMediaWikiのANTLR文法やWikiのクレオール文法を試してみましたが、私は彼らがここでANTLR 3に

をレクサー&パーサを生成するために得ることができない私が使用して試した2つの文法へのリンクです:

私はJavaのレクサーとパーサを生成するために、これら二つのいずれかを取得することはできません。 (私はEclipseプラグインとしてANTLR3を使用しています)。 MediaWikiは構築に時間がかかり、ある時点でOutOfMemory例外がスローされます。もう1つはデバッグ方法がわからないエラーがあります。

編集:私は非常に基本的な文法を持っているオーケー:

grammar wikitext; 

options { 
    //output = AST; 
    //ASTLabelType = CommonTree; 
    output = template; 
    language = Java; 
} 

document: line (NL line?)*; 

line: horizontal_line | list | heading | paragraph; 

/* horizontal line */ 
horizontal_line: HRLINE; 

/* lists */ 
list: unordered_list | ordered_list; 

unordered_list: '*'+ content; 
ordered_list: '#'+ content; 

/* Headings */ 
heading: heading1 | heading2 | heading3 | heading4 | heading5 | heading6; 
heading1: H1 plain H1; 
heading2: H2 plain H2; 
heading3: H3 plain H3; 
heading4: H4 plain H4; 
heading5: H5 plain H5; 
heading6: H6 plain H6; 

/* Paragraph */ 
paragraph: content; 

content: (formatted | link)+; 

/* links */ 
link: external_link | internal_link; 

external_link: '[' external_link_uri ('|' external_link_title)? ']'; 
internal_link: '[[' internal_link_ref ('|' internal_link_title)? ']]' ; 

external_link_uri: CHARACTER+; 
external_link_title: plain; 
internal_link_ref: plain; 
internal_link_title: plain; 

/* bold & italic */ 
formatted: bold_italic | bold | italic | plain; 

bold_italic: BOLD_ITALIC plain BOLD_ITALIC; 
bold: BOLD plain BOLD; 
italic: ITALIC plain ITALIC; 

/* Plain text */ 
plain: (CHARACTER | SPACE)+; 


/** 
* LEXER RULES 
* -------------------------------------------------------------------------- 
*/ 

HRLINE: '---' '-'+; 

H1: '='; 
H2: '=='; 
H3: '==='; 
H4: '===='; 
H5: '====='; 
H6: '======'; 

BOLD_ITALIC: '\'\'\'\'\''; 
BOLD: '\'\'\''; 
ITALIC: '\'\''; 

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

CHARACTER  :  '!' | '"' | '#' | '$' | '%' | '&' 
       |  '*' | '+' | ',' | '-' | '.' | '/' 
       |  ':' | ';' | '?' | '@' | '\\' | '^' | '_' | '`' | '~' 
       |  '0'..'9' | 'A'..'Z' |'a'..'z' 
       |  '\u0080'..'\u7fff' 
       |  '(' | ')' 
       |  '\'' | '<' | '>' | '=' | '[' | ']' | '|' 
       ; 

SPACE: ' ' | '\t'; 

それは1がHTMLを出力して行くだろうかしかし私にとっては明らかではありません。私はStringTemplateを調べてきましたが、テンプレートの構造を理解できません。具体的には、どのテンプレートが文法のどこに行くか。あなたは簡単な例で私を助けることができますか?

+0

どの文法が正確に意味していますか?あなたはそれらを投稿することができますか(または、彼らが大きい場合は、それらにリンクを投稿してください)?なぜあなたはレクサー&パーサーを生成できませんか?エラーメッセージが表示されますか?もしそうなら、それらを投稿できますか? –

+0

バート、私はいくつかの詳細を追加しました。 – Dan

+2

パーサーを自分で生成する特別な理由はありますか?代わりに[既存のパーサ](http://www.mediawiki.org/wiki/Alternative_parsers)を使用しないでください。 –

答えて

5

あなたの編集後、私はいくつかの推奨事項があります。

私はコメントで言ったように、そのような言語の文法を書くことはほとんど不可能です。少なくとも、1つのことでそうしようとしている、それはそうです。私がこの作業を見る唯一の方法は、最初の "解析段階"がwiki-sourceを非常に "粗く"解析する複数のパーサでこれを行うことです。たとえば、tableはトークン化されます。TABLE : '{|' .* '|}'とし、このテーブルを適切に解析する別のパーサーを作成します。 1つのパーサーでそれを行うと、パーサーのルールIMOにかなりのあいまい性が生じます。

HTMLコードを表示するには、これを行うための「適切な」方法は実際にはStringTemplateで行いますが、ANTLR自体が新しくなっていることを考えると、簡単なことです。パーサークラスにStringBuilder属性を作成して、ソースファイルを解析する際にすべてのHTMLコードを収集することができます。コードを{}とラップすることでANTLRルールにコードを埋め込むことができます。パーサーとレクサー生成、その文法から

grammar T; 

@parser::members { 

    // an attribute that is only available in your 
    // parser (so only in parser rules!) 
    protected StringBuilder htmlBuilder = new StringBuilder(); 
} 

// Parser rules 
parse 
    : atom+ EOF 
    ; 

atom 
    : header 
    | Any {htmlBuilder.append($Any.text);} // append the text from 'Any' token 
    ; 

header 
    : H3 h3Content H3 {htmlBuilder.append("<h3>" + $h3Content.text + "</h3>");} 
    | H2 h2Content H2 {htmlBuilder.append("<h2>" + $h2Content.text + "</h2>");} 
    | H1 h1Content H1 {htmlBuilder.append("<h1>" + $h1Content.text + "</h1>");} 
    ; 

h3Content : ~H3*; // match any token except H3, zero or more times 
h2Content : ~H2*; //  "    H2   " 
h1Content : ~H1*; //  "    H1   " 

// Lexer rules  
H3 : '==='; 
H2 : '=='; 
H1 : '='; 

// Fall through rule: if non of the above 
// lexer rules matched, this one will. 
Any 
    : . 
    ; 

java -cp antlr-3.2.jar org.antlr.Tool T.g 

をして、あなたのパーサをテストするために少しのクラスを作成します。ここでは

は、迅速なデモだ

import org.antlr.runtime.*; 

public class Main { 
    public static void main(String[] args) throws Exception { 

     // the source to be parsed 
     String source = 
       "= header 1 =    \n"+ 
       "       \n"+ 
       "some text here   \n"+ 
       "       \n"+ 
       "=== header level 3 === \n"+ 
       "       \n"+ 
       "and some more text   "; 

     ANTLRStringStream in = new ANTLRStringStream(source); 
     TLexer lexer = new TLexer(in); 
     CommonTokenStream tokens = new CommonTokenStream(lexer); 
     TParser parser = new TParser(tokens); 

     // invoke the start-rule in your parser 
     parser.parse(); 

     // print the contents of your parser's StringBuilder 
     System.out.println(parser.htmlBuilder); 
    } 
} 

すべてのソースファイルをコンパイルします。

javac -cp antlr-3.2.jar *.java 

そして最後に、あなたのメインクラスのコンソールに以下を出力します

// *nix & MacOS 
java -cp .:antlr-3.2.jar Main 

// Windows 
java -cp .;antlr-3.2.jar Main 

を実行します。

<h1> header 1 </h1>    

some text here   

<h3> header level 3 </h3> 

and some more text 

しかし、再び、あなたが解析する別の言語を選択して自由である場合に私はそれをして、この恐ろしいWikiのことを解析することを忘れてしまいます。

とにかく、あなたが何をしていても:運が最高です!

+0

ありがとう、あなたのコメントは本当に役立ちます! – Dan

+0

@ダン、どうぞよろしくお願いいたします。 –