Expression Parser and Parser Config
This commit is contained in:
parent
839e278e43
commit
212eecfdf7
3 changed files with 115 additions and 4 deletions
16
src/Ubc/Parse/Config.hs
Normal file
16
src/Ubc/Parse/Config.hs
Normal file
|
@ -0,0 +1,16 @@
|
|||
module Ubc.Parse.Config
|
||||
( Config(..)
|
||||
, defaultConfig
|
||||
)
|
||||
where
|
||||
|
||||
import Data.Set (Set)
|
||||
import qualified Data.Set as Set
|
||||
|
||||
data Config = Config
|
||||
{ includePaths :: Set FilePath
|
||||
}
|
||||
|
||||
defaultConfig :: Config
|
||||
defaultConfig = Config (Set.singleton ".")
|
||||
|
95
src/Ubc/Parse/Expression.hs
Normal file
95
src/Ubc/Parse/Expression.hs
Normal file
|
@ -0,0 +1,95 @@
|
|||
module Ubc.Parse.Expression
|
||||
( Expression(..)
|
||||
, BinaryOperator(..)
|
||||
, expressionParser
|
||||
)
|
||||
where
|
||||
import Control.Monad ( (<$!>) )
|
||||
import Data.Functor
|
||||
import Text.Parsec.Expr (Operator(Infix), Assoc (AssocLeft), buildExpressionParser)
|
||||
import qualified Ubc.Parse.Language as UbcLanguage
|
||||
import Text.Parsec (ParsecT, (<|>), (<?>), choice, option)
|
||||
|
||||
data Expression = Binary BinaryOperator Expression Expression
|
||||
| ConstantInteger Integer
|
||||
| FunctionCall String [Expression]
|
||||
| Variable String
|
||||
| If Expression Expression (Maybe Expression)
|
||||
deriving (Show)
|
||||
data BinaryOperator = Plus
|
||||
| Minus
|
||||
| Multiply
|
||||
| Divide
|
||||
| Modulo
|
||||
| ShiftLeft
|
||||
| ShiftRight
|
||||
| LessThan
|
||||
| GreaterThan
|
||||
| LessEqual
|
||||
| GreaterEqual
|
||||
| Equal
|
||||
| NotEqual
|
||||
| BitAnd
|
||||
| BitOr
|
||||
| BitXor
|
||||
deriving (Show)
|
||||
|
||||
operatorTable :: Monad m => [[Operator String u m Expression]]
|
||||
operatorTable =
|
||||
[
|
||||
[ Infix (UbcLanguage.reservedOperator "*" >> return (Binary Multiply)) AssocLeft
|
||||
, Infix (UbcLanguage.reservedOperator "/" >> return (Binary Divide)) AssocLeft
|
||||
, Infix (UbcLanguage.reservedOperator "%" >> return (Binary Modulo)) AssocLeft
|
||||
]
|
||||
,
|
||||
[ Infix (UbcLanguage.reservedOperator "+" >> return (Binary Plus)) AssocLeft
|
||||
, Infix (UbcLanguage.reservedOperator "-" >> return (Binary Minus)) AssocLeft
|
||||
]
|
||||
,
|
||||
[ Infix (UbcLanguage.reservedOperator "<<" >> return (Binary ShiftLeft)) AssocLeft
|
||||
, Infix (UbcLanguage.reservedOperator ">>" >> return (Binary ShiftRight)) AssocLeft
|
||||
]
|
||||
,
|
||||
[ Infix (UbcLanguage.reservedOperator ">=" >> return (Binary GreaterEqual)) AssocLeft
|
||||
, Infix (UbcLanguage.reservedOperator "<=" >> return (Binary LessEqual)) AssocLeft
|
||||
, Infix (UbcLanguage.reservedOperator "<" >> return (Binary LessThan)) AssocLeft
|
||||
, Infix (UbcLanguage.reservedOperator ">" >> return (Binary GreaterThan)) AssocLeft
|
||||
]
|
||||
,
|
||||
[ Infix (UbcLanguage.reservedOperator "==" >> return (Binary Equal)) AssocLeft
|
||||
, Infix (UbcLanguage.reservedOperator "!=" >> return (Binary NotEqual)) AssocLeft
|
||||
]
|
||||
,
|
||||
[ Infix (UbcLanguage.reservedOperator "&" >> return (Binary BitAnd)) AssocLeft
|
||||
, Infix (UbcLanguage.reservedOperator "|" >> return (Binary BitOr)) AssocLeft
|
||||
, Infix (UbcLanguage.reservedOperator "^" >> return (Binary BitXor)) AssocLeft
|
||||
]
|
||||
]
|
||||
|
||||
expressionParser :: (Monad m) => ParsecT String u m Expression
|
||||
expressionParser = buildExpressionParser operatorTable termParser <?> "expression"
|
||||
|
||||
termParser :: Monad m => ParsecT String u m Expression
|
||||
termParser = UbcLanguage.parens expressionParser
|
||||
<|> fmap ConstantInteger UbcLanguage.integer
|
||||
<|> expressionIf
|
||||
<|> functionCallOrVariable
|
||||
|
||||
expressionIf :: Monad m => ParsecT String u m Expression
|
||||
expressionIf = do
|
||||
_ <- UbcLanguage.reserved "if"
|
||||
condition <- expressionParser
|
||||
_ <- UbcLanguage.reserved "then"
|
||||
then_ <- expressionParser
|
||||
else_ <- option Nothing (UbcLanguage.reserved "else" >> expressionParser <&> Just)
|
||||
|
||||
return $ If condition then_ else_
|
||||
|
||||
functionCallOrVariable :: Monad m => ParsecT String u m Expression
|
||||
functionCallOrVariable = do
|
||||
name <- UbcLanguage.identifier
|
||||
choice
|
||||
[ FunctionCall name <$!> UbcLanguage.parens (UbcLanguage.commaSeparated expressionParser)
|
||||
, return $ Variable name
|
||||
]
|
||||
|
|
@ -53,10 +53,10 @@ languageDef = LanguageDef {
|
|||
, nestedComments = True
|
||||
, identStart = letter <|> char '_'
|
||||
, identLetter = alphaNum <|> char '_'
|
||||
, opStart = oneOf "+-*/"
|
||||
, opLetter = oneOf "+-*/"
|
||||
, reservedNames = [ "struct", "u32", "i32", "f32" ]
|
||||
, reservedOpNames = [ "+", "-", "*", "/" ]
|
||||
, opStart = oneOf "+-*/%"
|
||||
, opLetter = oneOf "+-*/%"
|
||||
, reservedNames = [ "struct", "u32", "i32", "f32", "if", "then", "else" ]
|
||||
, reservedOpNames = [ "+", "-", "*", "/", "%" ]
|
||||
, caseSensitive = True
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue