ตัวอย่างที่แน่นอนนี้ครอบคลุมอยู่ในร่างมาตรฐาน C99 ( รายละเอียดเดียวกันใน C11 ) หัวข้อ6.4 องค์ประกอบของคำศัพท์ย่อหน้าที่ 4ซึ่งกล่าวว่า:
หากสตรีมอินพุตถูกแยกวิเคราะห์เป็นโทเค็นก่อนการประมวลผลจนถึงอักขระที่กำหนดโทเค็นการประมวลผลก่อนหน้าถัดไปจะเป็นลำดับอักขระที่ยาวที่สุดซึ่งสามารถประกอบเป็นโทเค็นก่อนการประมวลผลได้ [... ]
ซึ่งเรียกอีกอย่างว่ากฎการเคี้ยวสูงสุดซึ่งใช้ในการวิเคราะห์ศัพท์เพื่อหลีกเลี่ยงความคลุมเครือและทำงานโดยใช้องค์ประกอบให้มากที่สุดเท่าที่จะทำได้เพื่อสร้างโทเค็นที่ถูกต้อง
ย่อหน้ายังมีสองตัวอย่างที่สองเป็นคำถามที่ตรงกันทุกประการสำหรับคุณและเป็นดังนี้
ตัวอย่าง 2 ส่วนของโปรแกรม x +++++ y ถูกแยกวิเคราะห์เป็น x ++ ++ + y ซึ่งละเมิดข้อ จำกัด ของตัวดำเนินการที่เพิ่มขึ้นแม้ว่าการแยกวิเคราะห์ x ++ + ++ y อาจให้นิพจน์ที่ถูกต้อง
ซึ่งบอกเราว่า:
a+++++b
จะถูกแยกวิเคราะห์เป็น:
a ++ ++ + b
ซึ่งละเมิดข้อ จำกัด ในการเพิ่มโพสต์เนื่องจากผลลัพธ์ของการเพิ่มโพสต์ครั้งแรกคือค่า rvalue และการเพิ่มโพสต์ต้องใช้ค่า lvalue สิ่งนี้กล่าวถึงในส่วนตัวดำเนินการ6.5.2.4
เพิ่มและลด Postfixซึ่งระบุว่า ( เน้นของฉัน ):
ตัวถูกดำเนินการของตัวดำเนินการส่วนเพิ่มหรือการลดหลังการแก้ไขจะต้องมีชนิดของจริงหรือตัวชี้ที่มีคุณสมบัติหรือไม่มีเงื่อนไขและจะต้องเป็นค่าที่ปรับเปลี่ยนได้
และ
ผลลัพธ์ของตัวดำเนินการ postfix ++ คือค่าของตัวถูกดำเนินการ
หนังสือC ++ Gotchasยังครอบคลุมกรณีนี้ในGotcha #17
Maximal Munch Problemsซึ่งเป็นปัญหาเดียวกันในC ++เช่นกันและยังให้ตัวอย่างบางส่วน อธิบายว่าเมื่อจัดการกับชุดอักขระต่อไปนี้:
->*
เครื่องวิเคราะห์คำศัพท์สามารถทำหนึ่งในสามสิ่ง:
- รักษามันเป็นสามราชสกุล:
-
, >
และ*
- ถือว่าเป็นโทเค็นสองอัน:
->
และ*
- ถือว่าเป็นโทเค็นเดียว:
->*
สูงสุดขบฉันกฎช่วยให้สามารถหลีกเลี่ยงความคลุมเครือเหล่านี้ ผู้เขียนชี้ให้เห็นว่า ( ในบริบท C ++ ):
แก้ปัญหาได้มากกว่าที่เป็นสาเหตุ แต่ในสองสถานการณ์ที่พบบ่อยมันน่ารำคาญ
ตัวอย่างแรกจะเป็นเทมเพลตที่มีอาร์กิวเมนต์ของเทมเพลตเป็นเทมเพลต ( ซึ่งได้รับการแก้ไขใน C ++ 11 ) เช่น
list<vector<string>> lovos;
^^
ซึ่งแปลความหมายของวงเล็บมุมปิดเป็นตัวดำเนินการกะดังนั้นจึงต้องมีช่องว่างเพื่อแยกแยะ:
list< vector<string> > lovos;
^
กรณีที่สองเกี่ยวข้องกับอาร์กิวเมนต์เริ่มต้นสำหรับพอยน์เตอร์ตัวอย่างเช่น:
void process( const char *= 0 );
^^
จะถูกตีความว่าเป็น*=
ตัวดำเนินการกำหนดวิธีแก้ปัญหาในกรณีนี้คือการตั้งชื่อพารามิเตอร์ในการประกาศ