Question

Je suis en train de chair un traducteur wikitext-to-HTML dans ANTLR 3, mais je continue à me coincer.

Connaissez-vous un exemple que je peux vérifier? J'ai essayé la grammaire ANTLR MediaWiki et la grammaire Wiki créole, mais je ne peux pas les amener à générer le lexer et parser dans ANTLR 3.

Voici les liens à deux que j'ai essayé grammaires en utilisant:

Je ne peux pas obtenir l'un de ces deux pour générer mon Java et Parser Lexer. (J'utilise antlr3 comme plug-in Eclipse). MediaWiki prend un temps très longue à construire puis à un moment donné, il jette une exception OutOfMemory. L'autre a des erreurs dans ce que je ne sais pas comment le débogage.

EDIT: Ok j'ai un très basique grammaire:

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';

On ne sait pas pour moi bien comment on pourrait s'y prendre pour délivrer en sortie HTML. Je cherchais dans StringTemplate, mais je ne comprends pas comment structurer mes modèles. Plus précisément, quel modèle va où dans la grammaire. Pouvez-vous me aider avec un court exemple?

Était-ce utile?

La solution

D'accord, après votre EDIT, j'ai quelques recommandations.

Comme je l'ai dit dans les commentaires, écrire une grammaire pour la langue d'une telle est presque impossible. Au moins, en essayant de le faire en une seule fois, ce qui est. La seule façon que je vois ce travail serait de le faire avec plusieurs parseurs où le premier « analyse syntaxique étape » serait d'analyser le wiki source très « grossièrement ». Par exemple: un table serait tokenisé comme: TABLE : '{|' .* '|}' et alors vous créer un autre analyseur qui analyse ce tableau correctement. Le faire dans un analyseur entraînera tout à fait quelques ambiguïtés dans votre analyseur règles de l'OMI.

A propos émission de code HTML, la « bonne » façon de le faire est en effet avec StringTemplate, mais compte tenu du fait que vous êtes assez nouveau pour ANTLR lui-même, je garde les choses simples de. Vous pouvez créer un attribut StringBuilder dans votre classe d'analyseur qui rassemblerait tout votre code HTML que vous analysez votre fichier source. Vous pouvez intégrer le code dans les règles ANTLR en l'enveloppant avec { et }.

Voici une démonstration rapide:

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
  :  .
  ;

A partir de cette grammaire, vous générez un analyseur et lexer:

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

et puis créer une petite classe pour tester votre analyseur:

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);
    }
}

puis compiler tous vos fichiers source:

javac -cp antlr-3.2.jar *.java

et enfin, exécutez votre classe principale

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

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

qui imprimera les éléments suivants à la console:

<h1> header 1 </h1>             

some text here           

<h3> header level 3 </h3>   

and some more text  

Mais, encore une fois, si vous êtes libre de choisir une autre langue pour analyser, je le ferais et oublier cette horrible analyse Wiki-chose.

Quoi qu'il en soit, quoi que vous fassiez: bonne chance

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top