الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

split decleartion into token using java

بدأه FAZ في 28 أكتوبر 2013 · 6 رد · 694 مشاهدة · في JavaSE
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

 السلام عليكم ورحمه الله وبركاته ..

 

لوسمحتوا اريد مساعدتكم  وسأرفق لكم محاولتي ...

 

المطلوب انه لما المستخدم يخل بيانات يقوم البرنامج بفصل كل شي بمفرده ويخبر المستخدم اسمه مثلا"

 

 

المستخدم ادخل "  int a,y;

البرنامج لازم يظهر للمستخدم التالي :

 

int is a keyword

a is an identifier

, is separator

y is identifier

; is terminator

 

 يعني البرناامج يقووم بعمل lexical analyzer

 

اانتظر ردودكم وربي يوووفق الجميع

 

وهنا محاولتي .... تحيااتي

 

 

 import java.util.Scanner;public class lexical{   public static int i,c;  public static String exp;  public static final String id =  "[a-z A-Z][a-z A-Z | 0-9]*";    public static void main(String args[]){ Scanner s=new Scanner(System.in);    String[] key={"int","double","String","float"};    String[] operator={"+","-","*","/","="};    String[] comma={","};    String[] terminator={";"};   System.out.print("Enter decleration : "); exp=s.nextLine();        String[] array=exp.split(" ");           for(i=0;i<array.length;i++)      {        //for keyword        for(c=0;c<key.length;c++)       { if(array.contains(key[c]))             { System.out.println(key[c] +" is a keyword");  }             }             //for operator       for(c=0;c<operator.length;c++)       {         if(array.contains(operator[c]))               { System.out.println(operator[c] +" is an operator"); }             }             //for identifier       if(array.matches(id))        { System.out.println(array+" is an identifier"); }                //for comma       for(c=0;c<comma.length;c++)      { if(array.contains(comma[c]))        { System.out.println(comma[c]+" is a comma"); }        }                       //for terminator       for(c=0;c<terminator.length;c++)      { if(array.contains(terminator[c]))        { System.out.println(terminator[c]+" is a terminator"); }       }             }      }}

تم تعديل هذه المشاركة بواسطة FAZ في 28 أكتوبر 2013 في 22:23

#2

لوسمحتــوا ارجوا الرد اللي يعرف ...

#3

اكتبي الكود بشكل منظم حتى نستطيع تعديله بشكل سريع, أعتقد أن هذا هو أقل شيء يمكن أن تساعدينا به ! :)

#4

import java.util.Scanner;

public class lexical

{

public static int i,c;

public static String exp;

public static final String id = "[a-z A-Z][a-z A-Z | 0-9]*";

public static void main(String args[])

{

Scanner s=new Scanner(System.in);

String[] key={"int","double","String","float"};

String[] operator={"+","-","*","/","="};

String[] comma={","};

String[] terminator={";"};

System.out.print("Enter decleration : ");

exp=s.nextLine();

String[] array=exp.split(" ");

for(i=0;i<array.length;i++)

{

//for keyword

for(c=0;c<key.length;c++)

{ if(array.contains(key[c]))

{ System.out.println(key[c] +" is a keyword"); }

}

//for operator

for(c=0;c<operator.length;c++)

if(array.contains(operator[c]))

{

{ System.out.println(operator[c] +" is an operator"); }}

//for identifier

if(array.matches(id))

{ System.out.println(array+" is an identifier"); }

//for comma

for(c=0;c<comma.length;c++)

if(array.contains(comma[c]))

{ System.out.println(comma[c]+" is a comma"); }

//for terminator

for(c=0;c<terminator.length;c++)

if(array.contains(terminator[c]))

{ System.out.println(terminator[c]+" is a terminator"); }

}

}

}

#5

الكود بعد التصحيح :

import java.util.Scanner;import java.util.StringTokenizer;public class Lexical {    public static final String id = "[a-z A-Z][a-z A-Z | 0-9]*";    public static String[] key = {"int", "double", "String", "float"};    public static String[] operator = {"+", "-", "*", "/", "="};    public static String[] comma = {","};    public static String[] terminator = {";"};    public static boolean exists(String[] liste, String mot) {        for (int i = 0; i < liste.length; i++) {            if (mot.equals(liste)) {                return true;            }        }        return false;    }    public static void main(String args[]) {        Scanner s = new Scanner(System.in);        String exp, token;        System.out.print("Enter decleration : ");        exp = s.nextLine();        StringTokenizer st = new StringTokenizer(exp, " ");        while (st.hasMoreTokens()) {            token = st.nextToken();            if (exists(key, token)) {                System.out.println(token + " is a keyword");                continue;            }            if (exists(operator, token)) {                System.out.println(token + " is an operator");                continue;            }            if (token.matches(id)) {                System.out.println(token + " is an identifier");                continue;            }            if (exists(comma, token)) {                System.out.println(token + " is a comma");                continue;            }            if (exists(terminator, token)) {                System.out.println(token + " is a terminator");                continue;            }        }    }}

مع العلم أنه يجب مراعاة الـ space (أو أي محرف آخر) بين مختلف الـ Tokens ليفصلها عن بعضها البعض (لأن طبيعة عمل split أو StringTokenizer تفرض عليك مثل هذا الشرط).

مثال :

Enter decleration : int a , b ;
int is a keyword
a is an identifier
, is a comma
b is an identifier
; is a terminator

بالتوفيق.

1
#6

لنفرض أن المستخدم أدخل:

int name = 10 $$;

المفترض أن يحللها البرنامج هكذا:

int name = 10 $$;
^

int name = 10 $$; // وجدنا 'int'
   ^

int name = 10 $$; // نتجاهل المسافة
    ^

int name = 10 $$; // وجدنا معرف name
        ^

int name = 10 $$; // نتجاهل المسافة
         ^

int name = 10 $$; // وجدنا '='
          ^

int name = 10 $$; // نتجاهل المسافة
           ^

int name = 10 $$; // وجدنا رقم 10
             ^

int name = 10 $$;  // نتجاهل المسافة
              ^


int name = 10 $$; // حرف غير معروف، خطأ
               ^

الطريقة أن يعدل مؤشر النص للجزء التالي، هذا تطبيق بسيط:

import java.util.Collections;
import java.util.Map;
import java.util.LinkedHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

class lexical {

  public static void lex(Map<String, String> tokens, String stream) {
    // طالما لم نصل لنهاية النص
    for( int i = 0 ; i < stream.length() ; ) {
      // نفترض أننا لم نتعرف على النص
      boolean foundSomething = false;
      // نجرب جميع الأنماط
      for( Map.Entry<String, String> token : tokens.entrySet() ) {
        // i نجهز النمط ونبدأ من عند قيمة
        Pattern pattern = Pattern.compile(token.getValue());
        Matcher matcher = pattern.matcher(stream.substring(i)); // <-
        // هل وجدنا تطابق؟
        if( matcher.lookingAt() ) {
          // اطبع ماوجدت إذا لم يكن مسافة مثلاً
          if( ! token.getKey().equals("SKIP") ) {
            System.out.printf("%5d - %10s => %s\n", i, token.getKey(), matcher.group());
          }
          // نعدل موضع البحث
          i += matcher.end();
          // تعرفنا على جزء، لنتوقف وننتقل للجزء الثاني
          foundSomething = true;
          break;
        }
      }
      // إذا جربنا كل الأنماط ولم نتعرف على جزء من النص فهناك خطأ
      if( foundSomething == false ) {
        System.out.printf("Syntax error: at position %d near %s\n", i, stream.substring(i));
        break;
      }
    }
  }

  public static void main(String[] argv) {
    // يجب استخدام هذا النوع من الهاش لأن تريب الرجكس مهم
    Map<String, String> tokens = Collections.synchronizedMap (
     new LinkedHashMap<String, String>()
    );

    // الترتيب مهم جداً
    tokens.put("string",       "\"[^\"]+\""); // نصّ
    tokens.put("keyword",      "(int|long|double|String)"); // كلمة خاصة
    tokens.put("identifier",   "[a-zA-Z_][a-zA-Z0-9_]*"); // معرف
    tokens.put("number",       "[0-9]+"); // رقم
    tokens.put(",",            ","); // ,
    tokens.put("=",            "="); // =
    tokens.put(";",            ";"); // ;
    tokens.put("SKIP",         " "); // تجاهل المسافة

    // نجرب نص سليم
    lex(tokens, "int name = 10,          String age = \"Name age\";");

    System.out.println("-------------------------------");

    // نجرب نص به خطأ
    lex(tokens, "double name = 1$$");
  }
}

الوظيفة lex بسيطة وعامة الإستخدام، فقط مررلي لها hash به مفتاح بنوع الـtoken والنمط، الترتيب مهم جداً، لهذا استخدمت LinkedHashMap لأنها لاتفقد الترتيب، فلو وضعتي:

...
tokens.put("=",            "=");
...
tokens.put("==",           "==");
...

ستحدث مشكلة لو كتب شخص ==، سيعتبرها علامتي مساواة، الحل هو تبديل الترتيب:

...
tokens.put("==",           "==");
...
tokens.put("=",            "=");
...

تجربة:

    0 -    keyword => int
    4 - identifier => name
    9 -          = => =
   11 -     number => 10
   13 -          , => ,
   24 -    keyword => String
   31 - identifier => age
   35 -          = => =
   37 -     string => "Name age"
   47 -          ; => ;
-------------------------------
    0 -    keyword => double
    7 - identifier => name
   12 -          = => =
   14 -     number => 1
Syntax error: at position 15 near $$
1
#7

شكرا لردووووودكم وجزاكم الله خيرا ...

 

اخي اعرف انه split  تقوم بفصل المسافات بس انا اريد استخدم شي غير  split  بحيث تناسب ادخل بيانات بدون ما اعمل مسافات بينهم

مواضيع مشابهة