Commit bc670752 authored by Alyona Antonova's avatar Alyona Antonova
Browse files

[#557] Make separators between instructions and values mandatory

Problem: TODO

Solution: TODO
parent 4d286f56
Pipeline #396833423 failed with stages
in 16 minutes and 40 seconds
......@@ -54,7 +54,7 @@ primInstr contractParser opParser = label "primitive instruction" $ choice
-- | Parse a sequence of instructions.
ops' :: Parser ParsedOp -> Parser [ParsedOp]
ops' opParser = (braces $ sepEndBy opParser (optional semicolon)) <|> (pure <$> opParser)
ops' opParser = (braces $ sepEndBy opParser semicolon) <|> (pure <$> opParser)
-- Control Structures
......
......@@ -5,8 +5,11 @@
module Morley.Michelson.Parser.Lexer
( lexeme
, mSpace
, mSpace1
, symbol
, symbol'
, symbol1
, symbol1'
, word
, word'
, string'
......@@ -19,9 +22,11 @@ module Morley.Michelson.Parser.Lexer
, varID
) where
import Prelude hiding (try)
import Data.Char (isDigit, isLower, toLower)
import qualified Data.Text as T
import Text.Megaparsec (MonadParsec, Tokens, between, satisfy)
import Text.Megaparsec (MonadParsec, Tokens, between, choice, eof, lookAhead, satisfy, try)
import Text.Megaparsec.Char (lowerChar, space, space1, string)
import qualified Text.Megaparsec.Char.Lexer as L
......@@ -30,13 +35,22 @@ import qualified Morley.Michelson.Untyped as U
-- Lexing
lexeme :: Parser a -> Parser a
lexeme = L.lexeme mSpace
lexeme = L.lexeme mSpace1
mSpace :: Parser ()
mSpace = L.space space1
(L.skipLineComment "#")
(L.skipBlockComment "/*" "*/" >> space >> void (optional semicolon))
mSpace1 :: Parser ()
mSpace1 = choice $
[ try (space >> (L.skipBlockComment "/*" "*/" <|> L.skipLineComment "#") >> space)
, space1
, eof
]
++ map checkFollowing ["}", "{", "]", ")", ",", ";", ":", "."]
where
checkFollowing = void . lookAhead . string
symbol :: Tokens Text -> Parser ()
symbol = void . L.symbol mSpace
......@@ -44,11 +58,17 @@ symbol = void . L.symbol mSpace
symbol' :: Text -> Parser ()
symbol' str = symbol str <|> symbol (T.map toLower str)
symbol1 :: Tokens Text -> Parser ()
symbol1 = void . L.symbol mSpace1
symbol1' :: Text -> Parser ()
symbol1' str = symbol1 str <|> symbol1 (T.map toLower str)
word :: Tokens Text -> a -> Parser a
word str val = symbol str $> val
word str val = symbol1 str $> val
word' :: Tokens Text -> a -> Parser a
word' str val = symbol' str $> val
word' str val = symbol1' str $> val
string' :: (MonadParsec e s f, Tokens s ~ Text) => Text -> f Text
string' str = string str <|> string (T.map toLower str)
......
......@@ -43,16 +43,16 @@ macro opParser = label "macro"
<|> word' "CONSTRUCT" CONSTRUCT <*> someNE ops
<|> word' "VIEW" VIEW <*> ops
<|> word' "VOID" VOID <*> ops
<|> word' "CMP" CMP <*> cmpOp <*> noteDef
<|> (string' "CMP" >> return CMP <*> cmpOp <*> noteDef)
<|> word' "IF_SOME" IF_SOME <*> ops <*> ops
<|> word' "IF_RIGHT" IF_RIGHT <*> ops <*> ops
<|> word' "FAIL" FAIL
<|> word' "ASSERT_CMP" ASSERT_CMP <*> cmpOp
<|> (string' "ASSERT_CMP" >> return ASSERT_CMP <*> cmpOp)
<|> word' "ASSERT_NONE" ASSERT_NONE
<|> word' "ASSERT_SOME" ASSERT_SOME
<|> word' "ASSERT_LEFT" ASSERT_LEFT
<|> word' "ASSERT_RIGHT" ASSERT_RIGHT
<|> word' "ASSERT_" ASSERTX <*> cmpOp
<|> (string' "ASSERT_" >> return ASSERTX <*> cmpOp)
<|> word' "ASSERT" ASSERT
<|> do string' "DI"; n <- num "I"; symbol' "P"; DIIP (n + 1) <$> ops
<|> unpairMac
......@@ -132,8 +132,7 @@ mapCadrMac opParser = do
MAP_CADR a v f <$> ops' opParser
ifCmpMac :: Parser ParsedOp -> Parser Macro
ifCmpMac opParser =
word' "IFCMP" IFCMP <*> cmpOp <*> noteDef <*> ops' opParser <*> ops' opParser
ifCmpMac opParser = string' "IFCMP" >> return IFCMP <*> cmpOp <*> noteDef <*> ops' opParser <*> ops' opParser
tagMac :: Parser Macro
tagMac = do
......
......@@ -72,7 +72,7 @@ t_operator fp = do
typeInner
:: Parser FieldAnn -> Parser (FieldAnn, Ty)
typeInner fp = label "type" $ lexeme $ choice $ (\x -> x fp) <$>
typeInner fp = label "type" $ choice $ (\x -> x fp) <$>
[ t_operator
, t_int, t_nat, t_string, t_bytes, t_mutez, t_bool
, t_keyhash, t_timestamp, t_address
......
......@@ -62,7 +62,7 @@ with a parenthesis, i.e. everything else.
-- | Parse untyped 'ParsedValue'. Take instruction parser as argument
-- to avoid cyclic dependencies between modules, hence ' in its name.
value' :: Parser ParsedOp -> Parser ParsedValue
value' opParser = lexeme $ parensOrTuple opParser <|> valueInnerWithoutParens opParser
value' opParser = parensOrTuple opParser <|> valueInnerWithoutParens opParser
parensOrTuple :: Parser ParsedOp -> Parser ParsedValue
parensOrTuple opParser = parens $ foldr1 U.ValuePair <$> value' opParser `sepBy1` comma
......@@ -79,7 +79,7 @@ seqOrLambda :: Parser ParsedOp -> Parser ParsedValue
seqOrLambda opParser = try (lambdaValue opParser) <|> seqValue opParser
stringLiteral :: Parser ParsedValue
stringLiteral = U.ValueString . unsafeMkMText . toText <$> do
stringLiteral = lexeme $ U.ValueString . unsafeMkMText . toText <$> do
_ <- try $ string "\""
manyTill validChar (string "\"")
where
......@@ -104,7 +104,7 @@ stringLiteral = U.ValueString . unsafeMkMText . toText <$> do
-- It is safe not to use `try` here because bytesLiteral is the only
-- thing that starts from 0x (at least for now)
bytesLiteral :: Parser (U.Value' op)
bytesLiteral = do
bytesLiteral = lexeme $ do
string "0x"
hexdigits <- takeWhileP Nothing Char.isHexDigit
let mBytes = Hex.decodeHex hexdigits
......@@ -114,7 +114,7 @@ bytesLiteral = do
mBytes
intLiteral :: Parser (U.Value' op)
intLiteral = try $ U.ValueInt <$> L.signed pass L.decimal
intLiteral = lexeme $ try $ U.ValueInt <$> L.signed pass L.decimal
unitValue :: Parser ParsedValue
unitValue = word "Unit" U.ValueUnit
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment