为什么此 fsyacc 输入生成无法编译的 F#?

发布于 2024-12-13 16:13:55 字数 2050 浏览 1 评论 0原文

我的 fsyacc 代码给出编译器错误,表示未找到变量,但我不确定为什么。我希望有人能指出这个问题。

%{
open Ast
%}


// The start token becomes a parser function in the compiled code:
%start start

// These are the terminal tokens of the grammar along with the types of
// the data carried by each token:
%token NAME
%token ARROW TICK VOID
%token LPAREN RPAREN
%token EOF

// This is the type of the data produced by a successful reduction of the 'start'
// symbol:
%type < Query > start

%%

// These are the rules of the grammar along with the F# code of the 
// actions executed as rules are reduced.  In this case the actions 
// produce data using F# data construction terms.
start: Query { Terms($1) }

Query:
    | Term EOF                  { $1 }

Term: 
    | VOID                      { Void }
    | NAME                      { Conc($1) }
    | TICK NAME                 { Abst($2) }
    | LPAREN Term RPAREN        { Lmda($2) }
    | Term ARROW Term           { TermList($1, $3) }

线路 | NAME {Conc($1)} 和以下行都给出此错误:

  error FS0039: The value or constructor '_1' is not defined

我理解语法问题,但 yacc 输入有什么问题?

如果有帮助,这里是 Ast 定义:

namespace Ast
open System

type Query =
    | Terms   of Term

and Term =
    | Void
    | Conc of String
    | Abst of String
    | Lmda of Term
    | TermList of Term * Term

以及 fslex 输入:

{
module Lexer
open System
open Parser
open Microsoft.FSharp.Text.Lexing

let lexeme lexbuf =
    LexBuffer<char>.LexemeString lexbuf
}

// These are some regular expression definitions
let name = ['a'-'z' 'A'-'Z' '0'-'9']
let whitespace = [' ' '\t' ]
let newline = ('\n' | '\r' '\n')

rule tokenize = parse
| whitespace    { tokenize lexbuf }
| newline       { tokenize lexbuf }
// Operators
| "->"          { ARROW }
| "'"           { TICK }
| "void"        { VOID }
// Misc
| "("           { LPAREN }
| ")"           { RPAREN }
// Numberic constants
| name+                                 { NAME }
// EOF
| eof   { EOF }

My fsyacc code is giving a compiler error saying a variable is not found, but I'm not sure why. I was hoping someone could point out the issue.

%{
open Ast
%}


// The start token becomes a parser function in the compiled code:
%start start

// These are the terminal tokens of the grammar along with the types of
// the data carried by each token:
%token NAME
%token ARROW TICK VOID
%token LPAREN RPAREN
%token EOF

// This is the type of the data produced by a successful reduction of the 'start'
// symbol:
%type < Query > start

%%

// These are the rules of the grammar along with the F# code of the 
// actions executed as rules are reduced.  In this case the actions 
// produce data using F# data construction terms.
start: Query { Terms($1) }

Query:
    | Term EOF                  { $1 }

Term: 
    | VOID                      { Void }
    | NAME                      { Conc($1) }
    | TICK NAME                 { Abst($2) }
    | LPAREN Term RPAREN        { Lmda($2) }
    | Term ARROW Term           { TermList($1, $3) }

The line | NAME {Conc($1)} and the following line both give this error:

  error FS0039: The value or constructor '_1' is not defined

I understand the syntactic issue, but what's wrong with the yacc input?

If it helps, here is the Ast definition:

namespace Ast
open System

type Query =
    | Terms   of Term

and Term =
    | Void
    | Conc of String
    | Abst of String
    | Lmda of Term
    | TermList of Term * Term

And the fslex input:

{
module Lexer
open System
open Parser
open Microsoft.FSharp.Text.Lexing

let lexeme lexbuf =
    LexBuffer<char>.LexemeString lexbuf
}

// These are some regular expression definitions
let name = ['a'-'z' 'A'-'Z' '0'-'9']
let whitespace = [' ' '\t' ]
let newline = ('\n' | '\r' '\n')

rule tokenize = parse
| whitespace    { tokenize lexbuf }
| newline       { tokenize lexbuf }
// Operators
| "->"          { ARROW }
| "'"           { TICK }
| "void"        { VOID }
// Misc
| "("           { LPAREN }
| ")"           { RPAREN }
// Numberic constants
| name+                                 { NAME }
// EOF
| eof   { EOF }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

淡莣 2024-12-20 16:13:55

这不是 FsYacc 的错。 NAME 是一个无价值的令牌。

您需要进行以下修复:

%token NAME

%token <字符串>; NAME

|姓名+{姓名}

<代码>| name+ { NAME (lexeme lexbuf) }

现在一切都应该编译了。

This is not FsYacc's fault. NAME is a valueless token.

You'd want to do these fixes:

%token NAME
to
%token <string> NAME

and

| name+ { NAME }
to
| name+ { NAME (lexeme lexbuf) }

Everything should now compile.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文