小编gur*_*aku的帖子

如何在Yesod中为外键的应用表单定义字段?

如果我们在模型文件中定义了2个简单对象,例如: -

Person
  name Text
  Age Int
Book
  title Text
  author Text
Run Code Online (Sandbox Code Playgroud)

我们可以为Book定义一个适用表格: -

addBookForm = renderDivs $ Book
  <$> areq textField "title" Nothing
  <*> areq textField "author" Nothing
Run Code Online (Sandbox Code Playgroud)

但是,如果我们想要将作者从一个文本字段更改为一个人的id,则:

Book
  title Text
  author PersonId
Run Code Online (Sandbox Code Playgroud)

然后上面的表格将无法编译,出现此错误: -

Couldn't match expected type `KeyBackend Database.Persist.GenericSql.Raw.SqlBackend Person' with actual type `Text'
Expected type: Field
                 sub0
                 master0
                 (KeyBackend Database.Persist.GenericSql.Raw.SqlBackend Person)
  Actual type: Field sub0 master0 Text
In the first argument of `areq', namely `textField'
In the second argument of `(<*>)', namely
  `areq textField "author" …
Run Code Online (Sandbox Code Playgroud)

haskell yesod

6
推荐指数
1
解决办法
466
查看次数

如何使用Red或Rebol解析和翻译DSL

我试图看看我是否可以使用Red(或Rebol)来实现一个简单的DSL.我想将我的DSL编译为另一种语言的源代码,可能是Red或C#或两者 - 而不是直接解释和执行它.

DSL只有几个简单的语句,加上一个if/else语句.语句可以分为规则.规则将被转换为函数定义,每个语句都是目标语言中的等效语句.

Red/Rebol中的解析功能很棒,让我可以非常轻松地实现解析器 - 实际上它基本上只是语法本身的定义.

但是,我无法找到如何采取后续步骤的任何示例,特别是处理if语句并将其转换为其他源代码.翻译if语句似乎是一个很小的例子,但仍然有点棘手 - 因为在Red中有一个else意味着你需要将if改为其中一个,而不仅仅是一个额外的可选else.

传统上,在解析期间,我将构建一个抽象语法树,然后具有在AST上操作并生成新源代码的函数.我应该遵循同样的方法还是在Red中还有其他一些更惯用的方法?

我已经尝试在我的解析规则中使用collect/keep来返回嵌套块的块,这实际上形成了AST.另一种方法是将数据保存到表示不同语句等的特定对象中.

我仍然要处理收集/保留,以及何时创建新块以及将保留什么.我还想让我的解析器规则尽可能"干净",其中很少有其他代码交织在一起.所以我仍然不确定如何在解析规则的圆括号中添加红色代码.即使规则最终失败,过早添加代码也会导致Red代码被执行.添加代码太晚意味着代码可能无法按照您期望的顺序执行,尤其是在处理多级语句(如if,可能包含其他语句)时.

因此,特别是,如何将我的示例DSL转换为红色源代码的任何帮助将不胜感激.在Red或Rebol中实现这样的DSL的任何链接都会很棒!:)

这是我的解析规则: -

Red [
    Purpose: example rules for parsing a simple language
]

SimpleLanguageParser: make object! [
    Expr: [string! | integer! | block!]
    Data: ['Person.AGE | 'Person.INCOME]
    WriteMessageToLog: ['write 'message 'to 'log Expr]
    SetData: ['set 'data  Data '= Expr]
    IfStatement: ['if Expr [any Statement] opt ['else [any Statement]] 'endif]
    Statement: [WriteMessageToLog | SetData | IfStatement]

    Rule: [
        'rule word!
        [any Statement]
        'endrule
    ]

    AnySimpLeLanguage: [Rule | …
Run Code Online (Sandbox Code Playgroud)

dsl parsing rebol red

6
推荐指数
1
解决办法
788
查看次数

标签 统计

dsl ×1

haskell ×1

parsing ×1

rebol ×1

red ×1

yesod ×1