ANTLR
V4 में लेसर नियम
खोज…
सरल नियम
लेक्सर नियम टोकन प्रकारों को परिभाषित करते हैं। उनका नाम उन्हें पार्सर नियमों से अलग करने के लिए एक बड़े अक्षर से शुरू करना होगा।
INTEGER: [0-9]+;
IDENTIFIER: [a-zA-Z_] [a-zA-Z_0-9]*;
OPEN_PAREN: '(';
CLOSE_PAREN: ')';
मूल सिंटैक्स:
| वाक्य - विन्यास | अर्थ |
|---|---|
A | मैच लेसर नियम या A नाम का टुकड़ा |
AB | मैच A उसके बाद B |
(A|B) | मैच A या B |
'text' | मैच शाब्दिक "पाठ" |
A? | मैच A शून्य या एक बार |
A* | मैच A शून्य या अधिक बार |
A+ | मैच A एक या अधिक बार |
[A-Z0-9] | परिभाषित सीमाओं में एक वर्ण का मिलान करें (इस उदाहरण में AZ या 0-9 के बीच) |
'a'..'z' | एक वर्ण सीमा के लिए वैकल्पिक वाक्यविन्यास |
~[AZ] | एक श्रेणी का निषेध - किसी एकल वर्ण को श्रेणी में नहीं मिलाता है |
. | किसी एक वर्ण से मेल खाना |
टुकड़े टुकड़े
टुकड़े lexer नियमों के पुन: प्रयोज्य भागों हैं जो अपने आप से मेल नहीं खा सकते हैं - उन्हें एक lexer नियम से संदर्भित करने की आवश्यकता है।
INTEGER: DIGIT+
| '0' [Xx] HEX_DIGIT+
;
fragment DIGIT: [0-9];
fragment HEX_DIGIT: [0-9A-Fa-f];
उत्तल लेसर नियम
जब पार्सर नियम में '{' जैसे टोकन का उपयोग किया जाता है, तो उनके लिए एक अंतर्निहित लेक्सर नियम बनाया जाएगा जब तक कि एक स्पष्ट नियम मौजूद न हो।
दूसरे शब्दों में, यदि आपके पास एक शाब्दिक नियम है:
OPEN_BRACE: '{';
तब ये दोनों पार्सर नियम समान हैं:
parserRule: '{';
parserRule: OPEN_BRACE;
लेकिन अगर OPEN_BRACE नियम को परिभाषित नहीं किया गया है, तो एक अंतर्निहित अनाम नियम बनाया जाएगा। उस मामले में, निहित नियम को परिभाषित किया जाएगा जैसे कि इसे अन्य नियमों से पहले परिभाषित किया गया था: इसमें अन्य नियमों की तुलना में उच्च प्राथमिकता होगी।
प्राथमिकता नियम
कई lexer नियम समान इनपुट पाठ से मेल खा सकते हैं। उस स्थिति में, टोकन प्रकार निम्नानुसार चुना जाएगा:
- सबसे पहले, लेक्सर नियम का चयन करें जो सबसे लंबे इनपुट से मेल खाता है
- यदि पाठ एक अंतर्निहित परिभाषित टोकन से मेल खाता है (जैसे
'{'), तो निहित नियम का उपयोग करें - यदि कई लेसर नियम समान इनपुट लंबाई से मेल खाते हैं, तो परिभाषा क्रम के आधार पर पहले वाले को चुनें
निम्नलिखित संयुक्त व्याकरण:
grammar LexerPriorityRulesExample;
// Parser rules
randomParserRule: 'foo'; // Implicitly declared token type
// Lexer rules
BAR: 'bar';
IDENTIFIER: [A-Za-z]+;
BAZ: 'baz';
WS: [ \t\r\n]+ -> skip;
निम्नलिखित इनपुट को देखते हुए:
aaa foo bar baz barz
लेसर से निम्नलिखित टोकन अनुक्रम का उत्पादन करेगा:
IDENTIFIER 'foo' BAR IDENTIFIER IDENTIFIER
aaaटाइपIDENTIFIERकेवल
IDENTIFIERनियम इस टोकन से मेल खा सकता है, कोई अस्पष्टता नहीं है।
foo'foo'प्रकार'foo'Parser नियम
randomParserRuleनिहित'foo'टोकन प्रकार का परिचय देता है, जोIDENTIFIERनियम पर प्राथमिकता है।
barटाइपBARयह पाठ
BARनियम से मेल खाता है, जिसेIDENTIFIERनियम से पहले परिभाषित किया गया है, और इसलिए इसकी पूर्वता है।
bazप्रकार काIDENTIFIERयह पाठ
BAZनियम से मेल खाता है, लेकिन यहIDENTIFIERनियम से भी मेल खाता है। बाद को चुना जाता है क्योंकि इसेBARसे पहले परिभाषित किया जाता है।व्याकरण को देखते हुए,
BAZकभी भी मैच नहीं कर पाएगा, क्योंकिIDENTIFIERनियम पहले से ही सब कुछBAZमेल खा सकता है।
barzIDENTIFIERप्रकार का हैBARनियम इस स्ट्रिंग (bar) के पहले 3 वर्णों का मिलान कर सकता है, लेकिनIDENTIFIERनियम 4 वर्णों से मेल खाएगा। चूंकिIDENTIFIERएक लंबे विकल्प से मेल खाता है, इसलिए इसेBARऊपर चुना जाता है।
अंगूठे के नियम के रूप में, विशिष्ट नियमों को अधिक सामान्य नियमों से पहले परिभाषित किया जाना चाहिए। यदि कोई नियम केवल एक इनपुट से मेल खा सकता है जो पहले से परिभाषित नियम द्वारा कवर किया गया है, तो इसका उपयोग कभी नहीं किया जाएगा।
अवैध रूप से परिभाषित नियम जैसे कि 'foo' अधिनियम, जैसे कि वे अन्य सभी लेक्सर नियमों से पहले परिभाषित किए गए हों।
लेक्सर की आज्ञा
एक लेसर नियम में संबंधित आदेश हो सकते हैं:
WHITESPACE: [ \r\n] -> skip;
नियम के अंत में -> बाद कमांड को परिभाषित किया जाता है।
-
skip: मिलान किए गए पाठ कोskip, कोई टोकन उत्सर्जित नहीं किया जाएगा -
channel(n): एक अलग चैनल पर टोकन का उत्सर्जन करता है -
type(n): परिवर्तित टोकन प्रकार -
mode(n),pushMode(n),popMode,more: नियंत्रण lexer मोड
क्रिया और अर्थ की भविष्यवाणी करता है
लेक्सर कार्रवाई लक्ष्य भाषा में { ... } घिरे मनमाने कोड का एक ब्लॉक है, जिसे मिलान के दौरान निष्पादित किया जाता है:
IDENTIFIER: [A-Z]+ { log("matched rule"); };
एक शब्दार्थ विधेय लक्ष्य भाषा में मनमाने कोड का एक खंड होता है, जो { ... }? घिरा होता है }? , जो एक बूलियन मूल्य का मूल्यांकन करता है। यदि लौटाया गया मान गलत है, तो लेक्सर नियम छोड़ दिया जाता है।
IDENTIFIER: [A-Z]+ { identifierIsValid() }?;
प्रदर्शन कारणों से जब भी संभव हो, नियम के अंत में शब्दार्थ विधेय को परिभाषित किया जाना चाहिए।