Avaldiste süntaksi kontroll Antlar3-ga

Sisendfailis on igal real kas täisarvudega opereeriv aritmeetiline avaldis või sellise avaldise omistamine muutujale (väärtustatud muutujat võib järgnevates avaldistes juba kasutada. Sellise sisendi süntaksi võib kirjeldada näiteks grammatikaga:

 avald  yksl
 	| avald + yksl
| avald - yksl yksl tegur | yksl * tegur | RV tegur ARV |ID ARV ('0'..'9')+ ID ('a'..'z'|'A'..'Z')+ RV ('\r''\n'|'\n'|'\t')

Antlr3 jaoks tuleb see sisendit kirjeldav grammatika (koos Javas kirjeldatud semantilise tegevusega, mis väljastab süntakstiliselt korrektse avaldise puhul avaldise teksti ja selle järel - OK) esitada kujul:

grammar avald;

tokens {
	PLUS 	= '+' ;
	MINUS	= '-' ;
	MULT	= '*' ;
	DIV	= '/' ;
}

@members { /* peaprogramm ! */
    public static void main(String[] args) throws Exception {
        /*avaldLexer lex = new avaldLexer(new ANTLRFileStream(args[0]));*/
        ANTLRInputStream input = new ANTLRInputStream(System.in);
        avaldLexer lex = new avaldLexer(input);
       	CommonTokenStream tokens = new CommonTokenStream(lex);
        avaldParser parser = new avaldParser(tokens);

        try {
            parser.avald();
        } catch (RecognitionException e)  {
            e.printStackTrace();
        }
    }
}
/*------------------------------------------------------------------
 * PARSER RULES
 *------------------------------------------------------------------*/

avald	: yksl ( ( PLUS | MINUS )  yksl)* 
			{System.out.println($avald.text + " - OK");}
			;

yksl	: tegur ( ( MULT | DIV ) tegur )* ;
tegur	: ARV ;
/*------------------------------------------------------------------
 * LEXER RULES
 *------------------------------------------------------------------*/

ARV	: NUM('.'NUM)?  ;
WHITESPACE : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+ 	{ $channel = HIDDEN; } ;
fragment NUM	: ('0'..'9')+ ;

vooskeemGrammatikafail algab grammatika nimega grammar avald ja see nimi peab kokku langema faili nimega, milles grammatika salvestatakse, see ga see grammatika tuleb salvestada failis avald.g ((.g - grammar - Antlr-i tavalaiend). Kui see fail avada silumiseks programmis ANTLRWorks, saab kontrollida kogu grammatika korrektsust ("Grammar - Check Grammar"), vaadelda produktsioonide vooskeeme.


InterpretaatorVõib käivitada ka grammatika interpretaatori ja kui interpretaatorile anda mingi sisend, siis saab vaadelda sisendi analüüsiks konstrueeritud derivatsioonipuud ja selle debuggeris samm-sammult läbida.


Kui sisend (grammatika) on korrektne, võib lasta genereerida lekseri (leksikaanalüsaatori) ja parseri koodi käsuga "Generate Code" - see loob .java failid avaldLexer.java, avaldParser.java; viimane sisaldab ka käivitatava peaprotseduuri main(). Need .java failid tuleb kompileerida:
javac *.java
Loome ka testfaili, kus on näiteks selline avadis:
2+3*4
Käivitame loodud süntaksikontrolleri, andes talle sisendiks selle faili (see peab UltraEdit-is olema aktiivses aknas):
java avaldParser < %f
Tulemuseks saame
2+3*4 - OK

Ülesandeid:
1. Täienda süntaksikontrollerit:
- ridu võib olla rohkem
- real võib olla mitu avaldist, mis lõpevad märgiga ';' - selle leidmisel teatab parser, kas avaldis oli korrektne või mitte
- tegur võib olla ka sulgudes avaldis ja aste kujul tegur ^ tegur
2.
Tee Java keele deklaratsioonide süntaksi kontrolli programm; programm peab vastu võtma näit sellised deklaratsioonid
  public static int i;
  static double rarv = 3.1415;
  public boolean result = true;
  private char capitalC = 'C';

Küsimused, probleemid: ©2004 Jaak Henno