मैं एक साधारण कार्यात्मक भाषा के लिए एक पार्सर बनाने की कोशिश कर रहा हूं, कैमल की तरह थोड़ा, लेकिन मुझे सबसे सरल चीजों से अटक जाना प्रतीत होता है।पारसी के साथ पूर्ण पार्सर उदाहरण?
तो मैं जानना चाहता हूं कि parsec
पार्सर्स के कुछ और पूर्ण उदाहरण हैं, जो कुछ है "यह है कि आप 2 + 3 कैसे पार्स करते हैं"। विशेष रूप से शब्दों और इस तरह के कॉल में काम करते हैं।
और मैंने "आपको एक योजना लिखें" पढ़ा है, लेकिन योजना का वाक्यविन्यास काफी सरल है और वास्तव में सीखने में मदद नहीं करता है।
expr = choice [number, call, ident]
number = liftM Number float <?> "Number"
ident = liftM Identifier identifier <?> "Identifier"
call = do
name <- identifier
args <- parens $ commaSep expr
return $ FuncCall name args
<?> "Function call"
:
मैं सबसे समस्याओं try
, <|>
और choice
उपयोग करने के लिए कैसे ठीक है, क्योंकि मैं सच में नहीं मिलता है क्यों पारसेक इस पार्सर का उपयोग कर एक समारोह कॉल के रूप में a(6)
पार्स करने के लिए लगता है कभी नहीं है संपादित करें, पूरा करने के लिए कुछ कोड जोड़ा गया है, हालांकि यह वास्तव में बात यह है कि मैंने पूछा नहीं है:
AST.hs
module AST where
data AST
= Number Double
| Identifier String
| Operation BinOp AST AST
| FuncCall String [AST]
deriving (Show, Eq)
data BinOp = Plus | Minus | Mul | Div
deriving (Show, Eq, Enum)
Lexer.hs
module Lexer (
identifier, reserved, operator, reservedOp, charLiteral, stringLiteral,
natural, integer, float, naturalOrFloat, decimal, hexadecimal, octal,
symbol, lexeme, whiteSpace, parens, braces, angles, brackets, semi,
comma, colon, dot, semiSep, semiSep1, commaSep, commaSep1
) where
import Text.Parsec
import qualified Text.Parsec.Token as P
import Text.Parsec.Language (haskellStyle)
lexer = P.makeTokenParser haskellStyle
identifier = P.identifier lexer
reserved = P.reserved lexer
operator = P.operator lexer
reservedOp = P.reservedOp lexer
charLiteral = P.charLiteral lexer
stringLiteral = P.stringLiteral lexer
natural = P.natural lexer
integer = P.integer lexer
float = P.float lexer
naturalOrFloat = P.naturalOrFloat lexer
decimal = P.decimal lexer
hexadecimal = P.hexadecimal lexer
octal = P.octal lexer
symbol = P.symbol lexer
lexeme = P.lexeme lexer
whiteSpace = P.whiteSpace lexer
parens = P.parens lexer
braces = P.braces lexer
angles = P.angles lexer
brackets = P.brackets lexer
semi = P.semi lexer
comma = P.comma lexer
colon = P.colon lexer
dot = P.dot lexer
semiSep = P.semiSep lexer
semiSep1 = P.semiSep1 lexer
commaSep = P.commaSep lexer
commaSep1 = P.commaSep1 lexer
Parser.hs
module Parser where
import Control.Monad (liftM)
import Text.Parsec
import Text.Parsec.String (Parser)
import Lexer
import AST
expr = number <|> callOrIdent
number = liftM Number float <?> "Number"
callOrIdent = do
name <- identifier
liftM (FuncCall name) (parens $ commaSep expr) <|> return (Identifier name)
विशिष्ट प्रश्न का उत्तर देना आसान होना चाहिए, लेकिन मैं आपकी समस्या का प्रदर्शन करने वाले पूर्ण, संकलित कोड नमूने के साथ प्रयास करना पसंद करूंगा ... क्या आप एक प्रदान कर सकते हैं? – sclv
मुझे लगता है कि, आप कहीं भी 'try' का उपयोग नहीं करते हैं। आपके न्यूनतम उदाहरण में, मुझे यकीन नहीं है कि यह महत्वपूर्ण है, लेकिन किसी बड़े नमूने में यह निश्चित रूप से होगा। – sclv
अब तक मेरा पूरा कार्यक्रम प्रदान करने की कोशिश कर रहा है। – Lanbo