2015-09-07 11 views
5

निम्नलिखित कोड एक मान्य जावा प्रोग्राम है।कोई टिप्पणी पार्स करते समय जावा कंपाइलर विफल होने का कारण क्या हो सकता है?

public class Foo 
{ 
    public static void \u006d\u0061\u0069\u006e(String[] args) 
    { 
     System.out.println("hello, world"); 
    } 
} 

main पहचानकर्ता यूनिकोड बच दृश्यों का उपयोग कर लिखा है। यह संकलित और ठीक चलाता है।

$ javac Foo.java && java Foo 
hello, world 

हालांकि निम्नलिखित विवरण इस प्रश्न के लिए आवश्यक नहीं हो सकता, मैं इसे मामले में किसी को साझा कर रहा हूँ इसके बारे में उत्सुक है। मैं डेबियन 8.0 पर ओपनजेडीके से जावा कंपाइलर का उपयोग कर रहा हूं लेकिन मैं इस प्रश्न में जो पूछता हूं वह किसी भी जावा कंपाइलर पर लागू होना चाहिए।

$ javac -version 
javac 1.7.0_79 
$ readlink -f $(which javac) 
/usr/lib/jvm/java-7-openjdk-amd64/bin/javac 

निम्नलिखित कार्यक्रम एक त्रुटि क्योंकि भागने इस्तेमाल किया अनुक्रम लिखने के main की m अमान्य है।

public class Foo 
{ 
    public static void \u6d\u0061\u0069\u006e(String[] args) 
    { 
     System.out.println("hello, world"); 
    } 
} 

संकलक अवैध यूनिकोड अनुक्रम के बारे में शिकायत।

$ javac Foo.java && java Foo 
Foo.java:3: error: illegal unicode escape 
    public static void \u6d\u0061\u0069\u006e(String[] args) 
         ^
Foo.java:3: error: invalid method declaration; return type required 
    public static void \u6d\u0061\u0069\u006e(String[] args) 
          ^
2 error 

क्या मुझे आश्चर्य है कि निम्नलिखित कार्यक्रम भी भले ही अवैध यूनिकोड एस्केप अनुक्रम प्रकट करने के लिए एक टिप्पणी में हो रहा है अमान्य है।

public class Foo 
{ 
    // This comment contains \u6d. 
    public static void main(String[] args) 
    { 
     System.out.println("hello, world"); 
    } 
} 

यहां त्रुटि है।

$ javac Foo.java && java Foo 
Foo.java:3: error: illegal unicode escape 
    // This comment contains \u6d. 
           ^
1 error 

संकलक अवैध यूनिकोड एस्केप अनुक्रम के बारे में शिकायत करता है हालांकि यह एक टिप्पणी में प्रतीत होता है।

इस व्यवहार के पीछे कारण स्पष्ट हो जाता है जब हम देखते हैं कि JLS §3.7 में अंतराल की टिप्पणी कैसे परिभाषित की जाती है। इस प्रकार

EndOfLineComment: 
// {InputCharacter} 

JLS §3.4InputCharacter परिभाषित करता है।

InputCharacter: 
    UnicodeInputCharacter but not CR or LF 

अंत में, JLS §3.3UnicodeInputCharacter इस प्रकार परिभाषित करता है।

UnicodeInputCharacter: 
    UnicodeEscape 
    RawInputCharacter 

UnicodeEscape: 
    \ UnicodeMarker HexDigit HexDigit HexDigit HexDigit 

UnicodeMarker: 
    u {u} 

HexDigit: 
    (one of) 
    0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F 

RawInputCharacter: 
    any Unicode character 

इसलिए, शाब्दिक विश्लेषक पहले के आदेश टिप्पणियां पहचान करने के लिए यूनिकोड बच दृश्यों पहचान करने के लिए आवश्यक है, और अगर एक अवैध यूनिकोड एस्केप अनुक्रम पाया जाता है, शाब्दिक विश्लेषण विफल हो जाएगा और कोई त्रुटि सामने आ जाएगा। इसलिए, संकलक कभी भी उस टिप्पणी को पहचानने के लिए आगे नहीं बढ़ेगा जिसमें अवैध यूनिकोड एस्केप अनुक्रम शामिल था।

हालांकि मुझे लगता है कि है कि अंत तक एक टिप्पणी की शुरुआत (माना //) से सब कुछ अनदेखा किया जाता है प्रयोग किया जाता है, ऊपर के उदाहरण से पता चलता है कि इस मामले क्योंकि शाब्दिक विश्लेषक शुरुआत के बीच यूनिकोड बच दृश्यों पहचान करने के लिए है नहीं है एक टिप्पणी और एक टिप्पणी के अंत, और एक अवैध यूनिकोड भागने अनुक्रम लेक्सिकल विश्लेषण विफल होने का कारण बन सकता है।

टिप्पणी को पार करते समय संकलक विफल होने का कारण क्या हो सकता है?

+1

देखो [यहां] (http://stackoverflow.com/questions/9225124/error-due-to-content-in-a-legal- टिप्पणी में जावा) – Dando18

+0

@ Dando18 धन्यवाद लिंक साझा करने के लिए। हालांकि, उत्तर में से कोई भी जवाब वास्तव में इस प्रश्न का उत्तर नहीं देता है। उत्तर जो '@ बहिष्कृत' के बारे में बात करता है वह ओपनजेडीके में पुन: उत्पन्न नहीं होता है। उत्तर जो '/ * इस यूनिकोड चार' */'*/'के कारण कंपाइलर त्रुटि का उल्लेख गलत है क्योंकि पीछे की ओर' */'स्पष्ट रूप से टिप्पणी के भीतर नहीं है। अन्य दो उत्तरों पूछे गए विशिष्ट प्रश्न को संबोधित नहीं करते हैं। –

+1

http://stackoverflow.com/q/30727515/2158288 – ZhongYu

उत्तर

2

लघु:

कुछ भी नहीं है (कुछ भी नहीं किसी और )।

लांग:

तार्किक रूप से, \u भागने दृश्यों नियंत्रित किया जाता है से पहले शाब्दिक प्रोसेसिंग (स्कैनिंग/tokenizing) जगह लेता है। https://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls-3.2 के अनुसार:

एक कच्चे यूनिकोड वर्ण धारा टोकन के एक दृश्य में अनुवाद किया है, निम्न तीन शाब्दिक अनुवाद चरणों, जो बारी में लागू होते हैं का उपयोग कर:

  1. यूनिकोड का अनुवाद निकल जाता है (§3.3) यूनिकोड वर्णों की कच्ची धारा में इसी यूनिकोड वर्ण में। प्रपत्र \ uxxxx, जहां xxxx हेक्साडेसिमल मान है, का एक यूनिकोड बच UTF-16 कोड इकाई जिसका एन्कोडिंग xxxx है प्रतिनिधित्व करता है। यह अनुवाद चरण किसी भी प्रोग्राम को केवल ASCII वर्णों का उपयोग करके व्यक्त करने की अनुमति देता है।

  2. यूनिकोड धारा इनपुट अक्षर और रेखा (§3.4) टर्मिनेटर्स की एक धारा में चरण 1 से उत्पन्न का एक अनुवाद।

  3. इनपुट तत्वों (§3.5) के अनुक्रम में चरण 2 से उत्पन्न इनपुट वर्णों और रेखा टर्मिनेटर की धारा का अनुवाद, जो सफेद स्थान (§3.6) और टिप्पणियों (§3.7) को छोड़कर छोड़ दिया जाता है, जिसमें शामिल है टोकन (§3.5) कि वाक्यात्मक व्याकरण (§2.3) के टर्मिनल प्रतीक हैं।

तो तकनीकी तौर पर, अपने उदाहरण में \u6dनहीं टिप्पणी का एक हिस्सा है। चाहे या नहीं यह संबंधित है कि टिप्पणी निर्धारित किया जाता है के बाद इसे वापस एक यूनिकोड कोड-बात करने के लिए अनुवाद किया है। लेकिन दुर्भाग्य से यह वहां विफल रहता है।

एक सबूत के रूप में, निम्न वर्ग को संकलित करना चाहिए:

public class Test { 
    // is comment, the rest, not\u000a public static void main(String[] args) { 
     System.out.println("See!"); 
    } 
} 
+1

मुझे लगता है कि आपको जोर देना चाहिए कि जेएलएस का वह हिस्सा क्यों है कि * कुछ भी नहीं * किसी टिप्पणी में त्रुटि उत्पन्न करने जा रहा है, और त्रुटि के कारण के बारे में कम है, जिसे ओपी पहले ही समझ में आता है। – RealSkeptic

संबंधित मुद्दे