1

我用 Alex 和 Happy 构建了一个解析器和词法分析器,它生成了我正在解析的语言的抽象语法树(Solidity)。我现在的问题是如何正确遍历和匹配语言的某些方面。目的是创建一个规则引擎,该引擎将对生成的 AST 执行代码分析,检查特定问题,如函数使用不当、危险调用或缺少某些元素。

这是我的数据的布局,它很高兴作为 AST 输出。(这不是完整的 AST,只是一个快照

 data SourceUnit = SourceUnit PragmaDirective
                  | ImportUnit ImportDirective 
                  | ContractDef ContractDefinition
                  deriving (Show, Eq, Data, Typeable, Ord)

  -- Version Information
  data PragmaDirective = PragmaDirective PragmaName Version Int
                        deriving(Show, Eq, Data, Typeable, Ord)

  data Version = Version String 
                deriving (Show, Eq, Data, Typeable, Ord)

  data PragmaName = PragmaName Ident
                    deriving(Show, Eq, Typeable, Data, Ord)

  data PragmaValue = PragmaValue Dnum
                    deriving(Show, Eq, Data, Typeable, Ord)
  -- File imports/Contract Imports
  data ImportDirective = ImportDir String
                      | ImportMulti Identifier Identifier Identifier String 
                        deriving (Show, Eq, Data, Typeable, Ord)

  -- The definition of an actual Contract Code Block
  data ContractDefinition = Contract Identifier [InheritanceSpec] [ContractConts]
                            deriving (Show, Eq, Data, Typeable, Ord)

  data ContractConts = StateVarDec StateVarDeclaration
               | FunctionDefinition FunctionDef
               | UsingFor UsingForDec
               deriving (Show, Eq, Data, Typeable, Ord)

我目前的思路是通过将 传递[SourceUnit]给函数并针对特定情况进行匹配来使用模式匹配。例如,以下函数匹配代码并返回状态变量声明的数据类型。

  getStateVar :: [SourceUnit] -> Maybe StateVarDeclaration
  getStateVar [SourceUnit _ , ContractDef (Contract _ _ [StateVarDec x]) ] = Just x
  getStateVar _ = Nothing

这会输出以下内容,这部分是我需要的。不幸的是,该语言可能包含多个合同声明,具有多个状态变量声明,所以我认为以这种方式匹配它是完全可能的。

 Main> getStateVar $ runTest "pragma solidity ^0.5.0; contract test { address owner = msg.send;}"
  Just (StateVariableDeclaration (ElementaryTypeName (AddrType "address")) [] (Identifier "owner") [MemberAccess (IdentExpression "msg") "." (Identifier "send")])

我读过一些关于通用编程和“废弃你的样板”的文章,但我不明白它是如何工作的,或者实现它的最佳方法是什么。

问题是,在这种模式匹配方面,我是否走在正确的轨道上,还是有更好的选择?

4

0 回答 0