วิธี traverse ที่ AST ใช้ภาษา-ศูนย์ควบคุม kde ในโมดูลจาวาสคริปต์?

0

คำถาม

สมมุติว่าผมมีโปรแกรมเหมือนแล้ว:

let words = ["foo", "bar", "baz", "qux"]

for (var i = 0; i < words.length; i++) {
  console.log(words[i])
}

ฉันต้องการให้ตัวกรองที่ AST และแค่เก็บ literals. ยังไงฉัน traverse ที่ AST เพื่อให้เท่านั้น"foo","บาร์"เป็นต้?

literals :: JSAST -> [String]
literals (JSAstProgram statements) = undefined
literals _ = []

ที่ทำดัชนีเทียบสีเส้นควรตัวกรองคน [JSStatement]และจากนั้นดูเป็นไปได้สำหรับแสดง. ถ้าการแสดงคืนพบโปรดตรวจสอบว่ามีการยึดตามตัวอักษรแบบนั้. Lastly,แผนที่รายการจาก JSStatement -> String.

กำลังตามหาเป็นไปได้แสดงเป็นปัญหาสำหรับฉันตอนนี้หรอก ฉันจะตรงกับรูปแบบ:

f :: JSStatement -> a
f (JSLet _ expression _) = undefined
f (JSConstant _ expression _) = undefined
f (JsDoWhile _ _ _ _ expression _ _) = undefined
... etc

และจากนั้นสิ่งที่เหมือนกันเพื่อตามหาสำหรับการยึดตามตัวอักษรแบบนั้:

g :: JSExpression -> a
g (JSLiteral _ literal) = undefined
g (JSStringLiteral _ literal) = undefined
g (JSArrayLiteral _ literal _) = undefined
... etc

อย่างไรก็ตามนี่คือมา verbose และฉันรู้สึกเหมือนมีบางอย่างที่ดีกว่าข้างนอกนั่น ยังไงฉัน traverse ผ่าน AST และตัวกรองออกเดียวที่ literals ในทำความสะอาดและ concise ด้วยวาจาแบบนี้

haskell
2021-11-23 00:50:07
2

คำตอบที่ดีที่สุด

2

ทั้งหมดประเภท Language.JavaScript.Parser เป็นของโห Data.Dataเป็นชั้นเรียนสำหรับส่วนพับเก็บได้ generically บข้อมูล constructors. คุณสามารถใช้ gmapQมีฟังก์ชันจากคลาสนี้เพื่อ traverse องโครงสร้างแล้ว cast เพื่อกำหนดงานอดิเรกตอนที่เธอเจอเป็นโหนดของดอกเบี้ย ด้านล่างนี้เป็น implementation ยที่ง่ายกว่าสำหรับตัวอย่างเช่น AST นแบบนั้น

{-# LANGUAGE DeriveDataTypeable #-}

import Data.Data (Data, gmapQ)
import Data.Typeable (cast)

data Lit = S String | I Int deriving Data
data Expr = Sum Expr Expr | LitExpr Lit deriving Data
data Statement = Stmt [Expr] deriving Data
data AST = AST [Statement] deriving Data

strings :: AST -> [String]
strings = concat . gmapQ go
  where go :: Data d => d -> [String]
        go x = case cast x of
          Nothing -> concat $ gmapQ go x
          Just (I _) -> []
          Just (S s) -> [s]

λ> strings (AST [Stmt [], Stmt [LitExpr (S "x"), Sum (LitExpr (I 5)) (LitExpr (S "y")), LitExpr (S "z")]])
["x","y","z"]

ข้อคโดยวิธีที่ผมต้องให้ go เป็น explicit ประเภทลายเซ็น ฉันคิดว่านี่เป็นเพราะไม่อย่างนั้น GHC น inferring ว่า recursive โทรไป go ต้องใช้คนเดียวกัน d constraint ที่ enclosing โทรหาแต่แน่นอนเราต้องการให้พวกเขาต่างจากนี้

2021-11-23 02:57:10

คุณแสดงเล็กๆตัวอย่างของทำลายบรรยากาศได้มากเลย ไม่จำเป็นต้องเป็นอย่างกับ AST จากภาษา-จาวาสคริปต์ ฉันไม่แน่ใจว่าจะใช้มันออกจากคนประเภท-นิยามตัวมันเอง
Salox

แน่นอน,ฉันถูกเพิ่มเป็นตัวอย่าง. ฉันมั่นใจว่า uniplate เป็นที่น่ารักแต่อ่านมันเอกสารคู่มือ@info:shell เหลือฉันแปลกใจเกี่ยวกับเรื่องที่ฉันจะทำทุกอย่างแต่ทว่าข้อมูลข้อมูลถูกชัดเจนมากพอที่จะปล่อยให้ฉันเขียน implementation หลังจากไม่เคยใช้ข้อมูลมาก่อน
amalloy

ผมแค่เพิ่ม uniplate ทางออกไปเหมือนกัน มันเป็นจริงมากง่ายมากเลยที่จะใช้เมื่อเทียบกับต้องใช้ของ Data.Data.
alias

มันจะพาฉันมาได้ซักพักนึงแล้วที่จะทำลายทุกอย่างลงไปที่จะเข้าใจว่าเกิดอะไรขึ้นแต่ก็ขอบคุณมากสำหรับตัวอย่างเช่น! ฉันซาบซึ้งมัน
Salox
2

คุณพูดถูกนั่นพวกนี้อย่างของสิ่งที่เป็นปกติ boilerplate;และภาษา haskelllanguage มีที่ยอดเยี่ยบรรณารักษ์จะปล่อยให้คุณรหัสเช่นฟังก์ชันอย่างง่าย หนึ่งในคนโปรดของฉันคือ uniplate: https://hackage.haskell.org/package/uniplate

ตาม@amalloy เป็นตัวอย่างเช่นนี่เป็นวิธีที่คุณจะรหัสเดียวกันโดยใช้ Uniplate:

{-# LANGUAGE DeriveDataTypeable #-}

import Data.Data
import qualified Data.Generics.Uniplate.Data as G

data Lit       = S String | I Int            deriving Data
data Expr      = Sum Expr Expr | LitExpr Lit deriving Data
data Statement = Stmt [Expr]                 deriving Data
data AST       = AST [Statement]             deriving Data

strings :: AST -> [String]
strings a = [s | S s <- G.universeBi a]

แล้ว:

*Main> strings (AST [Stmt [], Stmt [LitExpr (S "x"), Sum (LitExpr (I 5)) (LitExpr (S "y")), LitExpr (S "z")]])
["x","y","z"]

โปรดจำไว้ว่านิยามขอเชือกก็ตามเป็นหนึ่ง liner. งั้นทั้งหมดที่คุณต้องการคือหนึ่งเส้นของนำเข้าและองแสดงแค่บทเดียวสำหรับ extracting ทุ literals ใช้ uniplate น universeBi ฟังก์ชันซึ่งเป็นจริงที่แสดง:

   [s | S s <- G.universeBi ast]

ซึ่งค่อนข้าอ่านสิ่งที่คุณได้ตั้งใจ:Traverse ทั้งหมด AST และหาฉันยึดตามตัวอักษรแบบนั้ใช้เส้นสายปรากฎตัวขึ้นที่ไหนก็ได้ ไม่มีอะไรมากก declarative กว่านั้น!

2021-11-23 01:32:16

โอ้ว้าวนั่นก็ตัวเตี้ยเวลาเปรียบเทียบกับ\n ค Data แพ็คเก็จฉันทำอยู่บ่อยๆ ฉันหวังว่าฉันจะเลือกคำตอบของคุณด้วย! อ่าเอ่อล้นออกมาไม่ปล่อยฉัน upvote มันตั้งแต่ฉันใหม่ของผู้ใช้ร้ายอย่างโชคร้ายจริงๆ ขอบคุณมากสำหรับของคุณตัวอย่างเช่นเอ่อฉันซาบซึ้งมาก
Salox

ในภาษาอื่นๆ

หน้านี้อยู่ในภาษาอื่นๆ

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................

ดังอยู่ในนี้หมวดหมู่

ดังคำถามอยู่ในนี้หมวดหมู่