Parsing dypgen中的模式匹配

Parsing dypgen中的模式匹配,parsing,ocaml,lexical-analysis,ambiguity,Parsing,Ocaml,Lexical Analysis,Ambiguity,我想处理dypgen中的一些歧义。我在手册中找到了一些东西,我想知道我如何使用它。 在手册第5.2点“符号上的模式匹配”中,有一个示例: expr: | expr OP<"+"> expr { $1 + $2 } | expr OP<"*"> expr { $1 * $2 } forest.ml现在具有以下打印功能: let print_forest forest = let rec aux1 t = match t with | Word x -&

我想处理dypgen中的一些歧义。我在手册中找到了一些东西,我想知道我如何使用它。 在手册第5.2点“符号上的模式匹配”中,有一个示例:

expr:
| expr OP<"+"> expr { $1 + $2 }
| expr OP<"*"> expr { $1 * $2 }
forest.ml现在具有以下打印功能:

let print_forest forest =
  let rec aux1 t = match t with
    | Word x
    -> print_string x
    | Noun (x) -> (
        print_string "N [";
        aux1 x;
        print_string " ]")
    | Sg (x) -> (
        print_string "Sg [";
        aux1 x;
        print_string " ]")
    | Pl (x) -> (
        print_string "Pl [";
        aux1 x;
        print_string " ]")
  in
  let aux2 t = aux1 t; print_newline () in
  List.iter aux2 forest;
  print_newline ()
parser_tree.mli包含:

{
open Parse_tree
let dyp_merge = Dyp.keep_all
}

%start main
%layout [' ' '\t']

%%

main : np "." "\n" { $1 }

np:
  |    sg                   {Noun($1)}
  |    pl                   {Noun($1)}

sg: word    <Word("sheep"|"fish")>  {Sg($1)}
sg: word    <Word("cat"|"dog")>  {Sg($1)}
pl: word    <Word("sheep"|"fish")>  {Pl($1)}
pl: word    <Word("cats"|"dogs")>  {Pl($1)}

/* OR try:
    sg: word    <printf>  {Sg($1)}
    pl: word    <printf>  {Pl($1)}
*/

word: 
  | (['A'-'Z' 'a'-'z']+)    {Word($1)}
type tree = 
  | Word        of string
  | Noun        of tree
  | Sg          of tree
  | Pl          of tree
然后你可以确定鱼、羊、猫等的数字

sheep or fish can be singular and plural. cats and dogs cannot.

fish.
N [Sg [fish ] ]
N [Pl [fish ] ]

我对戴普根一无所知,所以我想弄明白

让我们看看我发现了什么

在parser.dyp文件中,可以定义lexer和解析器,也可以使用外部lexer。以下是我所做的:

我的ast如下所示:

parse_prog.mli

type f = 
  | Print of string
  | Function of string list * string * string

type program = f list
prog_parser.dyp

{
  open Parse_prog

  (* let dyp_merge = Dyp.keep_all *)    

  let string_buf = Buffer.create 10
}

%start main

%relation pf<pr

%lexer

let newline = '\n'
let space = [' ' '\t' '\r']
let uident = ['A'-'Z']['a'-'z' 'A'-'Z' '0'-'9' '_']*
let lident = ['a'-'z']['a'-'z' 'A'-'Z' '0'-'9' '_']*

rule string = parse
  | '"' { () }
  | _ { Buffer.add_string string_buf (Dyp.lexeme lexbuf);
      string lexbuf }

main lexer =
  newline | space + -> { () }
  "fun"  -> ANONYMFUNCTION { () }
  lident -> FUNCTION { Dyp.lexeme lexbuf }
  uident -> MODULE { Dyp.lexeme lexbuf }
  '"' -> STRING { Buffer.clear string_buf;
                  string lexbuf;
                  Buffer.contents string_buf }

%parser

main : function_calls eof                                          
   { $1 }

function_calls:
  |                                                                
    { [] }
  | function_call ";" function_calls                               
    { $1 :: $3 }

function_call:
  | printf STRING                                                  
    { Print $2 } pr
  | "(" ANONYMFUNCTION lident "->" printf lident ")" STRING        
    { Print $6 } pf
  | nested_modules "." FUNCTION STRING                             
    { Function ($1, $3, $4) } pf
  | FUNCTION STRING                                                
    { Function ([], $1, $2) } pf
  | "(" ANONYMFUNCTION lident "->" FUNCTION lident ")" STRING      
    { Function ([], $5, $8) } pf

printf:
  | FUNCTION<"printf">                                             
    { () }
  | MODULE<"Printf"> "." FUNCTION<"printf">                        
    { () }

nested_modules:
  | MODULE                                       
    { [$1] }
  | MODULE "." nested_modules                    
    { $1 :: $3 }
例如,对于以下文件:

测试

printf "first print";
Printf.printf "nested print";
Format.eprintf "nothing possible";
(fun x -> printf x) "Anonymous print";
如果我执行
/myexec test
,我将得到以下提示

You want to print : first print
You want to print : nested print
I can't do anything with Format.eprintf("nothing possible")
You want to print : x
------------
所以,TL;DR,这里的手动示例只是为了向您展示,您可以使用已定义的令牌(我从未定义过令牌打印,只是功能)并匹配它们以获得新规则

我希望这是清楚的,我从你的问题中学到了很多;-)

[EDIT]因此,我更改了解析器以匹配您想要观看的内容:

{
      open Parse_prog

      (* let dyp_merge = Dyp.keep_all *)

      let string_buf = Buffer.create 10
    }

    %start main

    %relation pf<pp

    %lexer

    let newline = '\n'
    let space = [' ' '\t' '\r']
    let uident = ['A'-'Z']['a'-'z' 'A'-'Z' '0'-'9' '_']*
    let lident = ['a'-'z']['a'-'z' 'A'-'Z' '0'-'9' '_']*

    rule string = parse
      | '"' { () }
      | _ { Buffer.add_string string_buf (Dyp.lexeme lexbuf);
          string lexbuf }

    main lexer =
      newline | space + -> { () }
      "fun"  -> ANONYMFUNCTION { () }
      lident -> FUNCTION { Dyp.lexeme lexbuf }
      uident -> MODULE { Dyp.lexeme lexbuf }
      '"' -> STRING { Buffer.clear string_buf;
                      string lexbuf;
                      Buffer.contents string_buf }

    %parser

    main : function_calls eof                                          
       { $1 }

    function_calls:
      |                                                                
        { [] } pf
      | function_call <Function((["Printf"] | []), "printf", st)> ";" function_calls
        { (Print st) :: $3 } pp
      | function_call ";" function_calls                               
        { $1 :: $3 } pf


    function_call:
      | nested_modules "." FUNCTION STRING                          
        { Function ($1, $3, $4) }
      | FUNCTION STRING                             
        { Function ([], $1, $2) }
      | "(" ANONYMFUNCTION lident "->" FUNCTION lident ")" STRING
        { Function ([], $5, $8) }

    nested_modules:
      | MODULE                                       
        { [$1] }
      | MODULE "." nested_modules                    
        { $1 :: $3 }
{
打开解析程序
(*让dyp_合并=dyp.keep_all*)
让string_buf=Buffer.create 10
}
%起动总管
%关系pf{()}
“fun”->匿名函数{()}
lident->FUNCTION{Dyp.lexeme-lexbuf}
uident->MODULE{Dyp.lexeme-lexbuf}
“''->STRING{Buffer.clear STRING_buf;
字符串lexbuf;
Buffer.contents字符串_buf}
%分析器
main:函数_调用eof
{ $1 }
函数调用:
|                                                                
{[]}pf
|功能调用”;“函数调用”
{(正版):$3}页
|功能调用”;“函数调用”
{$1::$3}pf
函数调用:
|嵌套的_模块“.”函数字符串
{函数($1,$3,$4)}
|函数字符串
{函数([],$1,$2)}
|“(“匿名函数lident”->“函数lident”)”字符串
{函数([],$5,$8)}
嵌套的\u模块:
|模块
{ [$1] }
|模块“.”嵌套的_模块
{ $1 :: $3 }

在这里,正如您所看到的,我在解析函数时并没有处理函数是打印的这一事实,而是在我将其放入函数列表时处理的。因此,我匹配了由我的解析器构建的
代数类型。
。我希望这个示例对您来说是可以的;-)(但请注意,这是非常不明确的!:-D)

如何解析函数?我使用dypgen的演示作为起点,并使用它们的makefile…语法在.dyp文件中,它确实:.dyp.ml:path_to_dypgen$You want to print : first print You want to print : nested print I can't do anything with Format.eprintf("nothing possible") You want to print : x ------------
{
      open Parse_prog

      (* let dyp_merge = Dyp.keep_all *)

      let string_buf = Buffer.create 10
    }

    %start main

    %relation pf<pp

    %lexer

    let newline = '\n'
    let space = [' ' '\t' '\r']
    let uident = ['A'-'Z']['a'-'z' 'A'-'Z' '0'-'9' '_']*
    let lident = ['a'-'z']['a'-'z' 'A'-'Z' '0'-'9' '_']*

    rule string = parse
      | '"' { () }
      | _ { Buffer.add_string string_buf (Dyp.lexeme lexbuf);
          string lexbuf }

    main lexer =
      newline | space + -> { () }
      "fun"  -> ANONYMFUNCTION { () }
      lident -> FUNCTION { Dyp.lexeme lexbuf }
      uident -> MODULE { Dyp.lexeme lexbuf }
      '"' -> STRING { Buffer.clear string_buf;
                      string lexbuf;
                      Buffer.contents string_buf }

    %parser

    main : function_calls eof                                          
       { $1 }

    function_calls:
      |                                                                
        { [] } pf
      | function_call <Function((["Printf"] | []), "printf", st)> ";" function_calls
        { (Print st) :: $3 } pp
      | function_call ";" function_calls                               
        { $1 :: $3 } pf


    function_call:
      | nested_modules "." FUNCTION STRING                          
        { Function ($1, $3, $4) }
      | FUNCTION STRING                             
        { Function ([], $1, $2) }
      | "(" ANONYMFUNCTION lident "->" FUNCTION lident ")" STRING
        { Function ([], $5, $8) }

    nested_modules:
      | MODULE                                       
        { [$1] }
      | MODULE "." nested_modules                    
        { $1 :: $3 }