working on naming parsers

This commit is contained in:
Yehowshua Immanuel 2024-12-09 13:20:21 -05:00
parent 193210273d
commit 17ed883f96
4 changed files with 131 additions and 67 deletions

View file

@ -1,4 +1,4 @@
# General and Planning # General and Planning
- [ ] might need many validation phases - [ ] might need many validation phases
- [ ] it's conceivable that one could construct a Yosys memory Cell - [ ] it's conceivable that one could construct a Yosys memory Cell
with invalid parameters with invalid parameters
@ -34,7 +34,7 @@
parser doesn't conflict(exhibit a partial early match) with parser doesn't conflict(exhibit a partial early match) with
the argument of the parser after the argument of the `many` parser. the argument of the parser after the argument of the `many` parser.
# Parser Development # Parser Development
- [x] Sync - [x] Sync
- [ ] Process - [ ] Process
- [x] Finish `pCell` with `pCellEndStmt` - [x] Finish `pCell` with `pCellEndStmt`
@ -42,6 +42,8 @@
- [x] Remove all instances of `_ <-` - [x] Remove all instances of `_ <-`
- [ ] Module - [ ] Module
- [ ] Remove weird GHC imports - [ ] Remove weird GHC imports
- [ ] Embed locs in AST
- [ ] Remove `preProcessDiscardComments` from exports
- [x] Are the `try` statements in `pWireOption` correctly constructed? - [x] Are the `try` statements in `pWireOption` correctly constructed?
- [ ] Consider the very weird case where the process body has nothing, - [ ] Consider the very weird case where the process body has nothing,
thus, `pEolAndAdvanceToNextNonWs` may never get invoked in any of thus, `pEolAndAdvanceToNextNonWs` may never get invoked in any of
@ -56,7 +58,7 @@
I still need to verify how other parsers behave. For example, what I still need to verify how other parsers behave. For example, what
happens if we have a cell with no `<cell-body-stmt>` happens if we have a cell with no `<cell-body-stmt>`
# Parser Verification # Parser Verification
- [ ] I think only EOL terminated parsers should be responsible - [ ] I think only EOL terminated parsers should be responsible
for advancing the Parsec scanner to the next non-space... for advancing the Parsec scanner to the next non-space...
- [ ] lift grammar into prover and show that all EOL terminated parsers - [ ] lift grammar into prover and show that all EOL terminated parsers

View file

@ -18,7 +18,7 @@ main = do
-- Attempt to read the file -- Attempt to read the file
contents <- catch (readFile filePath) handleReadError contents <- catch (readFile filePath) handleReadError
putStrLn "File Contents:" putStrLn "File Contents:"
putStrLn contents putStrLn $ Haskellator.preProcessDiscardComments contents
[] -> putStrLn "cabal run Haskellator -- <file-path>" [] -> putStrLn "cabal run Haskellator -- <file-path>"
putStrLn $ ppShow Haskellator.val putStrLn $ ppShow Haskellator.val

View file

@ -1,3 +1,11 @@
module Haskellator(val) where module Haskellator(
val,
preProcessDiscardComments,
runParser
) where
import RTLILParser.Parser(val) import RTLILParser.Parser(
val,
preProcessDiscardComments,
runParser,
)

View file

@ -1,6 +1,6 @@
module RTLILParser.Parser( module RTLILParser.Parser(
preProcessDiscardComments, preProcessDiscardComments,
pFile, RTLILParser.Parser.runParser,
a, a,
val) where val) where
@ -68,16 +68,24 @@ import RTLILParser.Primitives(
-- taken from: https://yosyshq.readthedocs.io/projects/yosys/en/0.47/appendix/rtlil_text.html -- taken from: https://yosyshq.readthedocs.io/projects/yosys/en/0.47/appendix/rtlil_text.html
-- parsers below are split int sections from the above link -- parsers below are split int sections from the above link
runParser str = case parse pFile "pFile" preProcessedFile of
Left err -> error $ show err
Right val -> val
where preProcessedFile = preProcessDiscardComments str
-- identifiers -- identifiers
pId :: Parser Id pId :: Parser Id
pId = Public <$> pPublicId pId = Public <$> pPublicId
<|> Autogen <$> pAutogenId <|> Autogen <$> pAutogenId
<?> "Id"
pPublicId :: Parser PublicId pPublicId :: Parser PublicId
pPublicId = PublicId <$> (char '\\' *> many1 pNonWs) pPublicId = PublicId <$> (char '\\' *> many1 pNonWs)
<?> "PublicId"
pAutogenId :: Parser AutogenId pAutogenId :: Parser AutogenId
pAutogenId = AutogenId <$> (char '$' *> many1 pNonWs) pAutogenId = AutogenId <$> (char '$' *> many1 pNonWs)
<?> "AutogenId"
-- values -- values
pValue :: Parser Value pValue :: Parser Value
@ -86,6 +94,7 @@ pValue = do
char '\'' char '\''
value <- many pBinaryDigit value <- many pBinaryDigit
return $ Value (read width) (binaryStringToInt value) return $ Value (read width) (binaryStringToInt value)
<?> "Value"
pDecimalDigit :: Parser Char pDecimalDigit :: Parser Char
pDecimalDigit = oneOf "0123456789" pDecimalDigit = oneOf "0123456789"
@ -93,7 +102,7 @@ pDecimalDigit = oneOf "0123456789"
-- update in the future to support 4 state logic -- update in the future to support 4 state logic
-- by converting x and z to 0 and warning about it. -- by converting x and z to 0 and warning about it.
pBinaryDigit :: Parser Char pBinaryDigit :: Parser Char
pBinaryDigit = oneOf "01" pBinaryDigit = oneOf "01" <?> "BinaryDigit"
pInteger :: Parser Int pInteger :: Parser Int
pInteger = do pInteger = do
@ -103,37 +112,46 @@ pInteger = do
return $ case sign of return $ case sign of
Just _ -> -value Just _ -> -value
Nothing -> value Nothing -> value
<?> "Integer"
-- strings -- strings
pString :: Parser String pString :: Parser String
pString = pString =
between delimiter delimiter parseString between delimiter delimiter parseString
<?> "String"
where where
delimiter = char '"' delimiter = char '"'
parseString = many (pEscapedChar <|> noneOf "\\\"") parseString = many (pEscapedChar <|> noneOf "\\\"")
-- comments -- comments
-- | Removes inline comments starting with '#' while preserving newlines -- | Removes entire comment lines starting with '#' and inline comments
preProcessDiscardComments :: String -> String preProcessDiscardComments :: String -> String
preProcessDiscardComments input = unlines $ map stripComment $ lines input preProcessDiscardComments input =
where unlines $ map stripComment $ filter (not . isCommentLine) $ lines input
-- Strips comments from a single line where
stripComment line = case break (== '#') line of -- Checks if a line is a comment line (starts with '#')
(code, "") -> code -- No comment found isCommentLine line = case dropWhile (== ' ') line of
(code, _) -> code -- Strip everything after '#' ('#':_) -> True -- Line starts with '#'
_ -> False -- Line does not start with '#'
-- Strips inline comments from a single line
stripComment line = case break (== '#') line of
(code, "") -> code -- No comment found
(code, _) -> code -- Strip everything after '#'
-- file -- file
pFile :: Parser File pFile :: Parser File
pFile = File pFile = File
<$> pAutoIdxStmt <$> pAutoIdxStmt
<*> many pModule <*> many pModule
<?> "File"
-- Autoindex statements -- Autoindex statements
pAutoIdxStmt :: Parser AutoIdxStmt pAutoIdxStmt :: Parser AutoIdxStmt
pAutoIdxStmt = AutoIdxStmt pAutoIdxStmt = AutoIdxStmt
<$> (string "autoidx" *> pWs *> <$> (string "autoidx" *> pWs *>
pInteger <* pEolAndAdvanceToNextNonWs) pInteger <* pEolAndAdvanceToNextNonWs)
<?> "AutoIdxStmt"
-- Module -- Module
pModule :: Parser Module pModule :: Parser Module
@ -143,15 +161,18 @@ pModule = do
moduleBody <- pModuleBody moduleBody <- pModuleBody
pModuleEndStmt pModuleEndStmt
return $ Module moduleStmt attrs moduleBody return $ Module moduleStmt attrs moduleBody
<?> "Module"
pModuleStmt :: Parser ModuleStmt pModuleStmt :: Parser ModuleStmt
pModuleStmt = ModuleStmt pModuleStmt = ModuleStmt
<$> (string "module" *> pWs *> <$> (string "module" *> pWs *>
pId <* pEolAndAdvanceToNextNonWs) pId <* pEolAndAdvanceToNextNonWs)
<?> "ModuleStmt"
pModuleBody :: Parser ModuleBody pModuleBody :: Parser ModuleBody
pModuleBody = ModuleBody pModuleBody = ModuleBody
<$> many pModuleBodyVariant <$> many pModuleBodyVariant
<?> "ModuleBody"
pModuleBodyVariant :: Parser ModuleBodyVariant pModuleBodyVariant :: Parser ModuleBodyVariant
pModuleBodyVariant = pModuleBodyVariant =
@ -167,92 +188,125 @@ pModuleBodyVariant =
try (ModuleBodyMemory <$> pMemory ) <|> try (ModuleBodyMemory <$> pMemory ) <|>
try (ModuleBodyCell <$> pCell ) <|> try (ModuleBodyCell <$> pCell ) <|>
(ModuleBodyProcess <$> pProcess ) (ModuleBodyProcess <$> pProcess )
<?> "ModuleBodyVariant"
pParamStmt :: Parser ParamStmt pParamStmt :: Parser ParamStmt
pParamStmt = ParamStmt pParamStmt = ParamStmt
<$> (string "parameter" *> pWs *> pId <* pWs) <$> (string "parameter" *> pWs *> pId <* pWs)
<*> optionMaybe pConstant <*> optionMaybe pConstant
<* pEolAndAdvanceToNextNonWs <* pEolAndAdvanceToNextNonWs
<?> "ParamStmt"
pConstant :: Parser Constant pConstant :: Parser Constant
pConstant = pConstant = p <?> name where
try (ConstantValue <$> pValue ) name = "Constant"
<|> (ConstantInteger <$> pInteger) p =
<|> (ConstantString <$> pString ) try (ConstantValue <$> pValue )
<|> (ConstantInteger <$> pInteger)
<|> (ConstantString <$> pString )
pModuleEndStmt :: Parser () pModuleEndStmt :: Parser ()
pModuleEndStmt = void (string "end") pModuleEndStmt = p <?> name where
name = "ModuleEndStmt"
p =
void (string "end")
-- Attribute statements -- Attribute statements
pAttrStmt :: Parser AttrStmt pAttrStmt :: Parser AttrStmt
pAttrStmt = AttrStmt pAttrStmt = p <?> name where
<$> (string "attribute" *> pWs *> pId) name = "AttrStmt"
<*> (pWs *> pConstant) p =
<* pEolAndAdvanceToNextNonWs AttrStmt
<$> (string "attribute" *> pWs *> pId)
<*> (pWs *> pConstant)
<* pEolAndAdvanceToNextNonWs
-- Signal Specifications -- Signal Specifications
pSigSpec :: Parser SigSpec pSigSpec :: Parser SigSpec
pSigSpec = do pSigSpec = p <?> name where
baseSigSpec <- (SigSpecConstant <$> pConstant) name = "SigSpec"
<|> p =
(SigSpecWireId <$> pWireId) do
<|> baseSigSpec <- (SigSpecConstant <$> pConstant)
pSigSpecConcat <|>
applySlices baseSigSpec (SigSpecWireId <$> pWireId)
<|>
pSigSpecConcat
applySlices baseSigSpec
pSigSpecConcat :: Parser SigSpec pSigSpecConcat :: Parser SigSpec
pSigSpecConcat = do pSigSpecConcat = p <?> name where
char '{' <* pWs name = "SigSpecConcat"
sigspecs <- pSigSpec `sepBy` pWs p =
pWs <* char '}' do
return $ SigSpecConcat sigspecs char '{' <* pWs
sigspecs <- pSigSpec `sepBy` pWs
pWs <* char '}'
return $ SigSpecConcat sigspecs
applySlices :: SigSpec -> Parser SigSpec applySlices :: SigSpec -> Parser SigSpec
applySlices base = do applySlices base = p <?> name where
maybeSlice <- optionMaybe pSlice name = "ApplySlices"
case maybeSlice of p =
Nothing -> return base do
Just slice -> applySlices (SigSpecSlice base slice) maybeSlice <- optionMaybe pSlice
case maybeSlice of
Nothing -> return base
Just slice -> applySlices (SigSpecSlice base slice)
pSlice :: Parser Slice pSlice :: Parser Slice
pSlice = pSlice = p <?> name where
Slice name = "Slice"
<$> (pMaybeWs *> char '[' *> pMaybeWs *> pInteger <* pMaybeWs) p =
<*> (optionMaybe (char ':' *> pInteger) <* pMaybeWs <* char ']') Slice
<$> (pMaybeWs *> char '[' *> pMaybeWs *> pInteger <* pMaybeWs)
<*> (optionMaybe (char ':' *> pInteger) <* pMaybeWs <* char ']')
-- Connections -- Connections
pConnStmt :: Parser ConnStmt pConnStmt :: Parser ConnStmt
pConnStmt = ConnStmt pConnStmt = p <?> name where
<$> (string "connect" *> pWs *> pSigSpec) name = "ConnStmt"
<*> (pWs *> pSigSpec) p =
<* pEolAndAdvanceToNextNonWs ConnStmt
<$> (string "connect" *> pWs *> pSigSpec)
<*> (pWs *> pSigSpec)
<* pEolAndAdvanceToNextNonWs
-- Wires -- Wires
pWire :: Parser Wire pWire :: Parser Wire
pWire = do pWire = p <?> name where
attrs <- many pAttrStmt name = "Wire"
wireStmt <- pWireStmt p = do
return $ Wire wireStmt attrs attrs <- many pAttrStmt
wireStmt <- pWireStmt
return $ Wire wireStmt attrs
pWireStmt :: Parser WireStmt pWireStmt :: Parser WireStmt
pWireStmt = do pWireStmt = p <?> name where
string "wire" <* pWs name = "WireStmt"
options <- many pWireOption <* pWs p = do
wireId <- WireId <$> pId <* pEolAndAdvanceToNextNonWs string "wire" <* pWs
return $ WireStmt wireId options options <- many pWireOption <* pWs
wireId <- WireId <$> pId <* pEolAndAdvanceToNextNonWs
return $ WireStmt wireId options
pWireId :: Parser WireId pWireId :: Parser WireId
pWireId = WireId <$> pId pWireId = p <?> name where
name = "WireId"
p =
WireId <$> pId
pWireOption :: Parser WireOption pWireOption :: Parser WireOption
pWireOption = pWireOption = p <?> name where
try (WireOptionWidth <$> (string "width" *> pWs *> pInteger)) <|> name = "WireOption"
try (WireOptionOffset <$> (string "offset" *> pWs *> pInteger)) <|> p =
try (WireOptionInput <$> (string "input" *> pWs *> pInteger)) <|> try (WireOptionWidth <$> (string "width" *> pWs *> pInteger)) <|>
try (WireOptionOutput <$> (string "output" *> pWs *> pInteger)) <|> try (WireOptionOffset <$> (string "offset" *> pWs *> pInteger)) <|>
try (WireOptionInout <$> (string "inout" *> pWs *> pInteger)) <|> try (WireOptionInput <$> (string "input" *> pWs *> pInteger)) <|>
(string "upto" *> return WireOptionUpto) <|> try (WireOptionOutput <$> (string "output" *> pWs *> pInteger)) <|>
(string "signed" *> return WireOptionSigned) try (WireOptionInout <$> (string "inout" *> pWs *> pInteger)) <|>
(string "upto" *> return WireOptionUpto) <|>
(string "signed" *> return WireOptionSigned)
-- Memories -- Memories
pMemory :: Parser Memory pMemory :: Parser Memory