I think I'm done with Process parsers

This commit is contained in:
Yehowshua Immanuel 2024-12-09 02:34:11 -05:00
parent 43ae657a5b
commit 851a18f82d
3 changed files with 81 additions and 40 deletions

21
TODO.md
View file

@ -29,16 +29,35 @@
with `pEolAndAdvanceToNextNonWs` with `pEolAndAdvanceToNextNonWs`
- [x] Check inline sequencing of whitespace parsers in do blocks. - [x] Check inline sequencing of whitespace parsers in do blocks.
Terminating instances of `pWs` should be preceeded by `<*` Terminating instances of `pWs` should be preceeded by `<*`
- [ ] Verify no backtracking needed when sequencing `many` parsers.
Basically, we want to make sure that the argument of the `many`
parser doesn't conflict(exhibit a partial early match) with
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`
- [ ] Rewrite `pWireStmt` and `pMemoryStmt` using do-notation... - [ ] Rewrite `pWireStmt` and `pMemoryStmt` using do-notation...
- [x] Remove all instances of `_ <-`
- [ ] Module - [ ] Module
- [ ] Remove weird GHC imports
- [ ] Consider the very weird case where the process body has nothing,
thus, `pEolAndAdvanceToNextNonWs` may never get invoked in any of
the sub-parsers encapsulated in `pProcessBody`. Do we need to
advance whitespaces so we can hit `<proc-end-stmt>`?
- [ ] What are the implications for other parsers?
I think that in this case we're OK as `<proc-stmt>` necessarily
precedes `<process-body>` and `<proc-stmt>` terminates in an EOL
parser that advances to the next non-whitespace.
I still need to verify how other parsers behave. For example, what
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 pre-winding 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
are either followed by EOF or a keyword such "module", "autoidx", are either followed by EOF or a keyword such "module", "autoidx",
etc etc

View file

@ -139,7 +139,7 @@ data Process = Process ProcStmt [AttrStmt] ProcessBody
data ProcStmt = ProcStmt Id deriving (Show) data ProcStmt = ProcStmt Id deriving (Show)
data ProcessBody = ProcessBody data ProcessBody = ProcessBody
[AssignStmt] [AssignStmt]
Switch (Maybe Switch)
[AssignStmt] [AssignStmt]
[Sync] [Sync]
deriving (Show) deriving (Show)

View file

@ -37,7 +37,8 @@ import RTLILParser.AST (
CellBodyStmt(..), CellBodyStmt(..),
-- Processes -- Processes
DestSigSpec(..), SrcSigSpec(..), AssignStmt(..), Process(..), ProcStmt(..), ProcessBody(..), AssignStmt(..),
DestSigSpec(..), SrcSigSpec(..),
-- Switches -- Switches
Switch(..), SwitchStmt(..), Case(..), CaseStmt(..), Compare(..), Switch(..), SwitchStmt(..), Case(..), CaseStmt(..), Compare(..),
@ -55,8 +56,6 @@ import RTLILParser.Primitives(
,pEscapedChar ,pEscapedChar
,pEolAndAdvanceToNextNonWs ,pEolAndAdvanceToNextNonWs
) )
import Text.Parsec.Token (GenLanguageDef(caseSensitive))
import GHC.IO.Handle.Types (Handle__(Handle__))
-- 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
@ -76,7 +75,7 @@ pAutogenId = AutogenId <$> (char '$' *> many1 pNonWs)
pValue :: Parser Value pValue :: Parser Value
pValue = do pValue = do
width <- many1 pDecimalDigit width <- many1 pDecimalDigit
_ <- char '\'' char '\''
value <- many pBinaryDigit value <- many pBinaryDigit
return $ Value (read width) (binaryStringToInt value) return $ Value (read width) (binaryStringToInt value)
@ -153,9 +152,9 @@ pSigSpec = do
pSigSpecConcat :: Parser SigSpec pSigSpecConcat :: Parser SigSpec
pSigSpecConcat = do pSigSpecConcat = do
_ <- char '{' <* pWs char '{' <* pWs
sigspecs <- pSigSpec `sepBy` pWs sigspecs <- pSigSpec `sepBy` pWs
_ <- pWs <* char '}' pWs <* char '}'
return $ SigSpecConcat sigspecs return $ SigSpecConcat sigspecs
applySlices :: SigSpec -> Parser SigSpec applySlices :: SigSpec -> Parser SigSpec
@ -186,14 +185,11 @@ pWire = do
return $ Wire wireStmt attrs return $ Wire wireStmt attrs
pWireStmt :: Parser WireStmt pWireStmt :: Parser WireStmt
pWireStmt = pWireStmt = do
WireStmt string "wire" <* pWs
<$ string "wire" options <- many pWireOption <* pWs
<* pWs wireId <- WireId <$> pId <* pEolAndAdvanceToNextNonWs
<*> (WireId <$> pId) return $ WireStmt wireId options
<* pWs
<*> many pWireOption
<* pEolAndAdvanceToNextNonWs
pWireId :: Parser WireId pWireId :: Parser WireId
pWireId = WireId <$> pId pWireId = WireId <$> pId
@ -216,14 +212,12 @@ pMemory = do
return $ Memory memoryStmt attrs return $ Memory memoryStmt attrs
pMemoryStmt :: Parser MemoryStmt pMemoryStmt :: Parser MemoryStmt
pMemoryStmt = pMemoryStmt = do
MemoryStmt (string "memory" <* pWs)
<$ string "memory" options <- (many pMemoryOption <* pWs)
<* pWs memoryId <- MemoryID <$> pId
<*> (MemoryID <$> pId) pEolAndAdvanceToNextNonWs
<* pWs return $ MemoryStmt memoryId options
<*> many pMemoryOption
<* pEolAndAdvanceToNextNonWs
pMemoryOption :: Parser MemoryOption pMemoryOption :: Parser MemoryOption
pMemoryOption = pMemoryOption =
@ -236,17 +230,17 @@ pCell :: Parser Cell
pCell = do pCell = do
attrStmts <- many pAttrStmt attrStmts <- many pAttrStmt
cellStmt <- pCellStmt cellStmt <- pCellStmt
cellBodyStmts <- many pCellBodyStmt cellBodyStmts <- many pCellBodyStmt <* pCellEndStmt
return $ Cell cellStmt attrStmts cellBodyStmts return $ Cell cellStmt attrStmts cellBodyStmts
pCellStmt :: Parser CellStmt pCellStmt :: Parser CellStmt
pCellStmt = do pCellStmt = do
_ <- string "cell" string "cell"
_ <- pWs pWs
cellType <- CellType <$> pId cellType <- CellType <$> pId
_ <- pWs pWs
cellId <- CellId <$> pId cellId <- CellId <$> pId
_ <- pEolAndAdvanceToNextNonWs pEolAndAdvanceToNextNonWs
return $ CellStmt cellId cellType return $ CellStmt cellId cellType
pCellBodyStmt :: Parser CellBodyStmt pCellBodyStmt :: Parser CellBodyStmt
@ -259,7 +253,7 @@ pParameterSign =
pCellBodyParameter :: Parser CellBodyStmt pCellBodyParameter :: Parser CellBodyStmt
pCellBodyParameter = do pCellBodyParameter = do
_ <- string "parameter" <* pWs string "parameter" <* pWs
sign <- optionMaybe pParameterSign <* pMaybeWs sign <- optionMaybe pParameterSign <* pMaybeWs
id <- pId id <- pId
const <- pConstant <* pEolAndAdvanceToNextNonWs const <- pConstant <* pEolAndAdvanceToNextNonWs
@ -267,13 +261,41 @@ pCellBodyParameter = do
pCellBodyConnect :: Parser CellBodyStmt pCellBodyConnect :: Parser CellBodyStmt
pCellBodyConnect = do pCellBodyConnect = do
_ <- string "connect" <* pWs string "connect" <* pWs
id <- pId <* pWs id <- pId <* pWs
sigSpec <- pSigSpec <* pEolAndAdvanceToNextNonWs sigSpec <- pSigSpec <* pEolAndAdvanceToNextNonWs
return $ CellConnect id sigSpec return $ CellConnect id sigSpec
pCellEndStmt :: Parser ()
pCellEndStmt = void (string "end" <* pEolAndAdvanceToNextNonWs)
-- Processes -- Processes
-- pProcessBody :: pProcess :: Parser Process
pProcess = do
attrs <- many pAttrStmt
procStmt <- pProcStmt
processBody <- pProcessBody
pProcEndStmt
return $ Process procStmt attrs processBody
pProcStmt :: Parser ProcStmt
pProcStmt = ProcStmt
<$> (string "process" *> pWs *> pId)
<* pEolAndAdvanceToNextNonWs
pProcessBody :: Parser ProcessBody
pProcessBody = do
-- Since the pAssignStmt parser begins with "assign" and the pSwitch
-- parser technically begins with "attribute", these both starting
-- with the character 'a', we need to be able to rewind failed
-- attempts for `pAssignStmt` and `pSwitch` parsers as the first
-- character being an 'a' would have been consumed.
assignStmtsBefore <- many $ try pAssignStmt
switch <- optionMaybe $ try pSwitch
assignStmtsAfter <- many pAssignStmt
syncs <- many pSync
return $ ProcessBody assignStmtsBefore switch assignStmtsAfter syncs
pAssignStmt :: Parser AssignStmt pAssignStmt :: Parser AssignStmt
pAssignStmt = AssignStmt pAssignStmt = AssignStmt
<$> (string "assign" *> pWs *> pDestSigSpec) <$> (string "assign" *> pWs *> pDestSigSpec)
@ -297,7 +319,7 @@ pSwitch = Switch
pSwitchStmt :: Parser SwitchStmt pSwitchStmt :: Parser SwitchStmt
pSwitchStmt = do pSwitchStmt = do
attrs <- many pAttrStmt attrs <- many pAttrStmt
_ <- string "switch" <* pWs string "switch" <* pWs
sigspec <- pSigSpec <* pEolAndAdvanceToNextNonWs sigspec <- pSigSpec <* pEolAndAdvanceToNextNonWs
return $ SwitchStmt sigspec attrs return $ SwitchStmt sigspec attrs