Java platformunda bir lexer oluşturmak istediğimizde elimizdeki seçenekler JavaCC, SableCC ve ANTLR olarak karşımıza çıkıyor. ANTLR ile elimizdeki dil için bir lexer oluşturmaya çalışalım.
Lexer için kullanacağımız dilin token kuralları:
Identifier: Harf ile başlar. Harf, rakam ve alt çizgilerden oluşan stringdir. Büyük haft – küçük harf farklı olarak değerlendirilir.
Integer constant: Rakamlardan oluşan string.
Binary operator: Aşağıdakilerden biri:
+ - * / &&
Yorum: İki türlü yorum olabilir:
Blok tipi yorum: /* */
Satır tipi yorum: //
ANTLR kurulumu için yapılması gerekenler:
Antlrworks'ü indir ve üzerine tıkla.
En sevdiğin kafeinli içecek de dahil olmak üzere bilgilerini göndermeyi kabul et. ;)
Yeni gramer dökümanı mı oluşturmak istiyorsun? Evet
Grammar name: MyLexer
Type: Lexer
Lexical items: Identifier, Integer, Comments (single line + multiline), Whitespace
Oluşturacağımız lexer için belirlenen kuralları ana pencerede görüyoruz:
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
;
INT : '0'..'9'+
;
Regular expressions konusu için bir önceki blog yazım incelenebilir.
http://kurumsalyazilim.blogspot.com/2011/12/regular-expressions-konusunu-tam-olarak.htmlŞimdi yapmamız gereken Generate -> Generate Code
Artık MyLexer.java dosyasını elde etmiş olduk.
MyLexer'ın nasıl çalıştığını anlamak ve debug etmek istiyorum. Lexer sınıfından türemiş ve bu sınıfın kodlarını görmek istiyorum. Maven projesi oluşturarak çalışalım.
Antlr3 maven plugin
POM dosyamızın plugins kısmına aşağıdaki tanımı ekleyelim:
<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr3-maven-plugin</artifactId>
<version>3.1.3-1</version>
<executions>
<execution>
<goals>
<goal>antlr</goal>
</goals>
</execution>
</executions>
</plugin>
Bu plugin benden default olarak, grammar dosyalarımı belli bir dizine koymamı istiyor.
Gramer dosyam MyLexer.g ve içeriği aşağıdaki gibi:
lexer grammar MyLexer;
@header {
package mylexer;
}
Burada verdiğim package yapısına göre anlr-maven plugin de /target dizini altına MyLexer.java dosyasını oluşturacak:
\target\generated-sources\antlr3\mylexer\MyLexer.java
Maven ile clean-install yaptığımda elde ettiğim MyLexer sınıfının türediği Lexer sınıfını da POM dosyasında dependency olarak tanımlamam gerekiyor:
<dependencies>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr-runtime</artifactId>
<version>3.4</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>CentralM1</id>
<url>https://repository.sonatype.org/content/shadows/centralm1/</url>
</repository>
</repositories>
Artık çalışma ortamım hazır olduğuna göre Lexer sınıfının nasıl çalıştığını gözlemleyebilirim.
public class Program {
public static void main(String[] args) {
String sourceCode = "int a 5 foo /* comment */ \r\n // other comment \r\n ";
ANTLRStringStream source = new ANTLRStringStream(sourceCode);
MyLexer myLexer = new MyLexer(source);
Token token;
while ((token = myLexer.nextToken()).getType() != Token.EOF) {
System.out.println(token.getText());
}
}
}
Comments