คำถามติดแท็ก grammar

20
C ++ ไม่มีบริบทหรือคำนึงถึงบริบทหรือไม่
ฉันมักจะได้ยินคำกล่าวอ้างว่า C ++ เป็นภาษาที่คำนึงถึงบริบท นำตัวอย่างต่อไปนี้: a b(c); นี่เป็นคำนิยามตัวแปรหรือการประกาศฟังก์ชันหรือไม่ cที่ขึ้นอยู่กับความหมายของสัญลักษณ์ ถ้าcเป็นตัวแปรแล้วa b(c);กำหนดชื่อตัวแปรประเภทb มันจะเริ่มต้นได้โดยตรงกับa cแต่ถ้าcเป็นประเภทแล้วa b(c);ประกาศฟังก์ชั่นที่มีชื่อbที่ใช้และส่งกลับca หากคุณค้นหาคำจำกัดความของภาษาที่ไม่มีบริบทมันจะบอกคุณโดยทั่วไปว่ากฎไวยากรณ์ทั้งหมดต้องมีด้านซ้ายมือที่ประกอบด้วยสัญลักษณ์ที่ไม่ใช่เทอร์มินัล ในทางกลับกันไวต่อไวยากรณ์อนุญาตให้ใช้สตริงของเทอร์มินัลและสัญลักษณ์ที่ไม่ใช่เทอร์มินัลโดยพลการด้านซ้ายมือ การเรียกดูผ่านภาคผนวก A ของ "ภาษาการเขียนโปรแกรม C ++" ฉันไม่สามารถหากฎไวยากรณ์เดียวที่มีสิ่งอื่นนอกเหนือจากสัญลักษณ์ที่ไม่ใช่เทอร์มินัลเดียวที่ด้านซ้ายมือ นั่นหมายความว่า C ++ นั้นไม่มีบริบท (แน่นอนว่าภาษาที่ไม่มีบริบททุกภาษานั้นมีความอ่อนไหวตามบริบทด้วยในแง่ที่ว่าภาษาที่ไม่ใช้บริบทนั้นเป็นส่วนย่อยของภาษาที่คำนึงถึงบริบท แต่นั่นไม่ใช่ประเด็น) ดังนั้น C ++ ไม่มีบริบทหรือตามบริบทหรือไม่

20
int a [] = {1,2,}; อนุญาตให้ใช้เครื่องหมายจุลภาคแปลก มีเหตุผลพิเศษไหม?
บางทีฉันอาจไม่ได้มาจากโลกใบนี้ แต่ดูเหมือนว่าฉันต่อไปนี้ควรเป็นข้อผิดพลาดทางไวยากรณ์: int a[] = {1,2,}; //extra comma in the end แต่มันไม่ใช่ ฉันรู้สึกประหลาดใจเมื่อรหัสนี้รวบรวม Visual Studio แต่ฉันได้เรียนรู้ที่จะไม่ไว้วางใจ MSVC คอมไพเลอร์เท่าที่ c ++ กฎระเบียบที่เกี่ยวข้องเพื่อให้ผมตรวจสอบมาตรฐานและเป็นที่ได้รับอนุญาตตามมาตรฐานเช่นกัน คุณสามารถดู 8.5.1 สำหรับกฎไวยากรณ์หากคุณไม่เชื่อฉัน ทำไมถึงได้รับอนุญาต นี่อาจเป็นคำถามที่ไร้ประโยชน์ แต่ฉันต้องการให้คุณเข้าใจว่าทำไมฉันถึงถาม หากเป็นกรณีย่อยของกฎไวยากรณ์ทั่วไปฉันจะเข้าใจ - พวกเขาตัดสินใจที่จะไม่ทำให้ไวยากรณ์ทั่วไปยากขึ้นเพียงเพื่อไม่อนุญาตให้ใช้เครื่องหมายจุลภาคซ้ำซ้อนในตอนท้ายของรายการ initializer แต่ไม่อนุญาตให้ใช้เครื่องหมายจุลภาคเพิ่มเติมอย่างชัดเจน ยกตัวอย่างเช่นมันจะไม่ได้รับอนุญาตให้มีเครื่องหมายจุลภาคซ้ำซ้อนในตอนท้ายของรายการอาร์กิวเมนต์ฟังก์ชั่นการโทร (เมื่อฟังก์ชั่นใช้เวลา...) ซึ่งเป็นเรื่องปกติ ดังนั้นอีกครั้งมีเหตุผลใดที่อนุญาตให้ใช้เครื่องหมายจุลภาคซ้ำซ้อนนี้อย่างชัดเจนหรือไม่

6
ทำไม C ++ ไม่สามารถแยกวิเคราะห์ด้วยตัวแยกวิเคราะห์ LR (1)
ฉันอ่านเกี่ยวกับตัวแยกวิเคราะห์และตัวแยกวิเคราะห์และพบคำสั่งนี้ในการแยกวิเคราะห์ LR ของวิกิพีเดีย - หน้า: ภาษาการเขียนโปรแกรมจำนวนมากสามารถแยกวิเคราะห์ได้โดยใช้รูปแบบของตัวแยกวิเคราะห์ LR ข้อยกเว้นหนึ่งที่น่าสังเกตคือ C ++ ทำไมถึงเป็นเช่นนั้น? มีคุณสมบัติพิเศษใดของ C ++ ที่ทำให้ไม่สามารถวิเคราะห์ด้วยตัวแยกวิเคราะห์ LR ได้ เมื่อใช้ google ฉันพบว่า C สามารถแยกวิเคราะห์ได้อย่างสมบูรณ์แบบด้วย LR (1) แต่ C ++ ต้องใช้ LR (∞)

2
ไวยากรณ์ฟรีตามบริบทคืออะไร?
ใครช่วยอธิบายให้ฉันเข้าใจว่าไวยากรณ์ที่ไม่มีบริบทคืออะไร หลังจากดูรายการ Wikipedia และรายการ Wikipedia เกี่ยวกับไวยากรณ์ที่เป็นทางการแล้วฉันก็รู้สึกสับสนอย่างสิ้นเชิง จะมีใครใจดีอธิบายว่าสิ่งเหล่านี้คืออะไร? ฉันสงสัยสิ่งนี้เพราะฉันต้องการตรวจสอบการแยกวิเคราะห์และในด้านข้างข้อ จำกัด ของเอนจิน regex ฉันไม่แน่ใจว่าคำศัพท์เหล่านี้เกี่ยวข้องกับการเขียนโปรแกรมโดยตรงหรือไม่หรือเกี่ยวข้องกับภาษาศาสตร์โดยทั่วไปมากกว่า ถ้าเป็นเช่นนั้นต้องขออภัยด้วยนะคะถ้าเป็นเช่นนั้น

8
อะไรคือความแตกต่างระหว่างตัวแยกวิเคราะห์ LR, SLR และ LALR
อะไรคือความแตกต่างที่แท้จริงระหว่างตัวแยกวิเคราะห์ LR, SLR และ LALR ฉันรู้ว่า SLR และ LALR เป็นประเภทของตัวแยกวิเคราะห์ LR แต่อะไรคือความแตกต่างที่แท้จริงของตารางแยกวิเคราะห์ และจะแสดงได้อย่างไรว่าไวยากรณ์เป็น LR, SLR หรือ LALR? สำหรับไวยากรณ์ LL เราต้องแสดงให้เห็นว่าเซลล์ใด ๆ ของตารางการแยกวิเคราะห์ไม่ควรมีกฎการผลิตหลายข้อ กฎที่คล้ายกันสำหรับ LALR, SLR และ LR หรือไม่ ตัวอย่างเช่นเราจะแสดงให้เห็นว่าไวยากรณ์ได้อย่างไร S --> Aa | bAc | dc | bda A --> d LALR คือ (1) แต่ไม่ใช่ SLR (1)? แก้ไข (ybungalobill) : …

1
อะไรทำให้ Java แยกวิเคราะห์ได้ง่ายกว่า C
ฉันคุ้นเคยกับข้อเท็จจริงที่ว่าไวยากรณ์ของ C และ C ++ มีความละเอียดอ่อนตามบริบทและโดยเฉพาะอย่างยิ่งคุณต้องมี "lexer hack" ใน C ในทางกลับกันฉันรู้สึกว่าคุณสามารถแยกวิเคราะห์ Java ได้เพียง 2 โทเค็นแห่งการมองไปข้างหน้าแม้จะมีความคล้ายคลึงกันมากระหว่างสองภาษา คุณต้องเปลี่ยนแปลงอะไรเกี่ยวกับ C เพื่อให้สามารถแยกวิเคราะห์ได้ง่ายขึ้น ฉันถามเพราะตัวอย่างทั้งหมดที่ฉันเคยเห็นเกี่ยวกับความไวต่อบริบทของ C นั้นสามารถทำได้ในทางเทคนิค แต่ก็แปลกมาก ตัวอย่างเช่น, foo (a); อาจจะมีการเรียกฟังก์ชันโมฆะกับข้อโต้แย้งfoo aหรืออาจเป็นการประกาศว่าaเป็นวัตถุประเภทหนึ่งfooแต่คุณสามารถกำจัด parantheses ได้อย่างง่ายดาย ส่วนหนึ่งความแปลกนี้เกิดขึ้นเนื่องจากกฎการผลิต "ผู้ประกาศโดยตรง" สำหรับไวยากรณ์ Cตอบสนองวัตถุประสงค์สองประการในการประกาศทั้งฟังก์ชันและตัวแปร ในทางกลับกันไวยากรณ์ Javaมีกฎการผลิตแยกต่างหากสำหรับการประกาศตัวแปรและการประกาศฟังก์ชัน ถ้าคุณเขียน foo a; คุณจะรู้ว่ามันเป็นการประกาศตัวแปรและfooสามารถแยกวิเคราะห์เป็นชื่อประเภทได้อย่างชัดเจน นี่อาจไม่ใช่รหัสที่ถูกต้องหากfooไม่ได้กำหนดคลาสไว้ที่ใดที่หนึ่งในขอบเขตปัจจุบัน แต่นั่นเป็นงานสำหรับการวิเคราะห์เชิงความหมายที่สามารถดำเนินการได้ในคอมไพเลอร์พาสในภายหลัง ฉันเคยเห็นมันบอกว่า C นั้นยากที่จะแยกวิเคราะห์เนื่องจาก typedef แต่คุณสามารถประกาศประเภทของคุณเองใน Java ได้เช่นกัน กฎไวยากรณ์ภาษา C …
90 java  c  parsing  grammar 

3
ฉันจะกำหนดไวยากรณ์ Raku เพื่อแยกวิเคราะห์ข้อความ TSV ได้อย่างไร
ฉันมีข้อมูล TSV ID Name Email 1 test test@email.com 321 stan stan@nowhere.net ฉันต้องการแยกวิเคราะห์นี้เป็นรายการของแฮช @entities[0]<Name> eq "test"; @entities[1]<Email> eq "stan@nowhere.net"; ฉันมีปัญหากับการใช้ตัวขึ้นบรรทัดใหม่เพื่อกำหนดแถวส่วนหัวจากแถวค่า คำจำกัดความไวยากรณ์ของฉัน: use v6; grammar Parser { token TOP { <headerRow><valueRow>+ } token headerRow { [\s*<header>]+\n } token header { \S+ } token valueRow { [\s*<value>]+\n? } token value { \S+ } …
13 csv  grammar  raku 

1
การหยุดไวยากรณ์ Raku ที่ EOS (End of String)
ในกระบวนการเขียนนักแปลของภาษาดนตรีหนึ่งไปยังอีกภาษาหนึ่ง (ABC ถึง Alda) เป็นข้ออ้างในการเรียนรู้ความสามารถของ Raku DSL ฉันสังเกตว่าดูเหมือนจะไม่มีทางที่จะยุติ a .parse! นี่คือตัวอย่างรหัสย่อของฉัน: #!/home/hsmyers/rakudo741/bin/perl6 use v6d; # use Grammar::Debugger; use Grammar::Tracer; my $test-n01 = q:to/EOS/; a b c d e f g A B C D E F G EOS grammar test { token TOP { <score>+ } token score { <.ws>? …
9 parsing  grammar  raku 

2
วิธีการตั้งค่าไวยากรณ์ที่สามารถจัดการกับความกำกวม
ฉันกำลังพยายามสร้างไวยากรณ์เพื่อแยกสูตรคล้าย Excel ที่ฉันคิดขึ้นมาโดยที่อักขระพิเศษในตอนต้นของสตริงแสดงถึงแหล่งที่มาที่แตกต่างกัน ยกตัวอย่างเช่น$สามารถมีความหมายสตริงดังนั้น " $This is text" จะได้รับการปฏิบัติเป็นสัญญาณเข้าสตริงในโปรแกรมและ&สามารถมีความหมายฟังก์ชั่นเพื่อให้สามารถจะถือว่าเป็นการเรียกร้องให้ฟังก์ชั่นภายใน&foo()foo ปัญหาที่ฉันเผชิญคือการสร้างไวยากรณ์อย่างถูกต้อง ตัวอย่างเช่นนี่เป็นเวอร์ชั่นย่อที่มีชื่อว่า MWE: grammar = r'''start: instruction ?instruction: simple | func STARTSYMBOL: "!"|"#"|"$"|"&"|"~" SINGLESTR: (LETTER+|DIGIT+|"_"|" ")* simple: STARTSYMBOL [SINGLESTR] (WORDSEP SINGLESTR)* ARGSEP: ",," // argument separator WORDSEP: "," // word separator CONDSEP: ";;" // condition separator STAR: "*" func: STARTSYMBOL SINGLESTR …
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.