Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Parsing 一元负号会搞砸解析_Parsing_Haskell_Parsec - Fatal编程技术网

Parsing 一元负号会搞砸解析

Parsing 一元负号会搞砸解析,parsing,haskell,parsec,Parsing,Haskell,Parsec,以下是要分析的语言id的语法: expr ::= val | const | (expr) | unop expr | expr binop expr var ::= letter const ::= {digit}+ unop ::= - binop ::= /*+- 我用的是一个例子 这里没有显示语义和令牌解析器 exprparser = buildExpressionParser table term <?> "expression" table = [ [Prefix (

以下是要分析的语言id的语法:

expr ::= val | const | (expr) | unop expr | expr binop expr
var ::= letter
const ::= {digit}+
unop ::= -
binop ::= /*+-
我用的是一个例子

这里没有显示语义和令牌解析器

exprparser = buildExpressionParser table term <?> "expression"

table = [ [Prefix (m_reservedOp "-" >> return (Uno Oppo))] 
         ,[Infix (m_reservedOp "/"  >> return (Bino Quot)) AssocLeft
          ,Infix (m_reservedOp "*"  >> return (Bino Prod)) AssocLeft]
         ,[Infix (m_reservedOp "-"  >> return (Bino Diff)) AssocLeft
          ,Infix (m_reservedOp "+"  >> return (Bino Somm)) AssocLeft]
        ]

term = m_parens exprparser
       <|> fmap Var m_identifier
       <|> fmap Con m_natural

exprparser=buildExpressionParser表术语“表达式”
表=[[前缀(m_reservedOp“-”>>返回(Uno Oppo))]
,[Infix(m_reservedOp”/“>>return(Bino Quot))AssocLeft
,中缀(m_reservedOp“*”>>返回(Bino Prod))AssocLeft]
,[Infix(m_reservedOp“-”>>返回(Bino Diff))AssocLeft
,中缀(m_reservedOp“+”>>return(Bino-Somm))AssocLeft]
]
术语=m_parens exprparser
fmap Var m_标识符
fmap Con m_natural
减号字符出现两次,一次作为一元运算符,一次作为二元运算符

在输入
“1--2”
时,解析器只给出
Con 1

而不是预期的
“一号会议(二号会议))”


欢迎提供任何帮助。

reservedOp的目的是创建一个解析器(您将其命名为
m_reservedOp
),解析给定的运算符符号字符串,同时确保它不是较长的运算符符号字符串的前缀。您可以从源代码中的
reservedOp
定义中看到这一点:

reservedOp name =
    lexeme $ try $
    do{ _ <- string name
      ; notFollowedBy (opLetter languageDef) <?> ("end of " ++ show name)
      }
使用
GenTokenParser
对象创建的词素(空格吸收)解析器包括:

  • 标识符
    -解析未知的用户定义标识符。它解析从
    identStart
    后跟零个或多个
    identLetter
    s到第一个非
    identLetter
    的字符。(它从不解析部分标识符,因此它不会在表上留下更多的
    identLetter
    s。)此外,它检查标识符是否不在列表
    reservedNames
  • symbol
    -解析给定字符串。如果字符串是保留字,则不会检查它是否不是较大有效标识符的一部分。因此,“的“
    符号”将匹配
    前台=“黑色”
    的开头,这很少是您想要的。请注意,
    symbol
    不使用
    identStart
    identLetter
    reservedNames
  • reserved
    -解析给定字符串,然后确保其后面没有
    identLetter
    。因此,
    m_reserved”for“
    将解析
    for(i=1;…
    但不解析
    foreground=“black”
    。通常,提供的字符串将是一个有效标识符,但没有对此进行检查,因此您可以编写
    m_reserved“15”
    如果您愿意--在一种具有常见字母数字标识符的语言中,如果后面没有字母或其他数字,则将解析
    “15”
    。此外,可能有点奇怪,没有检查所提供的字符串是否在
    保留名称中
如果这对您有意义,则操作员设置遵循完全相同的模式。相关设置包括:

opStart          -- parser for first character of valid operator
opLetter         -- valid second and following operator chars, for multichar operators
reservedOpNames  -- list of reserved operator names not allowed as user-defined operators
而相关的解析器是:

  • 运算符
    -解析一个未知的、用户定义的运算符,该运算符从一个
    操作开始
    ,后跟零个或多个
    操作符
    ,直到第一个非
    操作符
    。因此,
    运算符
    应用于字符串
    “--2”
    将始终使用整个运算符
    ,而不仅仅是前缀
    “-”
    。还要检查结果运算符是否不在
    reservedOpNames
    列表中
  • symbol
    -与标识符完全相同。它解析字符串时不检查或引用
    opStart
    opLetter
    、或
    reservedOpNames
    ,因此
    symbol-“
    将解析字符串的第一个字符
    ”——“
    很好,留下第二个
    ”——”
    字符,供以后的解析器使用
  • reservedOp
    -解析给定的字符串,确保它后面没有
    opLetter
    。因此,
    m_reservedOp“-”
    将解析
    “-x”
    的开头,但不解析
    “--2”
    ,假设
    -
    匹配
    opLetter
    。与以前一样,不检查字符串是否位于
    reservedOpNames

您似乎正在使用Haskell标记器,该标记器在解析开始之前删除了
--2
作为注释。我认为没有:请参见另一个问题:
“-1+-2*3”
给出了
“Uno Oppo(Con 1)”
opStart          -- parser for first character of valid operator
opLetter         -- valid second and following operator chars, for multichar operators
reservedOpNames  -- list of reserved operator names not allowed as user-defined operators