We presentake kanggo manungsa waé terjemahan saka pandhuan singkat kanggo ungkapan biasa ing Jawa, ditulis dening Jeff Friesen kanggo website javaworld. Kanggo gampang maca, kita wis dibagi artikel dadi sawetara bagean. Bagian iki minangka sing pungkasan. Ungkapan Reguler ing Basa Jawa, Perangan 1 Ungkapan Reguler ing Basa Jawa, Bagian 2 Ungkapan Reguler ing Basa Jawa, Bagian 3 Ungkapan Reguler ing Basa Jawa, Bagian 4
Ekspresi reguler luwih efisien tinimbang analisa leksikal adhedhasar negara, sing kudu ditulis nganggo tangan lan umume ora bisa digunakake maneh. Conto penganalisa leksikal adhedhasar ekspresi reguler yaiku JLex , generator leksikal kanggo basa Jawa sing nggunakake ekspresi reguler kanggo nemtokake aturan kanggo ngilangi aliran data input dadi token. Conto liyane yaiku Lexan.
Nggunakake ekspresi reguler kanggo analisis leksikal
Aplikasi ekspresi reguler sing luwih migunani yaiku perpustakaan kode sing bisa digunakake maneh kanggo nindakake analisis leksikal, komponen kunci saka kompiler utawa assembler. Ing kasus iki, stream input karakter diklompokaké dadi stream output token - jeneng kanggo urutan karakter sing duwe makna umum. Contone, sawise kesandhung marang urutan karakterc
, o
, u
, n
, t
, e
, r
, ing stream input, analyzer leksikal bisa output token ID
(identifier). Urutan karakter sing cocog karo token kasebut diarani leksem.
Liyane babagan panandha lan leksem |
---|
Token kayata ID bisa cocog karo akeh urutan karakter. Ing kasus token kasebut, token nyata sing cocog karo token uga dibutuhake dening compiler, assembler, utawa sarana liyane sing mbutuhake analisis leksikal. Kanggo token sing makili siji urutan karakter tartamtu, kayata token PLUS sing mung cocog karo karakter kasebut + , token sing nyata ora dibutuhake amarga bisa ditemtokake kanthi [unik] dening token kasebut. |
Ngerti Lexan
Lexan minangka perpustakaan Jawa sing bisa digunakake maneh kanggo analisis leksikal. Iki adhedhasar kode saka seri kirim blog Nulis Parser ing Jawa ing situs web Cogito Learning . Pustaka kasebut kalebu kelas ing ngisor iki, sing ana ing paketca.javajeff.lexan
sing kalebu ing kode sing bisa didownload kanggo artikel iki:
Lexan
: penganalisis leksikal;LexException
: pangecualian dibuwang yen sintaksis sing salah dideteksi sajrone analisis leksikal;Token
: jeneng kanthi atribut ekspresi reguler;TokLex
: pasangan token/token.
LexanException
: istiméwa di buwang ing konstruktor kelasLexan;
Lexan(java.lang.Class tokensClass)
nggawe analisa leksikal anyar. Mbutuhake siji argumen ing wangun obyek kelas java.lang.Class
sing cocog karo tipe konstan kelas static Token
. Nggunakake API Refleksi, konstruktor maca kabeh konstanta Token
dadi sawetara nilai Token[]
. Yen Token
ora ana konstanta, pangecualian dibuwang LexanException
. Kelas kasebut Lexan
uga nyedhiyakake rong cara ing ngisor iki:
- Cara ngasilake dhaptar lexer iki;
List
getTokLexes() Token
Метод void lex(String str)
nindakake analisis leksikal saka string input [kanthi asil diselehake] menyang dhaptar nilai jinisTokLex
. Yen ditemoni karakter sing ora cocog karo pola arrayToken[]
, pangecualian bakal dibuwangLexException
.
LexanException
ora duwe metode; nggunakake metode sing diwarisake kanggo ngasilake pesen pangecualian getMessage()
. Ing kontras, kelas LexException
nyedhiyakake metode ing ngisor iki:
- Cara kasebut
int getBadCharIndex()
ngasilake posisi karakter sing ora cocog karo pola panandha. - Cara kasebut
String getText()
ngasilake teks sing dianalisis nalika pangecualian digawe.
Token
overrides cara toString()
kanggo bali jeneng panandha. Iki uga menehi cara String getPattern()
sing ngasilake atribut ekspresi reguler token. Kelas kasebut TokLex
nyedhiyakake metode Token getToken()
sing ngasilake token. Iki uga menehi cara String getLexeme()
sing ngasilake token.
Demonstrasi perpustakaan Lexan
Kanggo nduduhake cara kerja perpustakaan,Lexan
aku nulis aplikasi LexanDemo
. Iku kasusun saka kelas LexanDemo
, BinTokens
, MathTokens
lan NoTokens
. Kode sumber kanggo aplikasi LexanDemo
ditampilake ing Listing 2. Listing 2. Demonstrasi perpustakaan Lexan ing tumindak
import ca.javajeff.lexan.Lexan;
import ca.javajeff.lexan.LexanException;
import ca.javajeff.lexan.LexException;
import ca.javajeff.lexan.TokLex;
public final class LexanDemo
{
public static void main(String[] args)
{
lex(MathTokens.class, " sin(x) * (1 + var_12) ");
lex(BinTokens.class, " 1 0 1 0 1");
lex(BinTokens.class, "110");
lex(BinTokens.class, "1 20");
lex(NoTokens.class, "");
}
private static void lex(Class tokensClass, String text)
{
try
{
Lexan lexan = new Lexan(tokensClass);
lexan.lex(text);
for (TokLex tokLex: lexan.getTokLexes())
System.out.printf("%s: %s%n", tokLex.getToken(),
tokLex.getLexeme());
}
catch (LexanException le)
{
System.err.println(le.getMessage());
}
catch (LexException le)
{
System.err.println(le.getText());
for (int i = 0; i < le.getBadCharIndex(); i++)
System.err.print("-");
System.err.println("^");
System.err.println(le.getMessage());
}
System.out.println();
}
}
Cara main()
ing Listing 2 nyebutake sarana lex()
kanggo nduduhake analisis leksikal nggunakake Lexan. Saben telpon kanggo cara iki liwati kelas token ing obyek Class
lan senar kanggo parse. Cara lex()
pisanan nggawe obyek kelas Lexan
kanthi menehi obyek kasebut Class
menyang konstruktor kelas Lexan
. Lan banjur nelpon metode lex()
kelas Lexan
ing senar kasebut. Yen analisis leksikal sukses, metode kelas TokLex
diarani ngasilake dhaptar obyek . Kanggo saben obyek kasebut, metode kelas kasebut diarani ngasilake token lan metode kelas kanggo ngasilake token. Nilai loro kasebut dicithak menyang output standar. Yen analisis leksikal gagal, salah siji saka pangecualian utawa dibuwang lan ditangani sakcukupe . Kanggo ringkesan, ayo nimbang mung kelas sing nggawe aplikasi iki . Listing 3 nuduhake kode sumber. Listing 3. Katrangan saka set token kanggo basa matematika cilikgetTokLexes()
Lexan
getToken()
TokLex
getLexeme()
LexanException
LexException
MathTokens
import ca.javajeff.lexan.Token;
public final class MathTokens
{
public final static Token FUNC = new Token("FUNC", "sin|cos|exp|ln|sqrt");
public final static Token LPAREN = new Token("LPAREN", "\\(");
public final static Token RPAREN = new Token("RPAREN", "\\)");
public final static Token PLUSMIN = new Token("PLUSMIN", "[+-]");
public final static Token TIMESDIV = new Token("TIMESDIV", "[*/]");
public final static Token CARET = new Token("CARET", "\\^");
public final static Token INTEGER = new Token("INTEGER", "[0-9]+");
public final static Token ID = new Token("ID", "[a-zA-Z][a-zA-Z0-9_]*");
}
Listing 3 nuduhake yen kelas MathTokens
nggambarake urutan jinis konstanta Token
. Saben wong diwenehi nilai obyek Token
. Konstruktor kanggo obyek iki nampa senar sing jeneng panandha, bebarengan karo expression biasa sing njlèntrèhaké kabeh strings karakter sing digandhengake karo panandha. Kanggo gamblang, iku seng di pengeni sing jeneng string saka panandha padha karo jeneng pancet, nanging iki ora dibutuhake. Posisi konstanta Token
ing dhaptar tandha penting. Konstanta sing luwih dhuwur ing dhaptar Token
luwih diutamakake tinimbang sing ana ing ngisor iki. Contone, nalika ketemu sin
, Lexan milih token FUNC
tinimbang ID
. Yen token ID
wis ndhisiki token FUNC
, mesthi wis dipilih.
Nglumpukake lan mbukak aplikasi LexanDemo
Kode sing bisa didownload kanggo artikel iki kalebu arsiplexan.zip
sing ngemot kabeh file distribusi Lexan. Bukak arsip iki lan pindhah menyang subdirektori demos
direktori root lexan
. Yen sampeyan nggunakake Windows, jalanake printah ing ngisor iki kanggo ngumpulake file kode sumber aplikasi demo:
javac -cp ..\library\lexan.jar *.java
Yen kompilasi sukses, jalanake perintah ing ngisor iki kanggo mbukak aplikasi demo:
java -cp ..\library\lexan.jar;. LexanDemo
Sampeyan kudu ndeleng asil ing ngisor iki:
FUNC: sin
LPAREN: (
ID: x
RPAREN: )
TIMESDIV: *
LPAREN: (
INTEGER: 1
PLUSMIN: +
ID: var_12
RPAREN: )
ONE: 1
ZERO: 0
ONE: 1
ZERO: 0
ONE: 1
ONE: 1
ONE: 1
ZERO: 0
1 20
--^
Неожиданный символ во входном тексте: 20
Pesen kasebut Неожиданный символ во входном тексте: 20
kedadeyan minangka akibat saka pangecualian sing dibuwang LexanException
amarga kasunyatane kelas kasebut BinTokens
ora nyatakake konstanta Token
kanthi nilai 2
minangka ekspresi reguler. Elinga yen pawang pangecualian ngasilake posisi karakter sing ora cocog sing dipikolehi saka analisis leksikal teks kasebut. Pesen sing ora ana token minangka akibat saka pengecualian sing dibuwang LexException
amarga NoTokens
ora ana konstanta sing diumumake ing kelas kasebut Token
.
Neng mburi layar
Lexan
nggunakake kelas Lexan minangka mesin. Deleng ing implementasine saka kelas iki ing Listing 4 lan cathetan kontribusi saka ekspresi reguler kanggo nggawe mesin bisa digunakake maneh. Listing 4. Nggawe arsitektur analyzer leksikal adhedhasar ekspresi reguler
package ca.javajeff.lexan;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
/**
* Лексический анализатор. Этот класс можно использовать для
* преобразования входного потока символов в выходной поток маркеров.
*
* @Author Джефф Фризен
*/
public final class Lexan
{
private List tokLexes;
private Token[] values;
/**
* Инициализируем лексический анализатор набором an objectов Token.
*
* @параметры tokensClass – an object Class класса, содержащего
* набор an objectов Token
*
* @генерирует исключение LexanException в случае невозможности
* формирования an object Lexan, возможно, из-за отсутствия an objectов
* Token в классе
*/
public Lexan(Class tokensClass) throws LexanException
{
try
{
tokLexes = new ArrayList<>();
List _values = new ArrayList<>();
Field[] fields = tokensClass.getDeclaredFields();
for (Field field: fields)
if (field.getType().getName().equals("ca.javajeff.lexan.Token"))
_values.add((Token) field.get(null));
values = _values.toArray(new Token[0]);
if (values.length == 0)
throw new LexanException("маркеры отсутствуют");
}
catch (IllegalAccessException iae)
{
throw new LexanException(iae.getMessage());
}
/**
* Получаем список TokLex'ов этого лексического анализатора.
*
* @возвращает список TokLex'ов
*/
public List getTokLexes()
{
return tokLexes;
}
/** * Выполняет лексический анализ входной строки [с помещением * результата] в список TokLex'ов. * * @параметры str – строка, подвергаемая лексическому анализу * * @генерирует исключение LexException: во входных данных обнаружен * неожиданный символ */
public void lex(String str) throws LexException
{
String s = new String(str).trim(); // удалить ведущие пробелы
int index = (str.length() - s.length());
tokLexes.clear();
while (!s.equals(""))
{
boolean match = false;
for (int i = 0; i < values.length; i++)
{
Token token = values[i];
Matcher m = token.getPattern().matcher(s);
if (m.find())
{
match = true;
tokLexes.add(new TokLex(token, m.group().trim()));
String t = s;
s = m.replaceFirst("").trim(); // удалить ведущие пробелы
index += (t.length() - s.length());
break;
}
}
if (!match)
throw new LexException("Неожиданный символ во входном тексте: "
+ s, str, index);
}
}
}
Kode metode lex()
adhedhasar kode sing kasedhiya ing postingan blog "Writing a Parser in Java: A Token Generator" ing situs web Cogito Learning. Waca kirim iki kanggo mangerteni sing luwih lengkap babagan carane Lexan nggunakake Regex API kanggo ngumpulake kode.
Kesimpulan
Ekspresi reguler minangka alat sing migunani sing bisa migunani kanggo pangembang apa wae. Regex API saka basa pamrograman Java ndadekake gampang digunakake ing aplikasi lan perpustakaan. Saiki sampeyan wis duwe pangerten dhasar babagan ekspresi reguler lan API iki, deleng dokumentasi SDKjava.util.regex
kanggo sinau luwih lengkap babagan ekspresi reguler lan metode API Regex tambahan.
GO TO FULL VERSION