อ่าน 5 นาที
ไวยากรณ์ (ภาษาโปรแกรม)
ไวยากรณ์ของ ซอร์สโค้ด คอมพิวเตอร์ คือโค้ดที่มีโครงสร้างและเรียงลำดับโดยจำกัดตามกฎของภาษาคอมพิวเตอร์ เช่นเดียวกับ ภาษา ธรรมชาติ ภาษา คอมพิวเตอร์ (เช่น ภาษาโปรแกรม ) กำหนด ไวยากรณ์...
ไวยากรณ์ (ภาษาโปรแกรม)

ไวยากรณ์ของซอร์สโค้ดคอมพิวเตอร์ คือโค้ดที่มีโครงสร้างและเรียงลำดับโดยจำกัดตามกฎของภาษาคอมพิวเตอร์ เช่นเดียวกับภาษาธรรมชาติภาษาคอมพิวเตอร์ (เช่นภาษาโปรแกรม ) กำหนดไวยากรณ์ที่ถูกต้องสำหรับภาษานั้น[ 1 ]ข้อผิดพลาดทางไวยากรณ์เกิดขึ้นเมื่อซอร์สโค้ดที่ไม่ถูกต้องตามไวยากรณ์ถูกประมวลผลโดยเครื่องมือเช่นคอมไพเลอร์หรืออินเตอร์พรีเตอร์
ภาษาโปรแกรมที่ใช้กันทั่วไปมากที่สุดคือภาษาที่ใช้ข้อความ โดยมี ไวยากรณ์ที่อิงตามสตริง ในทางกลับกัน ไวยากรณ์ของภาษาโปรแกรมเชิงภาพจะอิงตามความสัมพันธ์ระหว่างองค์ประกอบกราฟิก
เมื่อออกแบบไวยากรณ์ นักออกแบบภาษาใดๆ อาจเริ่มต้นด้วยการเขียนตัวอย่างของสตริง ทั้งที่ถูกต้องและไม่ถูกต้อง ก่อนที่จะพยายามหาหลักเกณฑ์ทั่วไปจากตัวอย่างเหล่านั้นที่ใช้ เพื่อให้โครงสร้างทั่วไปของไวยากรณ์สามารถกำหนดได้ผ่านรูปแบบการประกอบ เพื่อให้ได้ช่วงที่ถูกต้องตามความหมายทุกครั้งสำหรับการเปลี่ยนแปลงที่เป็นไปได้แต่ละครั้ง มิฉะนั้น จะส่งคืนข้อผิดพลาดและคำเตือนสำหรับอินพุตที่ไม่ถูกต้องแต่ละรายการ[ 2 ]
ระดับของไวยากรณ์
โดยทั่วไปแล้ว ไวยากรณ์ของภาษาคอมพิวเตอร์จะแบ่งออกเป็นสามระดับ:
- คำ – ระดับคำศัพท์ ซึ่งกำหนดว่าตัวอักษรแต่ละตัวประกอบกันเป็นโทเค็น อย่างไร ;
- วลี – ระดับไวยากรณ์ที่แคบกว่านั้น คือการกำหนดว่าคำแต่ละคำรวมกันเป็นวลีได้อย่างไร
- บริบท – การพิจารณาว่าชื่อตัวแปรหรือวัตถุนั้นหมายถึง อะไร ประเภทถูกต้องหรือไม่ เป็นต้น
การจำแนกในลักษณะนี้ทำให้เกิดความเป็นโมดูลาร์ ซึ่งช่วยให้สามารถอธิบายและประมวลผลแต่ละระดับแยกจากกันได้ และบ่อยครั้งก็เป็นอิสระจากกัน
ขั้นแรกเลกเซอร์จะแปลงลำดับเชิงเส้นของอักขระให้เป็น ลำดับ เชิงเส้นของโทเค็น ซึ่งเรียกว่า " การวิเคราะห์คำศัพท์ " หรือ "เลกซิ่ง" [ 3 ]
ประการที่สอง ตัวแยกวิเคราะห์จะแปลงลำดับเชิงเส้นของโทเค็นให้เป็นโครงสร้างต้นไม้ไวยากรณ์แบบลำดับชั้นซึ่งในความหมายแคบๆ เรียกว่า " การแยกวิเคราะห์ " ขั้นตอนนี้ทำให้มั่นใจได้ว่าลำดับของโทเค็นเป็นไปตามไวยากรณ์ที่เป็นทางการของภาษาโปรแกรม ขั้นตอนการแยกวิเคราะห์นั้นสามารถแบ่งออกเป็นสองส่วน คือต้นไม้การแยกวิเคราะห์หรือ "ต้นไม้ไวยากรณ์ที่เป็นรูปธรรม" ซึ่งกำหนดโดยไวยากรณ์ แต่โดยทั่วไปแล้วมีรายละเอียดมากเกินไปสำหรับการใช้งานจริง และต้นไม้ไวยากรณ์นามธรรม (AST) ซึ่งทำให้สิ่งนี้ง่ายขึ้นและใช้งานได้ ขั้นตอน AST และการวิเคราะห์บริบทสามารถพิจารณาได้ว่าเป็นรูปแบบหนึ่งของการวิเคราะห์ความหมายเนื่องจากเป็นการเพิ่มความหมายและการตีความให้กับไวยากรณ์ หรืออีกทางหนึ่งคือเป็นการนำกฎไวยากรณ์ไปใช้แบบไม่เป็นทางการและด้วยตนเอง ซึ่งยากหรือยุ่งยากที่จะอธิบายหรือนำไปใช้ในรูปแบบที่เป็นทางการ
ประการที่สาม การวิเคราะห์ตามบริบทจะช่วยระบุชื่อและตรวจสอบประเภท ความเป็นโมดูลาร์นี้เป็นไปได้ในบางครั้ง แต่ในภาษาโปรแกรมจริงหลายภาษา ขั้นตอนก่อนหน้านี้ขึ้นอยู่กับขั้นตอนในภายหลัง ตัวอย่างเช่น การแก้ปัญหาด้วยตัวแยกวิเคราะห์ (lexer hack)ในภาษาซีเป็นเพราะการแยกคำขึ้นอยู่กับบริบท แม้ในกรณีเหล่านี้ การวิเคราะห์ทางไวยากรณ์มักถูกมองว่าเป็นการประมาณแบบจำลองในอุดมคตินี้
ระดับต่างๆ โดยทั่วไปจะสอดคล้องกับระดับในลำดับชั้นของชอมสกีคำต่างๆ อยู่ในภาษาปกติซึ่งระบุไว้ในไวยากรณ์ คำศัพท์ ซึ่งเป็นไวยากรณ์ประเภทที่ 3 โดยทั่วไปจะกำหนดเป็นนิพจน์ปกติวลีต่างๆ อยู่ในภาษาไร้บริบท (CFL) โดยทั่วไปเป็นภาษาไร้บริบทแบบกำหนดได้ (DCFL) ซึ่งระบุไว้ในไวยากรณ์โครงสร้างวลีซึ่งเป็นไวยากรณ์ประเภทที่ 2 โดยทั่วไปจะกำหนดเป็นกฎการผลิตในรูปแบบแบ็กคัส-เนาเออร์ (BNF) ไวยากรณ์วลีมักระบุไว้ในไวยากรณ์ที่มีข้อจำกัดมากกว่าไวยากรณ์ไร้บริบท แบบเต็มรูปแบบ เพื่อให้ง่ายต่อการแยกวิเคราะห์ ในขณะที่ตัวแยกวิเคราะห์ LRสามารถแยกวิเคราะห์ DCFL ใดๆ ได้ในเวลาเชิงเส้น ตัวแยกวิเคราะห์ LALR แบบง่าย และตัวแยกวิเคราะห์ LL ที่ง่ายกว่านั้น มีประสิทธิภาพมากกว่า แต่สามารถแยกวิเคราะห์ไวยากรณ์ที่มีกฎการผลิตที่มีข้อจำกัดเท่านั้น โดยหลักการแล้ว โครงสร้างตามบริบทสามารถอธิบายได้ด้วยไวยากรณ์ที่คำนึงถึงบริบทและวิเคราะห์โดยอัตโนมัติด้วยวิธีการต่างๆ เช่นไวยากรณ์คุณลักษณะแม้ว่าโดยทั่วไปแล้ว ขั้นตอนนี้จะทำด้วยตนเอง ผ่าน กฎ การแก้ไขชื่อและการตรวจสอบประเภทและนำไปใช้ผ่านตารางสัญลักษณ์ซึ่งจัดเก็บชื่อและประเภทสำหรับแต่ละขอบเขต
มีการสร้างเครื่องมือที่สามารถสร้างเลกเซอร์จากข้อกำหนด ทางคำศัพท์ ที่เขียนด้วยนิพจน์ปกติ และตัวแยกวิเคราะห์จากไวยากรณ์วลีที่เขียนด้วย BNF โดยอัตโนมัติ ซึ่งช่วยให้สามารถใช้การเขียนโปรแกรมแบบประกาศได้แทนที่จะต้องใช้ การเขียนโปรแกรม แบบขั้นตอนหรือแบบฟังก์ชันตัวอย่างที่โดดเด่นคือ คู่ lex - yaccเครื่องมือเหล่านี้สร้าง แผนผัง ไวยากรณ์ที่เป็นรูปธรรม โดยอัตโนมัติ จากนั้นผู้เขียนตัวแยกวิเคราะห์จะต้องเขียนโค้ดด้วยตนเองเพื่ออธิบายวิธีการแปลงแผนผังนี้เป็น แผนผัง ไวยากรณ์นามธรรม การวิเคราะห์ตามบริบทก็มักจะดำเนินการด้วยตนเองเช่นกัน แม้จะมีเครื่องมืออัตโนมัติเหล่านี้อยู่ การแยกวิเคราะห์มักจะดำเนินการด้วยตนเองด้วยเหตุผลต่างๆ เช่น โครงสร้างวลีอาจไม่เป็นอิสระจากบริบท หรือการใช้งานทางเลือกอื่นช่วยปรับปรุงประสิทธิภาพหรือการรายงานข้อผิดพลาด หรืออนุญาตให้เปลี่ยนแปลงไวยากรณ์ได้ง่ายกว่า ตัวแยกวิเคราะห์มักเขียนด้วยภาษาการเขียนโปรแกรมแบบฟังก์ชัน เช่นHaskellหรือภาษาสคริปต์เช่นPythonหรือPerlหรือ ภาษา การเขียนโปรแกรมแบบเชิงคำสั่งเช่นCหรือC ++
คำจำกัดความไวยากรณ์

ไวยากรณ์ของภาษาการเขียนโปรแกรมแบบข้อความมักจะถูกกำหนดโดยใช้การผสมผสานระหว่างนิพจน์ปกติ (สำหรับโครงสร้างคำศัพท์ ) และ รูปแบบ Backus–Naur ( ภาษาเมตาสำหรับโครงสร้างไวยากรณ์ ) เพื่อระบุหมวดหมู่ทาง ไวยากรณ์ ( ไม่ใช่เทอ ร์มินัล ) และสัญลักษณ์เทอร์มินัลแบบ อุปนัย [ 4 ]หมวดหมู่ทางไวยากรณ์ถูกกำหนดโดยกฎที่เรียกว่าการ ผลิต ซึ่งระบุค่าที่อยู่ในหมวดหมู่ทางไวยากรณ์เฉพาะ[ 1 ]สัญลักษณ์เทอร์มินัลคืออักขระหรือสตริงของอักขระที่เป็นรูปธรรม (ตัวอย่าง เช่น คำหลักเช่นdefine , if , letหรือvoid ) ซึ่งใช้ในการสร้างโปรแกรมที่ถูกต้องตามไวยากรณ์
ไวยากรณ์สามารถแบ่งออกเป็นไวยากรณ์ที่ไม่ขึ้นกับบริบทและไวยากรณ์ที่ขึ้นกับบริบท[ 4 ]ไวยากรณ์ที่ไม่ขึ้นกับบริบทคือกฎที่กำหนดโดยเมตาภาษาของภาษาโปรแกรม ไวยากรณ์เหล่านี้จะไม่ถูกจำกัดโดยบริบทที่อยู่รอบข้างหรืออ้างอิงถึงส่วนนั้นของไวยากรณ์ ในขณะที่ไวยากรณ์ที่ขึ้นกับบริบทจะถูกจำกัดโดยบริบท
ภาษาหนึ่งๆ สามารถมีไวยากรณ์ที่เทียบเท่ากันได้หลายแบบ เช่น นิพจน์ปกติที่เทียบเท่ากัน (ในระดับคำศัพท์) หรือกฎวลีที่แตกต่างกันแต่สร้างภาษาเดียวกันได้ การใช้หมวดหมู่ไวยากรณ์ที่กว้างกว่า เช่น ไวยากรณ์ LR สามารถทำให้ไวยากรณ์สั้นหรือเรียบง่ายกว่าเมื่อเทียบกับหมวดหมู่ที่จำกัดกว่า เช่น ไวยากรณ์ LL ซึ่งอาจต้องใช้ไวยากรณ์ที่ยาวกว่าและมีกฎมากกว่า ไวยากรณ์วลีที่แตกต่างกันแต่เทียบเท่ากันจะให้แผนผังการวิเคราะห์ที่แตกต่างกัน แม้ว่าภาษาพื้นฐาน (ชุดเอกสารที่ถูกต้อง) จะเหมือนกันก็ตาม
ตัวอย่าง: นิพจน์ S ในภาษา Lisp
ด้านล่าง นี้คือไวยากรณ์อย่างง่าย ซึ่งกำหนดโดยใช้สัญลักษณ์ของนิพจน์ปกติและรูปแบบ Backus–Naur แบบขยายโดยอธิบายไวยากรณ์ของนิพจน์ Sซึ่งเป็นไวยากรณ์ข้อมูลของภาษาโปรแกรมLispซึ่งกำหนดกฎการผลิตสำหรับหมวดหมู่ทางไวยากรณ์ ได้แก่นิพจน์อะตอมตัวเลขสัญลักษณ์และรายการ:
expression = atom | list atom = number | symbol number = [ + - ] ? [ '0' - '9' ] + symbol = [ 'A' - 'Z' ][ 'A' - 'Z''0' - '9' ]. * list = '(' , expression * , ')'ไวยากรณ์นี้ระบุสิ่งต่อไปนี้:
- นิพจน์อาจเป็นอะตอมหรือลิสต์ก็ได้ ;
- อะตอมอาจเป็นตัวเลขหรือสัญลักษณ์ก็ได้ ;
- ตัวเลขคือลำดับต่อเนื่องของตัวเลขทศนิยมหนึ่งหลักขึ้นไป โดยอาจมีเครื่องหมายบวกหรือลบนำหน้าหรือไม่ก็ได้
- สัญลักษณ์ คือ ตัวอักษรที่ตามด้วยอักขระใดๆ ตั้งแต่ศูนย์ตัว ขึ้นไป (ไม่รวมช่องว่าง) และ
- รายการคือวงเล็บคู่ที่เข้าคู่กัน โดยมีนิพจน์อยู่ภายในตั้งแต่ ศูนย์ถึงหลายนิพจน์
ในที่นี้ ตัวเลขทศนิยม ตัวอักษรพิมพ์ใหญ่และพิมพ์เล็ก และวงเล็บ เป็นสัญลักษณ์ปลายทาง
ต่อไปนี้เป็นตัวอย่างของลำดับโทเค็นที่ถูกต้องตามหลักไวยากรณ์นี้: ' 12345', ' ()', ' (A B C232 (1))'
ไวยากรณ์ที่ซับซ้อน
ไวยากรณ์ที่จำเป็นในการระบุภาษาโปรแกรมสามารถจำแนกได้ตามตำแหน่งในลำดับชั้นของ Chomskyไวยากรณ์วลีของภาษาโปรแกรมส่วนใหญ่สามารถระบุได้โดยใช้ไวยากรณ์ประเภท 2 กล่าวคือ เป็น ไวยากรณ์ แบบไร้บริบท[ 5 ]แม้ว่าไวยากรณ์โดยรวมจะไวต่อบริบท (เนื่องจากการประกาศตัวแปรและขอบเขตที่ซ้อนกัน) ดังนั้นจึงเป็นประเภท 1 อย่างไรก็ตาม มีข้อยกเว้น และสำหรับบางภาษา ไวยากรณ์วลีเป็นประเภท 0 (สมบูรณ์แบบทัวริง)
ในบางภาษา เช่น Perl และ Lisp ข้อกำหนด (หรือการใช้งาน) ของภาษาอนุญาตให้มีโครงสร้างที่ทำงานระหว่างขั้นตอนการวิเคราะห์ไวยากรณ์ นอกจากนี้ ภาษาเหล่านี้ยังมีโครงสร้างที่อนุญาตให้โปรแกรมเมอร์เปลี่ยนแปลงพฤติกรรมของตัววิเคราะห์ไวยากรณ์ได้ การผสมผสานนี้ทำให้ความแตกต่างระหว่างการวิเคราะห์ไวยากรณ์และการทำงานไม่ชัดเจน และทำให้การวิเคราะห์ไวยากรณ์เป็นปัญหาที่ไม่สามารถตัดสินได้ในภาษาเหล่านี้ ซึ่งหมายความว่าขั้นตอนการวิเคราะห์ไวยากรณ์อาจไม่เสร็จสิ้น ตัวอย่างเช่น ใน Perl สามารถเรียกใช้โค้ดระหว่างการวิเคราะห์ไวยากรณ์โดยใช้BEGINคำสั่ง และต้นแบบฟังก์ชันของ Perl อาจเปลี่ยนแปลงการตีความทางไวยากรณ์ และอาจเปลี่ยนแปลงความถูกต้องทางไวยากรณ์ของโค้ดที่เหลืออยู่ด้วย[ 6 ] [ 7 ]โดยทั่วไปแล้วสิ่งนี้เรียกว่า "มีเพียง Perl เท่านั้นที่สามารถวิเคราะห์ไวยากรณ์ Perl ได้" (เนื่องจากโค้ดต้องทำงานระหว่างการวิเคราะห์ไวยากรณ์ และสามารถแก้ไขไวยากรณ์ได้) หรือที่รุนแรงกว่านั้นคือ "แม้แต่ Perl ก็ไม่สามารถวิเคราะห์ไวยากรณ์ Perl ได้" (เนื่องจากไม่สามารถตัดสินได้) ในทำนองเดียวกัน มาโคร Lisp ที่แนะนำโดยdefmacroไวยากรณ์จะทำงานระหว่างการแยกวิเคราะห์ ซึ่งหมายความว่าคอมไพเลอร์ Lisp ต้องมีระบบรันไทม์ Lisp ทั้งหมดอยู่ด้วย ในทางตรงกันข้าม มาโคร C เป็นเพียงการแทนที่สตริง และไม่จำเป็นต้องมีการดำเนินการโค้ด[ 8 ] [ 9 ]
ไวยากรณ์กับความหมาย
ไวยากรณ์ของภาษาอธิบายรูปแบบของโปรแกรมที่ถูกต้อง แต่ไม่ได้ให้ข้อมูลใดๆ เกี่ยวกับความหมายของโปรแกรมหรือผลลัพธ์ของการดำเนินการโปรแกรมนั้น ความหมายที่กำหนดให้กับการรวมกันของสัญลักษณ์จะถูกจัดการโดยความหมาย (ไม่ว่าจะเป็นแบบเป็นทางการหรือแบบฮาร์ดโค้ดในการใช้งานอ้างอิง ) ไวยากรณ์ที่ถูกต้องจะต้องได้รับการกำหนดก่อนที่ความหมายจะสามารถสร้างความหมายจากมันได้[ 4 ]ไม่ใช่ว่าโปรแกรมที่ถูกต้องตามไวยากรณ์ทั้งหมดจะถูกต้องตามความหมาย โปรแกรมที่ถูกต้องตามไวยากรณ์หลายโปรแกรมยังคงมีรูปแบบที่ไม่ถูกต้องตามกฎของภาษา และอาจ (ขึ้นอยู่กับข้อกำหนดของภาษาและความถูกต้องของการใช้งาน) ส่งผลให้เกิดข้อผิดพลาดในการแปลหรือการดำเนินการ ในบางกรณี โปรแกรมดังกล่าวอาจแสดงพฤติกรรมที่ไม่กำหนดแม้ว่าโปรแกรมจะถูกกำหนดไว้อย่างดีภายในภาษา แต่ก็อาจยังมีความหมายที่ผู้เขียนไม่ได้ตั้งใจไว้
ยก ตัวอย่างเช่น ภาษาธรรมชาติอาจไม่สามารถกำหนดความหมายให้กับประโยคที่ถูกต้องตามหลักไวยากรณ์ได้ หรือประโยคนั้นอาจเป็นเท็จ:
- ประโยค " Colorless green ideas sleep furiously ." นั้นถูกต้องตามหลักไวยากรณ์ แต่ไม่มีความหมายที่เป็นที่ยอมรับโดยทั่วไป
- ประโยค "John is a married bachelor." นั้นถูกต้องตามหลักไวยากรณ์ แต่สื่อความหมายที่ไม่เป็นความจริง
ส่วนของโค้ดภาษาซีต่อไปนี้ถูกต้องตามหลักไวยากรณ์ แต่ทำการดำเนินการที่ไม่มีความหมาย (เนื่องจากpเป็นตัวชี้ว่างการดำเนินการและจึงไม่มีความหมาย): p->realp->im
complex * p = NULL ; complex abs_p = sqrt ( p -> real * p -> real + p -> im * p -> im );เพื่อความเข้าใจง่ายขึ้น ขออธิบายว่า
int x ; printf ( "%d" , x );ถูกต้องตามหลักไวยากรณ์ แต่ไม่ได้กำหนดความหมายไว้ เนื่องจากใช้ตัวแปรที่ไม่ได้กำหนดค่าเริ่มต้นแม้ว่าคอมไพเลอร์สำหรับภาษาโปรแกรมบางภาษา (เช่น Java และ C#) จะตรวจพบข้อผิดพลาดเกี่ยวกับตัวแปรที่ไม่ได้กำหนดค่าเริ่มต้นประเภทนี้ แต่ควรพิจารณาว่าเป็น ข้อผิดพลาด ทางความหมายมากกว่าข้อผิดพลาดทางไวยากรณ์[ 10 ] [ 11 ]
ดูเพิ่มเติม
ลิงก์ภายนอก
- โครงสร้างทางไวยากรณ์ต่างๆ ที่ใช้ในภาษาโปรแกรมคอมพิวเตอร์
- ข้อผิดพลาด Python “ImportError: No module named” ทำไม? ทำอย่างไร? ใช้คำสั่งบรรทัดคำสั่งได้หรือไม่? [แก้ไขแล้วในปี 2021]เก็บถาวรเมื่อ 2021-10-09 ที่Wayback Machine
สรุปเนื้อหา
ข้อมูลสำคัญจากบทความ
ข้อมูลสำคัญเกี่ยวกับ ไวยากรณ์ (ภาษาโปรแกรม)
ไวยากรณ์ของ ซอร์สโค้ด คอมพิวเตอร์ คือโค้ดที่มีโครงสร้างและเรียงลำดับโดยจำกัดตามกฎของภาษาคอมพิวเตอร์ เช่นเดียวกับ ภาษา ธรรมชาติ ภาษา คอมพิวเตอร์ (เช่น ภาษาโปรแกรม ) กำหนด ไวยากรณ์...
ระดับของไวยากรณ์
โดยทั่วไปแล้ว ไวยากรณ์ของภาษาคอมพิวเตอร์จะแบ่งออกเป็นสามระดับ:
คำจำกัดความไวยากรณ์
ไวยากรณ์ของภาษาการเขียนโปรแกรมแบบข้อความมักจะถูกกำหนดโดยใช้การผสมผสานระหว่าง นิพจน์ปกติ (สำหรับโครงสร้าง คำศัพท์ ) และ รูปแบบ Backus–Naur ( ภาษาเมตา สำหรับ โครงสร้างไวยากรณ์ ) เพื่อระบุ หมวดหมู่ทาง ไวยากรณ์ ( ไม่ใช่เทอ ร์มินัล ) และสัญลักษณ์เทอร์ มินัลแบบ...
ตัวอย่าง: นิพจน์ S ในภาษา Lisp
ด้านล่าง นี้คือไวยากรณ์อย่างง่าย ซึ่งกำหนดโดยใช้สัญลักษณ์ของนิพจน์ปกติและ รูปแบบ Backus–Naur แบบขยาย โดยอธิบายไวยากรณ์ของ นิพจน์ S ซึ่งเป็นไวยากรณ์ข้อมูลของภาษาโปรแกรม Lisp ซึ่งกำหนดกฎการผลิตสำหรับหมวดหมู่ทางไวยากรณ์ ได้แก่ นิพจน์ อะตอม ตัวเลข สัญลักษณ์และ...