1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

プログラミング言語を自作してみる②

Last updated at Posted at 2023-08-07

前回の続き

前回からの続きです。
言語処理系などについての事前知識を勉強しながら、chatGPT Claude3.5Sonnet とともに、設計をpest.rsで対話的に作成していきました。
ここまで大体3日ほどでしょうか?
まだまだ策定してるようなので、鋭意更新中です。
最初の設計からはずいぶん変わりました。
本来の言語設計のイメージを固めると、別の言語が出来てので①も更新しました。
(^_^;)

実装段階でなにか問題が出れば、もちろん見直す部分ですが、使用する記号などは明確化されています。

WHITESPACE = _{ " " | "\r" | "\n"}

program = { SOI ~ expression* ~ EOI }

expression = { export }

export = { f_export? ~ assign }
assign = { lambda ~ (f_assign ~ assign)? }
lambda = { product+ ~ (f_lambda ~ lambda)? }
product = { spread ~ (f_product ~ product)? }
spread = { lift ~ (f_spread ~ lift)? }
lift = { f_spread* ~ or_xor }
or_xor = { and ~ ((f_or | f_xor) ~ or_xor)? }
and = { not ~ (f_and ~ and)? }
not = { f_not* ~ compare }
compare = { add ~ (compare_op ~ compare)? }
add = { mul ~ ((f_add | f_sub) ~ add)? }
mul = { power ~ ((f_mul | f_div | f_mod) ~ mul)? }
power = { factorial ~ (f_power ~ power)? }
factorial = { flat ~ f_factorial* }
flat = { apply ~ f_spread* }
apply = { get ~ apply? }
get = { import ~ (f_get ~ get)? }
import = { f_import? ~ block }

block = {
  (f_block* ~ primary)
  | "(" ~ expression ~ ")"
  | "[" ~ expression ~ "]"
  | "{" ~ expression ~ "}"
}

primary = {
    literal
  | point_free
  | partial_application
  | "(" ~ lambda ~ ")"
  | "{" ~ lambda ~ "}"
  | "[" ~ lambda ~ "]"
  | "(" ~ point_free ~ ")"
  | "{" ~ point_free ~ "}"
  | "[" ~ point_free ~ "]"
  | "(" ~ partial_application ~ ")"
  | "{" ~ partial_application ~ "}"
  | "[" ~ partial_application ~ "]"
}

point_free = {
    prefix
  | postfix_point_free
  | infix
  | infix_l
  | infix_r
  | (literal | identifier) ~ infix
  | (literal | identifier) ~ infix_l
  | (literal | identifier) ~ infix_r
  | infix ~ (literal | identifier)
  | infix_l ~ (literal | identifier)
  | infix_r ~ (literal | identifier)
}

postfix_point_free = @{ "_" ~ postfix }
partial_application = { (identifier | point_free) ~ primary* ~ unit }

prefix = { f_not | f_spread }
infix_l = { f_product | f_or | f_xor | f_and | f_add | f_sub | f_mul | f_div | f_mod | f_get }
infix_r = { f_assign | f_lambda | f_power }
postfix = { f_factorial | f_spread }

infix = { compare_op | f_spread}
compare_op = { f_less | f_less_eq | f_eq | f_neq | f_more_eq | f_more }

f_export = { "#" }
f_assign = { ":" }
f_lambda = { "?" }
f_or = { "|" }
f_xor = { ";" }
f_and = { "&" }
f_less = { "<" }
f_less_eq = { "<=" }
f_eq = { "=" | "==" }
f_neq = { "!=" }
f_more_eq = { ">=" }
f_more = { ">" }
f_add = { "+" }
f_sub = { "-" }
f_mul = { "*" }
f_div = { "/" }
f_mod = { "%" }
f_power = { "^" }
f_product = { "," }
f_not = { "!" }
f_spread = { "~" }
f_factorial = { "!" }
f_get = { "'" }
f_import = { "@" }
f_block = { "\t" }

literal = { number | string | char | unit | identifier }
number = { hex | oct | bit | float | uint | int}
uint = @{ ASCII_DIGIT+ }
int = @{ "-"? ~ ASCII_DIGIT+ ~ !(("." ~ ASCII_DIGIT*) | "e" | "E") }
float = @{ 
    "-"? ~ (
        (ASCII_DIGIT+ ~ "." ~ ASCII_DIGIT* ~ (^"e" ~ ("+" | "-")? ~ ASCII_DIGIT+)?) |
        (ASCII_DIGIT+ ~ ^"e" ~ ("+" | "-")? ~ ASCII_DIGIT+) |
        ("." ~ ASCII_DIGIT+ ~ (^"e" ~ ("+" | "-")? ~ ASCII_DIGIT+)?)
    )
}
hex = @{ "0x" ~ ASCII_HEX_DIGIT+ }
oct = @{ "0o" ~ ASCII_OCT_DIGIT+ }
bit = @{ "0b" ~ ASCII_BIN_DIGIT+ }
string = { "`" ~ (!("`" | "\n") ~ (" " | ANY))* ~ "`" }
char = @{ "\\" ~ (NEWLINE | " " | ANY) }
identifier = @{ ASCII_ALPHA ~ (ASCII_ALPHANUMERIC | "_")* }
unit = { "_" | "[]" }

式指向の言語であるための仕様がモリモリです😂
この言語の最大の特徴の一つは、文字列にエスケープシーケンスが必要ないことです。

 `文字列` `は簡単に` `結合できる` \
 `改行も、簡単に…`

次回から、実装にかかりたいと思います。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?