diff options
Diffstat (limited to 'lib/parser.mly')
| -rw-r--r-- | lib/parser.mly | 91 | 
1 files changed, 91 insertions, 0 deletions
| diff --git a/lib/parser.mly b/lib/parser.mly new file mode 100644 index 0000000..c506e9c --- /dev/null +++ b/lib/parser.mly @@ -0,0 +1,91 @@ + +%{ +     + +    module T = Qsp_syntax.T + +    let dummy_pos = (Lexing.dummy_pos, Lexing.dummy_pos) + +%} + +%parameter<Analyzer: Qsp_syntax.S.Analyzer> +%start <Analyzer.Location.repr>main + +%%  + +main:  +    | EOL* +      LOCATION_START  +      EOL+ +      expressions = line_statement* +      LOCATION_END  +      EOL* +      EOF  +    {  +        Analyzer.Location.location $loc expressions +    } + +(* All these statement should terminate with EOL *) +line_statement: +    | COMMENT EOL+ { Analyzer.Instruction.comment $loc } +    | COLUMN i=IDENT EOL* { Analyzer.Instruction.location $loc i } +    | s = terminated(instruction, line_sep)  +    | s = terminated(inline_action, line_sep) +        { s } +    | a = action_bloc(IF, elif_else_body)  +      { let loc, expression, statements, loc_s, body = a in  +        let elifs, else_ = match body with  +        | None -> [], [] +        | Some (elifs, else_) -> (elifs, else_) +        in +        Analyzer.Instruction.if_ +            loc  +            (loc_s, expression, statements)  +            ~elifs +            ~else_ +      } +    | a = action_bloc(ACT, empty_body)  +      { let loc, label, statements, _, _ = a in  +        Analyzer.Instruction.act loc ~label statements +      } + +(** Represent an instruction which can either be on a single line,  +    or created in a block until an END  + *) +%inline action_bloc(TOKEN, BODY): +    | TOKEN +      e = expression  +      COLUMN EOL+ +      s = line_statement* +      b = BODY +      END TOKEN? +      line_sep +      { $loc, e, s, $loc(s), b } + +empty_body: +    | { None } + +elif: +    | ELIF +      e = expression  +      COLUMN EOL+ +      s = line_statement* +      { $loc, e, s } + +else_: +    | ELSE EOL+ +      expressions = line_statement* +      { expressions } +    | { [] } + + +elif_else_body:  +    | elifs = elif* +      else_ = else_ +      { Some (elifs, else_) } + + +%inline line_sep: +    | EOL+ +    | AMPERSAND+ EOL* +    {} | 
