@@ -3,7 +3,8 @@
6−To run our parser we call 'parse'. This requires a Grammar and the output from the lexer (a list of tokens).
6+To run our parser we call 'parse'. This requires a Grammar and the output
7+from the lexer (a list of tokens).
8.. code-block:: idris
9.. code-block:: idris
@@ -18,8 +19,9 @@ If successful this returns 'Right' with a pair of
18otherwise it returns 'Left' with the error message.
19otherwise it returns 'Left' with the error message.
20So we need to define the Grammar for our parser, this is done using the following
21So we need to define the Grammar for our parser, this is done using the following
21−'Grammar' data structure. This is a combinator structure, similar in principle to the
22+'Grammar' data structure. This is a combinator structure, similar in principle
22−recogniser combinator for the lexer, which was discussed on the previous page.
23+to the recogniser combinator for the lexer, which was discussed on the
24As with the Recogniser the Grammar type is dependent on a boolean 'consumes'
26As with the Recogniser the Grammar type is dependent on a boolean 'consumes'
25value which allows us to ensure that complicated Grammar structures will always
27value which allows us to ensure that complicated Grammar structures will always
@@ -111,8 +113,8 @@ parse which takes two parameters:
111 (Integer, List (TokenData ExpressionToken))
113 (Integer, List (TokenData ExpressionToken))
112 test1 s = parse intLiteral (fst (lex expressionTokens s))
114 test1 s = parse intLiteral (fst (lex expressionTokens s))
114−As required, if we pass it a string which is a number literal then it will return the
116+As required, if we pass it a string which is a number literal then it will
115−number in the 'Right' option.
117+return the number in the 'Right' option.
117.. code-block:: idris
119.. code-block:: idris
@@ -260,7 +262,8 @@ token lists are not:
261.. list-table::
263.. list-table::
263− * - Now we can generate a Grammar for an expression inside parenthesis like this.
265+ * - Now we can generate a Grammar for an expression inside parenthesis
265 - .. code-block:: idris
268 - .. code-block:: idris
@@ -281,7 +284,8 @@ value from the inner expression.
281 expr = (add expr (op "+") expr)
284 expr = (add expr (op "+") expr)
283This is a potentially infinite structure which is not total.
286This is a potentially infinite structure which is not total.
287+In order to work up to this gradually I will start with prefix operators
284−In order to work up to this gradually I will start with prefix operators (sometimes known as Polish notation) then modify later for infix operators.
288+(sometimes known as Polish notation) then modify later for infix operators.
286.. list-table::
290.. list-table::
@@ -490,16 +494,20 @@ If we have a rule like this:
491 A -> (x<*>y) <|> (x<*>z)
495 A -> (x<*>y) <|> (x<*>z)
493−If 'x<*>y' fails but 'x<*>z' would succeed a problem is that, 'x<*>y' has already consumed 'x', so now 'x<*>z' will fail.
497+If 'x<*>y' fails but 'x<*>z' would succeed a problem is that, 'x<*>y' has
498+already consumed 'x', so now 'x<*>z' will fail.
500+so we could write code to backtrack. That is 'try' 'x<*>y' without consuming
495−so we could write code to backtrack. That is 'try' 'x<*>y' without consuming so that, if the first token succeeds but the following tokens fail, then the first tokens would not be consumed.
501+so that, if the first token succeeds but the following tokens fail, then the
502+first tokens would not be consumed.
497Another approach is left factoring:
504Another approach is left factoring:
499Left Factoring
506Left Factoring
500--------------
507--------------
502−Replace the rule with two rules (that is we add a non-terminal symbol) so for example, instead of:
509+Replace the rule with two rules (that is we add a non-terminal symbol) so
510+for example, instead of:
504.. code-block:: idris
512.. code-block:: idris
@@ -512,9 +520,11 @@ we add an extra rule to give:
512 A -> x<*>N
520 A -> x<*>N
513 N -> y <|> z
521 N -> y <|> z
515−That is we convert a general context-free grammar to a LL(1) grammar. Although not every context-free grammar can be converted to a LL(1) grammar.
523+That is we convert a general context-free grammar to a LL(1) grammar. Although
524+not every context-free grammar can be converted to a LL(1) grammar.
517−This still does not solve the infinite recursion issue and there is another problem: the precedence of the operators +, - and * is not explicit.
526+This still does not solve the infinite recursion issue and there is another
527+problem: the precedence of the operators +, - and * is not explicit.
519To resolve this we can alter the example like this:
529To resolve this we can alter the example like this: