<commit_before>{
module JML (parse) where

import JMLTokens
import Types
}

%name parse
%tokentype { Token }
%error { parseError }

%token
  '('     { TokenOpenParen }
  ')'     { TokenCloseParen }
  '['     { TokenOpenBracket }
  ']'     { TokenCloseBracket }
  ','     { TokenComma }
  '='     { TokenEquals }
  '=>'    { TokenArrow }
  fn      { TokenFn }
  fun     { TokenFun }
  val     { TokenVal }
  const   { TokenConst }
  main    { TokenMain }
  if      { TokenIf }
  then    { TokenThen }
  else    { TokenElse }
  let     { TokenLet }
  in      { TokenIn }
  end     { TokenEnd }
  trace   { TokenTrace }
  op1     { TokenOperator1 $$ }
  op2     { TokenOperator2 $$ }
  num     { TokenNumber $$ }
  bool    { TokenBool $$ }
  id      { TokenIdentifier $$ }

%%

Program : ConstDecls Declarations MainDecl     { ($1, $2, $3) }

ConstDecl : const id '=' Exp       { ($2, $4) }
ConstDecls : ConstDecl ConstDecls  { $1 : $2 }
           |                       { [] }

Declarations : Declaration Declarations { $1 : $2 }
             |                          { [] }
Declaration : FunDecl              { $1 }
            | ValDecl              { $1 }

FunDecl : fun id Pats '=' Exp      { FunDecl $2 $3 $5 }
ValDecl : val Pat '=' Exp          { ValDecl $2 $4 }

MainDecl : main Pats '=' Exp       { MainDecl $2 $4 }

Pats : Pat Pats                    { $1 : $2 }
     |                             { [] }
Pat : id                           { $1 }

AtExp : num                                { Number $1 }
      | bool                               { Boolean $1 }
      | '(' Exp ',' ExpsWithCommasPlus ')' { Tuple ($2 : $4) }
      | '[' ExpsWithCommas ']'             { List $2 }
      | id                                 { Identifier (makeIdentifier $1) }
      | '(' Exp ')'                        { $2 }
      | let LetPat '=' Exp in Exp end      { Let $2 $4 $6 }
      | trace Exp in Exp end               { Trace $2 $4 }

OpExp : AtExp                             { $1 }
      | op1 AtExp                         { Operator1 (stringToOp1 $1) $2 }
      | AtExp op2 OpExp                   { Operator2 (stringToOp2 $2) $1 $3 }
      | AtExp AtExps                      { App $1 $2 }

Exp : OpExp                        { $1 }
    | fn Pats '=>' Exp             { Fn $2 $4 }
    | if Exp then Exp else Exp     { If $2 $4 $6 }

LetPat : id                                 { IdPat $1 }
       | '(' id ',' IdsWithCommasPlus ')'   { TuplePat ($2 : $4) }

IdsWithCommasPlus : id ',' IdsWithCommasPlus { $1 : $3 }
                  | id                       { [$1] }

AtExps : AtExp AtExps                  { $1 : $2 }
       | AtExp                         { [$1] }

ExpsWithCommas : Exp ',' ExpsWithCommas { $1 : $3 }
               | Exp                    { [$1] }
               |                        { [] }

ExpsWithCommasPlus : Exp ',' ExpsWithCommasPlus { $1 : $3 }
                   | Exp ','                    { [$1] }
                   | Exp                        { [$1] }

{

makeIdentifier :: String -> Identifier
makeIdentifier name = name

parseError :: [Token] -> a
parseError tokens = error $ "Parse error at " ++ show (take 20 tokens)

}
<commit_msg>Allow application-expressions on either side of a binary operator.<commit_after>{
module JML (parse) where

import JMLTokens
import Types
}

%name parse
%tokentype { Token }
%error { parseError }

%token
  '('     { TokenOpenParen }
  ')'     { TokenCloseParen }
  '['     { TokenOpenBracket }
  ']'     { TokenCloseBracket }
  ','     { TokenComma }
  '='     { TokenEquals }
  '=>'    { TokenArrow }
  fn      { TokenFn }
  fun     { TokenFun }
  val     { TokenVal }
  const   { TokenConst }
  main    { TokenMain }
  if      { TokenIf }
  then    { TokenThen }
  else    { TokenElse }
  let     { TokenLet }
  in      { TokenIn }
  end     { TokenEnd }
  trace   { TokenTrace }
  op1     { TokenOperator1 $$ }
  op2     { TokenOperator2 $$ }
  num     { TokenNumber $$ }
  bool    { TokenBool $$ }
  id      { TokenIdentifier $$ }

%%

Program : ConstDecls Declarations MainDecl     { ($1, $2, $3) }

ConstDecl : const id '=' Exp       { ($2, $4) }
ConstDecls : ConstDecl ConstDecls  { $1 : $2 }
           |                       { [] }

Declarations : Declaration Declarations { $1 : $2 }
             |                          { [] }
Declaration : FunDecl              { $1 }
            | ValDecl              { $1 }

FunDecl : fun id Pats '=' Exp      { FunDecl $2 $3 $5 }
ValDecl : val Pat '=' Exp          { ValDecl $2 $4 }

MainDecl : main Pats '=' Exp       { MainDecl $2 $4 }

Pats : Pat Pats                    { $1 : $2 }
     |                             { [] }
Pat : id                           { $1 }

AtExp : num                                { Number $1 }
      | bool                               { Boolean $1 }
      | '(' Exp ',' ExpsWithCommasPlus ')' { Tuple ($2 : $4) }
      | '[' ExpsWithCommas ']'             { List $2 }
      | id                                 { Identifier (makeIdentifier $1) }
      | '(' Exp ')'                        { $2 }
      | let LetPat '=' Exp in Exp end      { Let $2 $4 $6 }
      | trace Exp in Exp end               { Trace $2 $4 }

AppExp : AtExp                             { $1 }
       | AtExp AtExps                      { App $1 $2 }

OpExp : AppExp                             { $1 }
      | op1 AppExp                         { Operator1 (stringToOp1 $1) $2 }
      | AppExp op2 OpExp                   { Operator2 (stringToOp2 $2) $1 $3 }

Exp : OpExp                        { $1 }
    | fn Pats '=>' Exp             { Fn $2 $4 }
    | if Exp then Exp else Exp     { If $2 $4 $6 }

LetPat : id                                 { IdPat $1 }
       | '(' id ',' IdsWithCommasPlus ')'   { TuplePat ($2 : $4) }

IdsWithCommasPlus : id ',' IdsWithCommasPlus { $1 : $3 }
                  | id                       { [$1] }

AtExps : AtExp AtExps                  { $1 : $2 }
       | AtExp                         { [$1] }

ExpsWithCommas : Exp ',' ExpsWithCommas { $1 : $3 }
               | Exp                    { [$1] }
               |                        { [] }

ExpsWithCommasPlus : Exp ',' ExpsWithCommasPlus { $1 : $3 }
                   | Exp ','                    { [$1] }
                   | Exp                        { [$1] }

{

makeIdentifier :: String -> Identifier
makeIdentifier name = name

parseError :: [Token] -> a
parseError tokens = error $ "Parse error at " ++ show (take 20 tokens)

}

{'fraction_non_alphanumeric': 0.1271212588707189, 'fraction_numerical': 0.023295279234804074, 'mean_word_length': 1.1360790774299836, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 40, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5465028', 'n_tokens_mistral': 2057, 'n_tokens_neox': 1994, 'n_words': 519}