Jeff Frieseniň javaworld web sahypasy üçin ýazan Java-da yzygiderli aňlatmalar üçin gysga gollanmanyň terjimesini size hödürleýäris. Okamagyň aňsatlygy üçin makalany birnäçe bölege böldük. Bu bölüm iň soňky bölüm. Java-da yzygiderli aňlatmalar, 1-nji bölüm Java-da yzygiderli aňlatmalar, 2-nji bölüm Java-da yzygiderli aňlatmalar, 3-nji bölüm Java-da yzygiderli aňlatmalar, 4-nji bölüm
Yzygiderli aňlatmalar , el bilen ýazylan we umuman ulanyp bolmaýan döwlet esasly leksiki analizatorlardan has täsirli. Yzygiderli aňlatma esasly leksiki analizatoryň mysaly , Java diliniň leksiki generatory, giriş maglumat akymyny belliklere bölmek düzgünlerini kesgitlemek üçin yzygiderli aňlatmalary ulanýan JLex . Başga bir mysal Lexan.
Leksiki derňew üçin yzygiderli aňlatmalary ulanmak
Yzygiderli aňlatmalaryň has peýdaly ulanylyşy, islendik düzüjiniň ýa-da ýygnaýjynyň esasy bölegi bolan leksiki derňewi geçirmek üçin gaýtadan ulanylýan koduň kitaphanasydyr. Bu ýagdaýda nyşanlaryň giriş akymy bellikleriň çykyş akymyna - umumy manysy bolan nyşanlaryň yzygiderliligi üçin atlara bölünýär. Mysal üçin , giriş akymynda ,,,,,, belgileriň yzygiderliligine duş gelende, leksiki analizator birc
belgi ( kesgitleýji ) o
çykaryp biler . Nyşana gabat gelýän nyşanlaryň yzygiderliligine leksema diýilýär. u
n
t
e
r
ID
Markerler we leksemalar hakda has giňişleýin |
---|
ID ýaly belgiler köp nyşan yzygiderliligine gabat gelip biler. Şeýle bellikler ýüze çykan halatynda, bellige gabat gelýän hakyky belgi düzüjisi, ýygnaýjy ýa-da leksiki derňewi talap edýän beýleki kömekçi enjam hem zerur. PLUS Nyşanlaryň belli bir yzygiderliligini görkezýän bellikler üçin, diňe nyşana gabat gelýän belgi ýaly + , bellikden kesgitlenip bilinýänligi üçin hakyky belgi talap edilmeýär. |
Lexan bilen tanyşmak
“Lexan” leksiki derňew üçin gaýtadan ulanylýan Java kitaphanasydyr. Blog ýazgy seriýasyndaky kodlara esaslanýar, Cogito Learning web sahypasynda Java-da Parser ýazmak . Kitaphana şu makala üçin göçürip alyp bolýan kody öz içine alýan aşakdaky sapaklardan ybarat :ca.javajeff.lexan
Lexan
: leksiki analizator;LexException
: leksiki derňew wagtynda nädogry sintaksis ýüze çykarylsa kadadan çykma;Token
: yzygiderli aňlatma atributy bolan at;TokLex
: nyşan / bellik jübüti.
LexanException
: synp konstruktoryna atylan kadadan çykmaLexan;
Lexan(java.lang.Class tokensClass)
täze leksiki analizator döredýär. java.lang.Class
Hemişelik synpa laýyk gelýän synp obýekti görnüşinde bir argument talap edýär static Token
. “Reflection API” -ni ulanyp, konstruktor ähli yzygiderliligi Token
gymmatlyklar toplumyna okaýar Token[]
. Dowamlylyk ýok bolsa Token
, kadadan çykma atylýar LexanException
. Şeýle hem synp Lexan
aşakdaky iki usuly hödürleýär:
- Usul bu lekseriň sanawyny görkezýär ;
List
getTokLexes() Token
Метод void lex(String str)
görnüşiň bahalarynyň sanawyna girizilen setiriň leksiki derňewini ýerine ýetirýärTokLex
. Eger massiw nagyşlarynyň hiç birine gabat gelmeýän bir nyşan ýüze çyksaToken[]
, kadadan çykma bolýarLexException
.
LexanException
hiç hili usul ýok, kadadan çykma habaryny yzyna gaýtarmak üçin miras galan usuly ulanýar getMessage()
. Munuň tersine, synp LexException
aşakdaky usullary hödürleýär:
- Usul,
int getBadCharIndex()
marker nagyşlarynyň hiç birine gabat gelmeýän nyşanlaryň ýagdaýyny görkezýär. - Usul,
String getText()
kadadan çykma ýüze çykanda seljerilen teksti yzyna berýär.
Token
usulyny ýok edýär . Şeýle hem , belligiň yzygiderli aňlatma häsiýetini yzyna gaýtarýan toString()
usul bilen üpjün edýär . String getPattern()
Synp öz nyşanyny yzyna gaýtaryp berýän TokLex
usul bilen üpjün edýär . Şeýle hem belligini yzyna gaýtarýan Token getToken()
usul bilen üpjün edýär .String getLexeme()
“Lexan” kitaphanasynyň görkezilmegi
Kitaphananyň nähili işleýändigini görkezmek üçinLexan
bir programma ýazdym LexanDemo
. Sapaklardan we . LexanDemo
_ _ Programmanyň deslapky kody Sanawda 2. Sanawda görkezilýär . 2. Lexan kitaphanasynyň hereketde görkezilmegiBinTokens
MathTokens
NoTokens
LexanDemo
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();
}
}
main()
2-nji sanawdaky usul, lex()
“Lexan” -y ulanyp leksiki derňewi görkezmek üçin peýdaly bir zat diýýär. Bu usula edilen her bir jaň, obýektdäki bellikleriň synpyny Class
we derňemek üçin setirden geçýär. Usul lex()
ilki bilen obýekti synp konstruktoryna Lexan
geçirip, synpyň obýektini döredýär . Soň bolsa şol setirde synp usuly diýilýär . Leksiki derňew üstünlikli bolsa, obýektleriň sanawyny yzyna gaýtarmak üçin synp usuly çagyrylýar . Bu obýektleriň her biri üçin nyşany yzyna gaýtarmak üçin synp usuly we nyşany yzyna gaýtarmak üçin synp usuly diýilýär. Iki baha hem adaty çykyşda çap edilýär. Leksiki derňew şowsuz bolsa, kadadan çykmalardan biri ýa-da şoňa görä zyňylýar we işlenýär . Gysga wagtlyk üçin, diňe bu programmany düzýän synpy gözden geçireliň . 3-nji sanawda onuň deslapky kody görkezilýär. Sanaw 3. Kiçijik matematiki dil üçin bellikler toplumynyň beýanyClass
Lexan
lex()
Lexan
TokLex
getTokLexes()
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_]*");
}
3-nji sanawda synpyň MathTokens
görnüşleriň yzygiderliligini beýan edýändigi görkezilýär Token
. Olaryň hersine bir obýektiň bahasy berilýär Token
. Bu obýekt üçin konstruktor, marker bilen baglanyşykly ähli nyşan setirlerini suratlandyrýan yzygiderli aňlatma bilen birlikde markeriň ady bolan bir setir alýar. Has düşnükli bolmak üçin markeriň setir adynyň hemişelik ady bilen birmeňzeş bolmagy islenýär, ýöne bu hökmany däl. Markerleriň sanawynda hemişelik orny möhümdir. Token
Sanawda has ýokary ýerleşýän yzygiderlilik Token
aşakda ýerleşýänlerden has möhümdir. Mysal üçin, duşanda , Lexan ýerine sin
belligi saýlaýar . Marker markerden öň bolan bolsa , saýlanardy. FUNC
ID
ID
FUNC
“LexanDemo” programmasyny düzmek we işletmek
lexan.zip
Bu makala üçin göçürip alyp bolýan kod , “Lexan” paýlanyşynyň ähli faýllaryny öz içine alýan arhiwi öz içine alýar . demos
Bu arhiwi açyň we kök katalogynyň kiçi bukjasyna geçiň lexan
. Windows ulanýan bolsaňyz, demo programma çeşmesiniň kod faýllaryny düzmek üçin aşakdaky buýrugy işlediň:
javac -cp ..\library\lexan.jar *.java
Eger düzmek üstünlikli bolsa, demo programmasyny işletmek üçin aşakdaky buýrugy işlediň:
java -cp ..\library\lexan.jar;. LexanDemo
Aşakdaky netijeleri görmeli:
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
Habar, synpyň adaty aňlatma hökmünde gymmaty bilen hemişelik yglan etmeýändigi sebäpli Неожиданный символ во входном тексте: 20
kadadan çykma netijesinde ýüze çykýar . Kadadan çykaryjy tekstiň leksiki derňewinden alnan ýerliksiz nyşanlaryň ýagdaýyny çykarýar. Missingitirilen bellikler, synpda hiç hili yzygiderlilik yglan edilmändigi sebäpli kadadan çykmagyň netijesidir . LexanException
BinTokens
Token
2
LexException
NoTokens
Token
Sahnanyň arkasynda
Lexan
hereketlendirijisi hökmünde “Lexan” synpyny ulanýar. 4-nji sanawda bu synpyň ýerine ýetirilişine göz aýlaň we motoryň gaýtadan ulanylmagy üçin yzygiderli sözlemleriň goşandyna üns beriň. Sanaw 4. Adaty sözlemlere esaslanýan leksik analizator arhitekturasyny döretmek
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);
}
}
}
Usul kody, Cogito Okuw web sahypasyndaky "Java-da Parser ýazmak: Token Generator"lex()
blog ýazgysynda berlen koda esaslanýar . “Lexan” -yň kod düzmek üçin “Regex API” -ni nähili ulanýandygy barada has giňişleýin öwrenmek üçin bu ýazgyny okaň.
Netije
Yzygiderli aňlatmalar, islendik dörediji üçin peýdaly bolup biljek peýdaly guraldyr. Java programmirleme diliniň Regex API programmalarynda we kitaphanalarda ulanmagy aňsatlaşdyrýar. Indi yzygiderli aňlatmalar we bu API barada esasy düşünjäňiz bar bolsa, yzygiderli aňlatmalar we goşmaça Regex API usullary barada has giňişleýin öwrenmek üçin SDK resminamalaryna göz aýlaňjava.util.regex
.
GO TO FULL VERSION