Search code examples
c++parsingcontext-free-grammarbnf

How to build parse tree?


Have found C++ BNF and there next lines

selection-statement:
    if ( condition ) statement
    if ( condition ) statement else statement

Now trying to write parser. Need to build parse tree. On input i have BNF and source file. But i'm stucked in how i can point my parser what if condition evaluated to true, then it need to execute first statement otherwise else block? Thanks.


Solution

  • Conditional statements have a simple recursive structure. The corresponding recursive descent parser has a similarly simple recursive structure. Abstractly, the interior conditionals are parsed as follows:

    <cond> -> if <expression> then <statement> [else <statement>]
    
    cond :
      a = parse expression
      b = parse statement
      if is_else(token)
        then c = parse statement
             return conditional(a,b,c)
        else return conditional(a,b)
    

    In your example, conditional statements contain blocks of conditionals the last of which contains an else clause. Assuming that the tokenized input sequence has this form and syntactic errors were detected during lexical analysis, the outer conditional is parsed as follows:

    <conditional> -> selection_statement: {<cond>} <cond>
    
    conditional :
      b = new block
      while (iscond(next))
        s = parse cond
        b = insert(s,b)
      return b
    

    Of course, the actual implementation will be significantly more detailed and tedious. However, the preceding describes in outline the construction of a parse tree of a conditional statement having the required form from a tokenized input sequence.

    I just realized you were talking about evaluating the abstract syntax tree. The structure of the function that evaluations a conditional statement is similar to the function that parses a conditional statement. Abstractly,

    cond(input) :
      a = evaluate(if_part(input))
      if is_true(a)
        then evaluate(then_part(input))
        else if(is_else(input))
               then evaluate(else_part(input))
               else return
    

    In order to determine which portion of the conditional to evaluate, you must first evalute the "if" part of the conditional to a Boolean value. If the Boolean value is "true," the "then" part of the conditional is evaluated. If the Boolean value is "false," then the "else" part of the conditional is evaluated. If there is no "else" part, there is nothing to evaluate. Of course, the implementation will be more detailed than the above.