@@ -598,10 +598,11 @@ problem: the precedence of the operators ``+``, ``-`` and ``*`` is not explicit.
598.. list-table::
598.. list-table::
600 * - To resolve this we can alter the example to have a BNF like this:
600 * - To resolve this we can alter the example to have a BNF like this:
601+ Where braces ``{ ... }`` mean the contents can occur 1 or more times.
602 - .. code-block:: idris
603 - .. code-block:: idris
604− 'expression' ::= ['+'|'-'] 'term' {('+'|'-') 'term'}
605+ 'expression' ::= ('+'|'-') 'term' {('+'|'-') 'term'}
606 'term' ::= 'factor' {'*' 'factor'}
607 'term' ::= 'factor' {'*' 'factor'}
@@ -612,46 +613,44 @@ problem: the precedence of the operators ``+``, ``-`` and ``*`` is not explicit.
613.. code-block:: idris
614.. code-block:: idris
615− paren : Rule Integer -> Rule Integer
616− paren exp = openParen *> exp <* closeParen
618− addInt : Integer -> Integer -> Integer
621− subInt : Integer -> Integer -> Integer
624− multInt : Integer -> Integer -> Integer
628 expr : Rule Integer
616 expr : Rule Integer
631− exprAtom : Rule Integer
618+ factor : Rule Integer
632− exprAtom = intLiteral <|> (paren expr)
619+ factor = intLiteral <|> do
634− partial
621+ r <- expr
635− expr1 : Rule Integer
622+ closeParen
636− expr1 = map multInt exprAtom <*> ((op "*") *> exprAtom)
623+ pure r
639− exprMult : Rule Integer
640− exprMult = expr1 <|> exprAtom
643− expr2 : Rule Integer
625+ term : Rule Integer
644− expr2 = map addInt exprMult <*> ((op "+") *> exprMult)
626+ term = map multInt factor <*> (
631+ expr = map addInt term <*> (
634+ <|> map subInt term <*> (
639+ calc : String -> Either (ParseError (TokenData ExpressionToken))
640+ (Integer, List (TokenData ExpressionToken))
641+ calc s = parse expr (fst (lex expressionTokens s))
646− partial
643+ lft : (ParseError (TokenData ExpressionToken)) -> IO ()
647− exprAdd : Rule Integer
644+ lft (Error s lst) = putStrLn ("error:"++s)
648− exprAdd = expr2 <|> exprMult
650− partial
646+ rht : (Integer, List (TokenData ExpressionToken)) -> IO ()
651− expr3 : Rule Integer
647+ rht i = putStrLn ("right " ++ (show i))
652− expr3 = map subInt exprAdd <*> ((op "-") *> expr)
654− expr = expr3 <|> exprAdd
649+ main : IO ()
653+ either lft rht (calc x) -- eliminator for Either
656As the following tests show, this now handles infix operators and precedence.
655As the following tests show, this now handles infix operators and precedence.
@@ -661,44 +660,41 @@ As the following tests show, this now handles infix operators and precedence.
662 - .. code-block:: idris
661 - .. code-block:: idris
664− *parserExInfix> test "2*3"
663+ *algebraREPL> :exec
665− Right (6,
664+ alg>2*3
666− []) : Either (ParseError (TokenData ExpressionToken))
665+ right (6, [])
667− (Integer, List (TokenData ExpressionToken))
669 * - Check that atomic number literals work:
667 * - Check that atomic number literals work:
671 - .. code-block:: idris
669 - .. code-block:: idris
673− *parserExInfix> test "2"
671+ *algebraREPL> :exec
675− []) : Either (ParseError (TokenData ExpressionToken))
673+ right (2, [])
676− (Integer, List (TokenData ExpressionToken))
678 * - Check that '*' has a higher precedence than '+'.
675 * - Check that '*' has a higher precedence than '+'.
680 - .. code-block:: idris
677 - .. code-block:: idris
682− *parserExInfix> test "2+3*4"
679+ *algebraREPL> :exec
683− Right (14,
680+ alg>2+3*4
684− []) : Either (ParseError (TokenData ExpressionToken))
681+ right (14, [])
685− (Integer, List (TokenData ExpressionToken))
687 * - Also '*' has a higher precedence than '+' when the order is reversed.
683 * - Also '*' has a higher precedence than '+' when the order is reversed.
689 - .. code-block:: idris
685 - .. code-block:: idris
691− *parserExInfix> test "3*4+2"
687+ *algebraREPL> :exec
692− Right (14,
688+ alg>3*4+2
693− []) : Either (ParseError (TokenData ExpressionToken))
689+ right (14, [])
694− (Integer, List (TokenData ExpressionToken))
696 * - Also precedence can be overridden by parenthesis.
691 * - Also precedence can be overridden by parenthesis.
698 - .. code-block:: idris
693 - .. code-block:: idris
700− *parserExInfix> test "(2+3)*4"
695+ *algebraREPL> :exec
701− Right (20,
696+ alg>(2+3)*4
702− []) : Either (ParseError (TokenData ExpressionToken))
697+ right (20, [])
703− (Integer, List (TokenData ExpressionToken))
699+This is still not correct because it does not correctly parse multiple sums or terms
700+like ``1+2+3`` or ``1*2*3``.