2013-12-12 18 views
5

próbuję skonstruować tłumacza, który może konwertować kod PL/SQL, Java z wykorzystaniem antlr 4 i StringTemplate 4. Mam gramatyki PL/SQL i mieć już zbudować parser dla PL/SQL, ale nie mam pojęcia jak dalej podejść do problemu. znalazłem wiele artykułów tłumaczy używając ANTLR i StringTemplate ale wszystkie one używać ANTLR 3 lub ANTLR 2. Czy jest jakakolwiek różnica, gdy Antlr 4 tłumaczy się wraz z Stringtemplate jako parserem dla PL/SQL, gdy Antlr 4 miał pewne różnice niż Antlr3Tłumaczenie kodu PL/SQL do Java z wykorzystaniem antlr 4 i StringTemplate 4

Jestem całkowicie nowy w tłumaczeniu języka programowania i nie wiem, czy jest jakiś lepszy sposób podejścia do problemu.

+0

Możesz podać przykład, na przykład fragment gramatyki/szablonu, który działa z antlr2/3, ale nie z antlr4? Czy używasz parsego porcelli, czy też sam piszesz? –

+0

Główna różnica między gramatyką ANTLR3 i ANTLR 4 'polega na usunięciu predykatów składniowych. Patrz: http://stackoverflow.com/questions/18431158/syntactic-predicates-upgrading-from-antlr-3-to-antlr-4. Nie, napisałem własny parser, Ref: https://github.com/developeron29/Antlr-4-PLSQL-Parser---AST-Generator/ –

+0

czy użyłeś istniejącego pliku gramatycznego kompatybilnego z v4? Jeśli tak, możesz udostępnić link –

Odpowiedz

10

ANTLR przed v4 miał wewnętrzną obsługę StringTemplate (można określić, że gramatyka jest wyjście ST). Począwszy od wersji 4, to wsparcie wydaje się być porzucone.
Jedną z opcji jest użycie interfejsów odbiornika lub użytkownika do ręcznego tworzenia szablonów. Gość jest prawdopodobnie bardziej przydatny w tym kontekście.
Inną opcją, którą obecnie badam, jest przypisanie parametru ParseTree (wynik z analizy) jako parametru do szablonu. Używam niestandardowej ModelAdapter dla ParserRuleContext więc mogę przejść podrzędne konteksty z szablonów.

Przykład: Zakładam, że używasz gramatyki dla PL/SQL. Wtedy można mieć grupę szablonu takiego:

plsql_block(block) ::= <<{ 
    <declarations(block.declare_section)> 
    <body(block.body)> 
}>> 

declarations(ds)  ::= "<ds.item_declaration:itemDecl()>" 
itemDecl(id)   ::= "<id.variable_declaration:varDecl()>" 
varDecl(vd)   ::= "<vd.datatype.text> <vd.ID>;" 

body(b)    ::= "<b.text>" 

będzie też trzeba ModelAdapter dla ParserRuleContext (to tylko przykład jedynej metody w nim):

@Override 
public Object getProperty(Interpreter interpreter, ST seld, Object o, Object property, String propertyName) throws STNoSuchPropertyException 
{ 
    Method m = null; 
    try { 
     String mn = "get" + Character.toUpperCase(propertyName.charAt(0)) + propertyName.substring(1); 
     m = o.getClass().getMethod(mn); 
    } catch (Exception e) { 
    } 
    if (m == null) 
     try { 
      m = o.getClass().getDeclaredMethod(propertyName); 
     } catch (Exception e) { 
     } 

    if (m != null) try { 
     return m.invoke(o); 
    } catch (Exception e) { 
     throw new STNoSuchPropertyException(e, property, propertyName); 
    } 
    else 
     throw new STNoSuchPropertyException(null, property, propertyName); 
} 

Teraz może wykonać następujące czynności:

ANTLRInputStream input = new ANTLRInputStream(new FileInputStream("block_test.sql")); 
PLSQLLexer lexer = new PLSQLLexer(input); 
CommonTokenStream tokens = new CommonTokenStream(lexer); 
PLSQLParser parser = new PLSQLParser(tokens); 
parser.setBuildParseTree(true); 
ParseTree tree = parser.plsql_block(); 

STGroupFile stg = new STGroupFile("test.stg"); 
stg.registerModelAdaptor(ParserRuleContext.class, new ContextModelAdapter()); 
ST t = stg.getInstanceOf("plsql_block"); 
t.add("block", tree); 
System.out.println(t.render()); 

Mam nadzieję, że to pomoże!

+0

Czy możesz podać przykład użycia Listenera lub interfejsu użytkownika lub użycia z ParseTree ? –

+0

Dzięki! Jesteś niesamowity! –

+1

Co zdumiewające odpowiedź! Nie udało się zdobyć wystarczającej ilości głosów. Przestałem używać odbiornika do mojego zadania i przerzuciłem się na to. Zauważyłem, że metody słuchacza w końcu są byciem proxy do ST. Jakieś inne wskazówki, które możesz podać na temat tego podejścia Marin? Dzięki jeszcze raz. – Core