การวิเคราะห์คำศัพท์ที่ไม่มีการแสดงออกปกติ


9

ฉันดู lexers สองสามตัวในระดับสูงกว่าต่างๆ ( Python , PHP , Javascriptและอื่น ๆ ) และพวกเขาทั้งหมดดูเหมือนจะใช้นิพจน์ปกติในรูปแบบเดียวหรืออีกรูปแบบหนึ่ง ในขณะที่ฉันแน่ใจว่า regex อาจเป็นวิธีที่ดีที่สุดในการทำสิ่งนี้ฉันสงสัยว่ามีวิธีใดบ้างที่จะได้รับการเลเยอร์พื้นฐานโดยไม่มีการแสดงออกปกติหรืออาจเป็นการแยกวิเคราะห์สตริงโดยตรง

ใช่แล้วเป็นไปได้ไหมที่จะใช้การเรียงลำดับขั้นพื้นฐานบางอย่างในภาษาระดับสูง * โดยไม่ใช้นิพจน์ทั่วไปในรูปแบบใด ๆ

* ภาษาระดับที่สูงขึ้นเป็นสิ่งต่าง ๆ เช่น Perl / PHP / Python / Javascript เป็นต้นฉันแน่ใจว่ามีวิธีที่จะทำได้ใน C


2
ดูเหมือนว่า "มีหนังสือเกี่ยวกับแคลคูลัสที่ไม่ได้ใช้ตัวอักษรกรีกทั้งหมดและสิ่งประหลาด ๆ อย่างงี่เง่า?"
วินไคลน์

@ kevincline ทำไมผู้คนถึงพายเรือข้ามมหาสมุทรแอตแลนติกเมื่อมีเครื่องบินดีเลิศบนท้องฟ้า?
Smudge

1
การพายและการขี่มีผลข้างเคียงที่แตกต่างกัน
วินไคลน์

คำตอบ:


3

ก่อนอื่นมีไลบรารีนิพจน์ทั่วไปสำหรับ C ตั้งแต่ก่อนที่ภาษา "ระดับสูง" ของคุณถูกประดิษฐ์ เพียงแค่พูดว่าโปรแกรม C ไม่ได้เป็น podunk อย่างที่บางคนคิด

สำหรับไวยากรณ์ส่วนใหญ่ lexing เป็นเรื่องของการค้นหาช่องว่างและตัวละครอื่น ๆ เช่น () [] {}; เพื่อแยกคำจากนั้นจับคู่กับรายการคำหลักเพื่อดูว่าตรงกันหรือไม่


1
ฉันไม่ได้หมายความว่า C ไม่สามารถทำ regex ได้ฉันหมายถึงมันมีคุณสมบัติที่ทรงพลังกว่าสำหรับทำสิ่งนี้ ฉันคิดว่ามันง่ายกว่าที่จะสร้าง lexer ขั้นสูงและมีประสิทธิภาพในภาษา C มากกว่าภาษาระดับสูงกว่า
รอยเปื้อน

1
@sam ความซับซ้อนและประสิทธิภาพของ lexer หรือ parser เป็นหน้าที่ของความซับซ้อนของภาษาที่ถูกแยกวิเคราะห์มากกว่า langugae ที่ parser ถูกนำมาใช้ดังนั้นไม่
jk

+1 lexer นั้นง่ายอย่างไม่น่าเชื่อ คุณเพียงแค่ต้องการสตริงประเภทข้อมูลสำหรับโทเค็นของคุณและตารางคำหลักที่กำหนดไว้ล่วงหน้า ส่วนที่ยากที่สุดคือการจัดการกับช่องว่างและความคิดเห็น: P
Mason Wheeler

2

คุณอาจสนใจใน "เครื่องมือแยกวิเคราะห์สแกนเนอร์" ซึ่งไม่มีขั้นตอนการแยกโทเค็น มีคำอธิบายอย่างหนึ่งเกี่ยวกับประโยชน์ของตัวแยกวิเคราะห์แบบไร้สแกนเนอร์ในตอนต้นของบทความนี้: ตัวกรองลดความกำกวมสำหรับตัวแยกวิเคราะห์ LR แบบไม่ใช้สแกนเนอร์ (มีข้อเสียเหมือนกัน)

(PEGs ซึ่งถูกกล่าวถึงในคำตอบอื่น ๆ สามารถใช้ในการสร้างตัวแยกวิเคราะห์ที่ไม่ใช้สแกนเนอร์ได้)


1

ไม่มีอะไรพิเศษเกี่ยวกับการแสดงออกปกติ มันเป็นการจดชวเลขซึ่งช่วยให้คุณสร้างรหัสได้ง่ายขึ้นและการใช้งานจะถูกจัดส่งทั่วไป อย่างไรก็ตามโดยพื้นฐาน lexers คือ FSMs และนิพจน์ทั่วไปเป็นเพียงวิธีหนึ่งในการบรรลุเป้าหมายนั้น


0

แน่นอนคุณสามารถใช้ parsers อื่น ๆ ได้เนื่องจากภาษาปกติทุกภาษานั้นไม่มีบริบท คำถามนี้มาจากสาเหตุที่คุณต้องการ

ไม่มีอะไรจะง่ายไปกว่านิพจน์ทั่วไป (คุณจะปรับปรุง O (N) ได้อย่างไร) และการพยายามทำให้ง่ายขึ้นจะไม่ช่วยอะไร คุณสามารถใช้การย้อนรอยง่าย ๆ ได้ตลอดเวลาเนื่องจาก Jetti ชี้ให้เห็นแม้ว่าฉันจะแนะนำให้หลีกเลี่ยงถ้าเป็นไปได้

หากคุณกำลังจะใช้เครื่องมือแยกวิเคราะห์ขั้นสูงขึ้นเพื่อใช้เลเยอร์แล้วคุณอาจไม่จำเป็นต้องใช้ขั้นตอน lexing เลย ในความเป็นจริงเหตุผลที่เรามีช่วง lexing ก็คือมันเร็วกว่าในการแยกสัญญาณโทเค็น lexed กว่าเพื่อแยกตัวอักษรพร้อมกับมันง่ายขึ้นอย่างมากขั้นตอนการแยกวิเคราะห์ของเรา ดังนั้นการใช้เครื่องมือแยกวิเคราะห์ขั้นสูงทำให้คุณสูญเสียผลประโยชน์ทั้งหมดของ lexing ตั้งแต่แรก


ดังนั้น regex จะทำอย่างไร มันจะไม่ต้องไปตามตัวละครโดยตัวอักษร (สำหรับรูปแบบส่วนใหญ่ที่ใช้ในการ lexing อย่างน้อย)?
Jetti

@Jetti ใช่แน่นอน
Pubby

มันจะเป็นการง่ายที่จะอ่านตัวละครแต่ละตัวและจากนั้นย้อนรอยหากจำเป็นต้องดึงโทเค็นออกมา มันจะเป็นรหัสมากกว่า แต่ก็ไม่ยากขึ้น
Jetti

@Jetti ฉันไม่เห็นว่า backtracking ที่ไร้เดียงสานั้นดีกว่าอย่างไร
Pubby

ฉันไม่เคยพูดดีขึ้น แต่ OP ถามว่ามีวิธีอื่นหรือไม่และเป็นอีกวิธีหนึ่งที่ไม่ใช่โปรแกรมแยกวิเคราะห์ขั้นสูง
Jetti

0

มันสมเหตุสมผลที่จะทำการวิเคราะห์คำด้วยนิพจน์ทั่วไปหรือข้ามผ่านเลยและทำการแยกวิเคราะห์ lexerless ที่มีความยืดหยุ่นและทรงพลังมากขึ้นด้วย PEG หรือ GLR

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.