JavaRush /Java Blog /Random-TK /Java-da yzygiderli aňlatmalar, 5-nji bölüm

Java-da yzygiderli aňlatmalar, 5-nji bölüm

Toparda çap edildi
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, 5-nji bölümJava-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

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 bir cbelgi ( kesgitleýji ) oçykaryp biler . Nyşana gabat gelýän nyşanlaryň yzygiderliligine leksema diýilýär. unterID
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. PLUSNyş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.
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.

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;
  • LexanException: synp konstruktoryna atylan kadadan çykmaLexan;
  • 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.
Konstruktor Lexan(java.lang.Class tokensClass)täze leksiki analizator döredýär. java.lang.ClassHemiş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 Tokengymmatlyklar toplumyna okaýar Token[]. Dowamlylyk ýok bolsa Token, kadadan çykma atylýar LexanException. Java-da yzygiderli aňlatmalar, 5-nji bölümŞeýle hem synp Lexanaş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ýär TokLex. Eger massiw nagyşlarynyň hiç birine gabat gelmeýän bir nyşan ýüze çyksa Token[], kadadan çykma bolýar LexException.
Synpda LexanExceptionhiç hili usul ýok, kadadan çykma habaryny yzyna gaýtarmak üçin miras galan usuly ulanýar getMessage(). Munuň tersine, synp LexExceptionaş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.
Synp markeriň adyny yzyna gaýtarmak Tokenusulyny ý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 TokLexusul 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 üçin Lexanbir programma ýazdym LexanDemo. Sapaklardan we . LexanDemo_ _ Programmanyň deslapky kody Sanawda 2. Sanawda görkezilýär . 2. Lexan kitaphanasynyň hereketde görkezilmegiBinTokensMathTokensNoTokensLexanDemo
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 Classwe derňemek üçin setirden geçýär. Usul lex()ilki bilen obýekti synp konstruktoryna Lexangeç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ýanyClassLexanlex()LexanTokLexgetTokLexes()LexangetToken()TokLexgetLexeme()LexanExceptionLexExceptionMathTokens
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ň MathTokensgö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 Java-da yzygiderli aňlatmalar, 5 - 3 bölümhemişelik orny möhümdir. TokenSanawda has ýokary ýerleşýän yzygiderlilik Tokenaşakda ýerleşýänlerden has möhümdir. Mysal üçin, duşanda , Lexan ýerine sinbelligi saýlaýar . Marker markerden öň bolan bolsa , saýlanardy. FUNCIDIDFUNC

“LexanDemo” programmasyny düzmek we işletmek

lexan.zipBu 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 . demosBu 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 Неожиданный символ во входном тексте: 20kadadan ç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 . LexanExceptionBinTokensToken2LexExceptionNoTokensToken

Sahnanyň arkasynda

Lexanhereketlendirijisi 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ň. Java-da yzygiderli aňlatmalar, 5 - 4 bölüm

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.
Teswirler
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION