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
|
, nestedComments = True
|
||||||
, identStart = letter <|> char '_'
|
, identStart = letter <|> char '_'
|
||||||
, identLetter = alphaNum <|> char '_'
|
, identLetter = alphaNum <|> char '_'
|
||||||
, opStart = oneOf "+-*/"
|
, opStart = oneOf "+-*/%"
|
||||||
, opLetter = oneOf "+-*/"
|
, opLetter = oneOf "+-*/%"
|
||||||
, reservedNames = [ "struct", "u32", "i32", "f32" ]
|
, reservedNames = [ "struct", "u32", "i32", "f32", "if", "then", "else" ]
|
||||||
, reservedOpNames = [ "+", "-", "*", "/" ]
|
, reservedOpNames = [ "+", "-", "*", "/", "%" ]
|
||||||
, caseSensitive = True
|
, caseSensitive = True
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue