ฉันคิดเสมอว่าการอ้างอิงถึงไวยากรณ์ของภาษานั้นเหมือนกับการอ้างอิงถึงความหมายของภาษา แต่ฉันได้รับแจ้งว่าไม่เป็นเช่นนั้น ความแตกต่างคืออะไร?
ฉันคิดเสมอว่าการอ้างอิงถึงไวยากรณ์ของภาษานั้นเหมือนกับการอ้างอิงถึงความหมายของภาษา แต่ฉันได้รับแจ้งว่าไม่เป็นเช่นนั้น ความแตกต่างคืออะไร?
คำตอบ:
ความหมาย ~ ความหมาย
ไวยากรณ์ ~ การแทนสัญลักษณ์
ดังนั้นสองโปรแกรมที่เขียนในภาษาต่าง ๆ สามารถทำสิ่งเดียวกัน (ซีแมนติกส์) แต่สัญลักษณ์ที่ใช้ในการเขียนโปรแกรมจะแตกต่างกัน (ไวยากรณ์)
คอมไพเลอร์จะตรวจสอบไวยากรณ์ของคุณสำหรับคุณ (ข้อผิดพลาดในการคอมไพล์ในเวลานั้น) และรับความหมายจากกฎภาษา ผลลัพธ์ไม่ถูกต้องเนื่องจากรหัสระบุว่าเพิ่ม 1 แทนการเพิ่ม 2)
x + y
ที่ไม่มี+
โอเปอเรเตอร์ที่เหมาะสมสำหรับตัวถูกดำเนินการเหล่านั้น) การเพิ่ม 1 แทน 2 เป็นสิ่งที่ฉันเรียกว่าข้อผิดพลาดเชิงตรรกะ
จริงๆแล้วไม่มีสองระดับ แต่มีสามระดับ:
i
และf
สร้างif
)if
, (
, 42
, ==
, answer
และ)
ผลิตคำสั่งเงื่อนไข)ValidIdentifier
เทอร์มินัลซึ่งสามารถกำหนดเป็นสิ่งที่ต้องการ![AnyKeyword] [Identifier]
(ฉันใช้สัญลักษณ์เหมือน PEG ที่นี่) คุณไม่จำเป็นต้องใช้ lexing pass แยกต่างหากสำหรับภาษาดังกล่าว ดูตัวอย่างตัวแยกวิเคราะห์ C ++ ที่ใช้ GLR
ฉันจะอธิบายให้คุณเห็นด้วยตัวอย่างง่ายๆในภาษาENGLISH
:
The glass drank Ben
เป็นคำสั่งที่ถูกต้องทางไวยากรณ์ มันมีคำนามคำกริยา ฯลฯ
แต่ความหมายมันผิดเพราะคำนี้ไม่มีความหมายที่เข้าใจได้หรือที่ถูกต้อง
ความหมายหมายถึงเอนทิตีแบบลอจิคัลของภาษาการเขียนโปรแกรมและการโต้ตอบ ไวยากรณ์กำหนดวิธีแสดงสิ่งเหล่านี้เป็นอักขระ
ตัวอย่างเช่นแนวคิดของตัวคำนวณเลขคณิตเป็นส่วนหนึ่งของซีแมนทิกส์ซี วิธีที่สามารถใช้+
และ-
โอเปอเรเตอร์เพื่อแสดงการทำงานของตัวชี้เป็นส่วนหนึ่งของไวยากรณ์
บางครั้งสองภาษาแบ่งปันบางส่วนของซีแมนทิกส์ของพวกเขา แต่ไวยากรณ์แตกต่างกันอย่างมาก (เช่น C # และ VB.NET - ทั้งสองประเภทใช้ค่าและประเภทอ้างอิง ในกรณีอื่น ๆ สองภาษามีความเหมือนกันทางวากยสัมพันธ์ แต่ความหมายไม่ตรงกัน (พิจารณาจาก Java กับ JavaScript ซึ่งความคล้ายคลึงกันมักทำให้ผู้เริ่มต้นสับสน)
ไวยากรณ์คือวิธีที่คุณจัดเรียงโทเค็นของภาษา ซีแมนทิกส์คือความหมายของโทเค็นเหล่านั้น (ปกติแล้วการจัดเรียงโทเค็นหมายถึงอะไร)
คุณไม่ได้ระบุว่าคุณอ้างถึงภาษาการเขียนโปรแกรมหรือภาษาทั่วไปที่ใช้ในการเขียนโปรแกรมเท่านั้นดังนั้นคำตอบของฉันเกี่ยวกับภาษาข้อมูล (เช่น XML, RDF, ระบบชนิดข้อมูลเป็นต้น):
ไบรอันแอถ่อมตนของเขาในเจ็ดกฎทองสำหรับการผลิตมาตรฐานภาษาอิสระ (1995) เขียนว่า"ไวยากรณ์ภาษาหนึ่งสามารถเป็นอีกหนึ่งของความหมาย" เขาอ้างถึงคำว่า "ไวยากรณ์" และ "ความหมาย" ที่ใช้ในคำอธิบายข้อมูล: ดังนั้นหากคุณสะดุดคำเหล่านี้ในสเปคของรูปแบบข้อมูลบางอย่างคุณควรแทนที่ทั้งสองคำด้วย"Potrzebie"เพื่อให้ชัดเจนว่าคุณต้องทำงาน ความหมายสำหรับตัวคุณเอง
ความสัมพันธ์ระหว่างไวยากรณ์และความหมายอย่างน้อยในข้อมูลที่ระบุว่าดีขึ้นสามารถอธิบายได้ด้วยคำว่า"เข้ารหัส" ความหมายถูกเข้ารหัสในรูปแบบไวยากรณ์ เนื่องจากการบันทึกสามารถซ้อนกันได้ไวยากรณ์ของภาษาหนึ่งจึงเป็นความหมายของอีกภาษาหนึ่ง หากมีข้อมูลเกินขอบเขตของข้อมูลการทำรังนี้อาจไม่มีที่สิ้นสุดตามที่อธิบายโดย Umberto Eco ว่า "semiosis ไม่ จำกัด "
เพื่อให้ตัวอย่าง:
ผู้คนมักจะหยุดในบางระดับและใช้เป็นความหมาย แต่ในที่สุดก็ไม่มีความหมายสุดท้ายเว้นแต่มนุษย์บางคนตีความข้อมูลในใจของเขา ทันทีที่มีคนพยายามที่จะแสดงความหมายในรูปแบบของข้อมูลมันจะกลายเป็นไวยากรณ์
หากสามารถอธิบายได้ในBNF (รูปแบบ Backus-Naur)หรือสิ่งที่คล้ายกันก็เป็นไวยากรณ์ หากไม่สามารถทำได้ก็ไม่เป็นเช่นนั้น
ในทางกลับกันซีแมนทิกส์นั้นเกี่ยวกับความหมายของโปรแกรม (หรือซอร์สโค้ดอื่น ๆ )
และบางครั้งเส้นแบ่งระหว่างทั้งสองก็อาจพร่ามัว
วิธีหนึ่งในการทำความเข้าใจความแตกต่างคือดูชนิดของข้อผิดพลาดที่คุณได้รับเมื่อไวยากรณ์หรือความหมายของโปรแกรมไม่ถูกต้อง
ข้อผิดพลาดทางไวยากรณ์คือความล้มเหลวของซอร์สโค้ดเพื่อให้ตรงกับไวยากรณ์ภาษาตัวอย่างเช่นไม่มีเซมิโคลอนที่ต้องการ
ข้อผิดพลาดทางความหมายคือความล้มเหลวในการตอบสนองความต้องการด้านภาษาอื่น ๆ (เช่น C เรียกว่า "ข้อ จำกัด "); ตัวอย่างอาจจะเขียนx + y
ที่ไหนx
และy
อยู่ในประเภทที่เข้ากันไม่ได้ ไวยากรณ์ภาษาจะบอกคุณว่าการเพิ่มนั้นดูเหมือนว่าsomething + something
แต่มันไม่มีประสิทธิภาพเพียงพอที่จะแสดงความต้องการเกี่ยวกับประเภทของตัวถูกดำเนินการทางซ้ายและขวา
(ข้อผิดพลาดเชิงตรรกะเช่นการใช้ 1 โดยที่ 2 จะถูกต้องโดยทั่วไปจะไม่สามารถตรวจพบได้โดยคอมไพเลอร์ - แม้ว่าในบางกรณีคอมไพเลอร์สามารถเตือนเกี่ยวกับรหัสที่น่าสงสัย)
ไวยากรณ์คือสิ่งที่สัญลักษณ์ (คำศัพท์) พูด ความหมายคือสิ่งที่พวกเขาหมายถึง
พิจารณา:
C #: condition ? true_value : false_value
VB.NET: If(condition, true_value, false_value)
- ไวยากรณ์ที่แตกต่างกันความหมายเดียวกัน
C #: left_value / right_value
VB.NET: left_value / right_value
- ไวยากรณ์เดียวกันความหมายที่แตกต่างกัน (สำหรับจำนวนเต็ม)
ไวยากรณ์คือการจัดเรียงทางไวยากรณ์ของคำในประโยคเช่นคำสั่ง
(อังกฤษ) ' cat dog boy ' และ (การเขียนโปรแกรม) ' hi.5 ' ไม่ถูกต้องทางไวยากรณ์
(อังกฤษ) ' cat hugs boy ' และ (programming) '* 3.2 * 5 *' ถูกต้องทางไวยากรณ์
ความหมายแบบคงที่คือว่าคำสั่งที่ถูกต้อง syntactically มีความหมายใด ๆ
(อังกฤษ) ' I are big ' (Programming) (python) ' 3 +' hi ' ' ถูกต้องทางไวยากรณ์ แต่มีข้อผิดพลาดทางความหมายแบบคงที่
ความหมายคือความหมายที่เกี่ยวข้องกับสตริงสัญลักษณ์ที่ถูกต้องโดยไม่มีข้อผิดพลาดความหมายคงที่เช่นประโยคที่ถูกต้องประโยคและความหมายถูกต้อง แต่ความหมายของมันอาจจะไม่เป็นสิ่งที่ตั้งใจ
(อังกฤษ) ' เครื่องบินที่บินได้อาจเป็นอันตรายได้ ' มีสองความหมายเช่นการบินของเครื่องบินอาจเป็นอันตรายหรือเครื่องบินที่กำลังบินอาจเป็นอันตรายได้
(การเขียนโปรแกรม) 'คอมพิวเตอร์จะไม่สร้างข้อความแสดงข้อผิดพลาด แต่จะไม่ทำสิ่งที่คุณบอกให้ทำ มันจะทำอย่างอื่น '
ที่มา : MIT 6.00.1
ไวยากรณ์หมายถึงกฎอย่างเป็นทางการที่ควบคุมการสร้างข้อความที่ถูกต้องในภาษา ความหมายหมายถึงชุดของกฎที่ให้ความหมายของคำสั่ง
ข้อผิดพลาดเนื่องจากไวยากรณ์เกิดขึ้นในโปรแกรมเมื่อภาษาของโปรแกรมถูกละเมิดหรือถูกนำไปใช้ในทางที่ผิด ข้อผิดพลาดเนื่องจากความหมายเกิดขึ้นในโปรแกรมเมื่อคำสั่งไม่มีความหมาย
การเรียงลำดับคำเป็นหลักการพื้นฐานของไวยากรณ์ผู้ที่พยายามเข้าใจสิ่งที่เขียนใช้คิวคำศัพท์เพื่อเรียงลำดับคำเพื่อช่วยกำหนดโครงสร้างประโยคและความหมาย ความหมายคือบุคคลตีความความหมายของคำว่า "ประโยค" ตามความรู้เดิม ดังนั้นประโยคที่ดูเหมือนไม่มีความหมายเชิงประโยคสามารถมีความหมายเมื่อใช้ตัวชี้นำความหมาย
ไวยากรณ์เกี่ยวข้องเฉพาะกับสิ่งที่ถูกต้องตามหลักภาษาและหลักไวยากรณ์เท่านั้น ซีแมนทิกส์ต้องการความรู้ล่วงหน้าทุกสิ่งซึ่งอยู่เหนือกว่าสิ่งใดซึ่งเป็นภาษาเฉพาะ
ประโยค "เครื่องดื่มนมสำหรับทารก" ไม่มีความหมายทางประโยค แต่ผ่านความหมายคนส่วนใหญ่จะตีความว่ามันเป็นความหมาย "เครื่องดื่มนมสำหรับทารก" ตามที่ความรู้ก่อนหน้าของเราบอกเราว่าเด็กดื่มนมและดังนั้นเราจึงสามารถค้นหาความหมายจาก คำสำคัญ
ไวยากรณ์และความหมายเหมือนยุทธศาสตร์และยุทธวิธีหรือทางซ้ายและขวา
พวกเขาไม่ได้เป็นแนวคิดสากลที่เป็นอิสระจริง ๆ แต่คู่ของคำที่เกี่ยวข้องที่เมื่อคุณอยู่ในบริบทที่เฉพาะเจาะจงระบุทิศทางที่ตรงข้าม แต่สิ่งเดียวกันที่เป็นกลยุทธ์ในระดับหนึ่งคือกลยุทธ์ในอีกระดับหนึ่ง
ดังนั้นหากคุณกำลังเขียนโค้ดในภาษาไวยากรณ์คือภาษาที่คุณใช้และพฤติกรรมที่ต้องการคือซีแมนทิกส์ แต่ถ้าคุณกำลังนำไปใช้หรือพูดถึงคอมไพเลอร์สำหรับภาษานั้นไวยากรณ์คือไวยากรณ์และบางทีพิมพ์ระบบและความหมายทุกอย่างที่สร้างขึ้นบนนั้น และอื่น ๆ
ไวยากรณ์คือสิ่งที่คอมพิวเตอร์เข้าใจความหมายคือสิ่งที่มนุษย์เข้าใจ
คอมไพเลอร์ / ล่ามไม่สนใจเล็กน้อยเกี่ยวกับการออกแบบของคุณและในรหัสใด ๆ ที่คอมไพล์ลงไปถึงระดับเครื่องคุณจะมีเวลาในการลดการออกแบบ นักพัฒนาให้ความสำคัญกับการออกแบบเพราะการออกแบบที่ดีนั้นเกี่ยวกับการลดความซับซ้อนโดยการสรุปพฤติกรรมและการโต้ตอบที่ซับซ้อนและปัญหาที่แตกต่างกันทำให้เกิดความหมายต่างกัน ตัวเลือกของภาษาส่วนใหญ่เกี่ยวกับความง่ายและความหมายที่คุณต้องการใช้สามารถแสดงในรูปแบบไวยากรณ์
ตัวอย่างสั้น ๆ กับ "plain c":
void main()
{
int a = 10;
int x = a - 1;
int y = - 1;
printf("x = %i", x);
printf("y = %i", y);
getch();
}
ในตัวอย่างนี้ไวยากรณ์สำหรับโทเค็น "-" เหมือนกัน แต่มีความหมายแตกต่างกัน ("ความหมาย") ขึ้นอยู่กับตำแหน่งที่ใช้
ในการมอบหมาย "x", "-" หมายถึงการดำเนินการ "การลบ", ในการมอบหมาย "y", "-" หมายถึงการดำเนินการ "เครื่องหมายลบ"
-
ดำเนินการทั้งสองเป็นโทเค็นเดียวกันแต่มีความแตกต่างทางไวยากรณ์เนื่องจากใช้ในบริบทที่แตกต่างกัน 0 - 1
ตรงกับกฎไวยากรณ์additive-expression: additive-expression - multiplicative-expression
ในขณะที่- 1
ตรงกับกฎไวยากรณ์unary-expression: unary-operator cast-expression
(อ้างอิง: มาตรฐาน C99)
-
Oeprators ทั้งสองคือวากยสัมพันธ์ไม่ใช่แค่ความหมาย (แม้ว่าพวกเขาจะมีความหมายต่างกัน) ไวยากรณ์ถูกกำหนดโดยไวยากรณ์ภาษาและตัวดำเนินการทั้งสองจะถูกระบุในส่วนต่าง ๆ ของไวยากรณ์ ดูร่าง N1570 , ส่วนที่ 6.5.3 สำหรับตัวดำเนินการ unary และ 6.5.6 สำหรับตัวดำเนินการเสริม (BTW ถ้าคุณจะใช้ตัวอย่าง C มันอาจจะถูกต้องvoid main()
ควรจะเป็นint main(void)
และคุณหายไป#include <stdio.h>
และสิ่งที่ส่วนหัวประกาศgetch