2016-09-19 2 views
0

J'écris l'analyseur et le grammer en utilisant scala.util.parsing.combinator. Mon entrée est ":za >= 1 alok && :ft == 9"Combinators Scala Parser: Liste d'extrait d'un type

case class Expression(op1:Operand,operator:Operator,op2:Operand) 

def word: Parser[String] = """[a-z\\\s]+""".r ^^ { _.toString } 

def colonWord:Parser[Operand]=":"~> word ^^{case variable => Operand(variable)} 

def constant:Parser[Operand]="""^[a-zA-Z0-9\\\s-]*""".r ^^ {case constant => Operand(constant)} 

def expression:Parser[Expression] = colonWord ~ operator ~ constant ^^{ case op1~operator~op2 => Expression(op1, operator, op2)} 

def expressions = expression ~ opt(" && " ~> expression)* 

mais quand je parse chaîne de l'exemple, le résultat ne devrait pas. La deuxième expression après && n'est pas analysée. Veuillez noter qu'il peut y avoir plusieurs expressions jointes en utilisant &&.

Quand j'Execute:

val expr= ":za >= 1 alok && :ft == 9" 
    parse(expressions, expr) match { 
     case Success(matched, _) => println(matched) 
     case ..} 

sortie est:

List((Expression(za ,>= ,1 alok)~None)) 

Je ne vois pas la deuxième expression en cours d'analyse. Quelqu'un peut-il aider ce que j'ai manqué ici?

EDIT -----------------------------------

Le l'exigence est d'obtenir List[Expression]. quand je dis, incorporting les changements mentionnés à Ans:

def expressions = expression ~ ("&&" ~> expression)* 

Le type de retour des expressions est pas la liste [expression]. Pour exemple: Si j'écris une autre définition:

case class Condition(exprs: List[Expression], st:Statement) 
def condition = expressions ~","~statement ^^{ 
    case exprs~commaa~statement => Condition(exprs,statement) //This is giving error. 

l'erreur est: incompatibilité de type; trouvé: ~ [Expression, Expression]] requis: Expressions. Alors comment convertir [Expression, Expression] en List [Expressions]? Comment convertir une expression [Expression, Expression] en List [Expressions]?

Merci

+0

Dans votre sortie 'Liste ((Expression (za,> =, 1 alok) ~ Aucun))'. Essayez de remarquer cet espace supplémentaire après '1 alok'. Et l'espace supplémentaire est le coupable, car votre prochain analyseur 'expressions' s'attend à ce que deux' expression's soient délimitées par un ' && ' –

+0

C'est pourquoi, c'est une bonne habitude d'avoir '' en tant que membre de première classe de votre grammaire. Ne déprécie jamais l'espace. –

+0

Merci. Oui, c'est le problème. J'ai essayé d'enlever des espaces de && . Cela a fonctionné dans ce cas. Mais j'ai donné une autre expression => ": za> = 1 &&: ft == 9 &&: wq == 12", Dans ce cas, il a fallu 2 expression, plutôt que 3. La sortie que je reçois est List ((Expression (za,> =, 1) ~ Some (Expression (ft, ==, 9)))) – Alok

Répondre

1

La correction nécessaire était:

expression ~ opt("&&" ~> expression)* 

espace Supprimer dans && et il devrait fonctionner. C'est parce que vous couvrez déjà l'espace dans votre parseur constant.

Edit: Sur la base de question éditée, est-ce que vous voulez:

def expressions = expression ~ (("&&" ~> expression)*) ^^{ 
    case x ~ y => x :: y 
    } 

Maintenant, le type de retour est expressionsList[Expression]. Votre condition va maintenant compiler

+0

Merci. Oui, c'est le problème. J'ai essayé d'enlever des espaces de && . Cela a fonctionné dans ce cas. Mais j'ai donné une autre expression => ": za> = 1 &&: ft == 9 &&: wq == 12", Dans ce cas, il a fallu 2 expression, plutôt que 3. La sortie que je reçois est List ((Expression (za,> =, 1) ~ Some (Expression (ft, ==, 9)))) – Alok

+0

Je crois que le problème est aussi avec def expressions = expression ~ opt ("&&" ~> expression) *. Je m'attendais à ce que cela me renvoie List [Expression]. Mais il renvoie [Expression, Option [Expression]] – Alok

+0

car vous avez 'opt' dans' opt ("&&" ~> expression) '. Maintenant que vous utilisez '*', ce qui signifie '0 ou plus', vous n'avez pas besoin de' opt'. –