4

我为 APL 子集制作了一个语法。

grammar APL;

program: (statement NEWLINE)*;

statement: thing;

assignment: variable LARR thing;

thing: simpleThing
     | complexThing;

escapedThing: simpleThing
            | '(' complexThing ')';

simpleThing: variable    # ThingVariable
           | number      # ThingNumber
           ;

complexThing: unary      # ThingUOp
            | binary     # ThingBOp
            | assignment # ThingAssignment
            ;

variable: CAPITAL;

number: DIGITS;

unary: iota   # UOpIota
     | negate # UOpNegate
     ;
  iota: SMALL_IOTA number;
  negate: TILDA thing;

binary: drop         # BOpDrop
      | select       # BOpSelect
      | outerProduct # BOpOuterProduct
      | setInclusion # BOpSetInclusion
      ;
  drop: left=number SPIKE right=thing;
  select: left=escapedThing SLASH right=thing;
  outerProduct: left=escapedThing OUTER_PRODUCT_OP right=thing;
  setInclusion: left=escapedThing '∊' right=thing;

NEWLINE: [\r\n]+;

CAPITAL: [A-Z];
CAPITALS: (CAPITAL)+;

DIGITS: [0-9]+;

TILDA: '~';
SLASH: '/';

// greek
SMALL_IOTA: 'ι' | '@i';

// arrows
LARR: '←' | '@<-';
SPIKE: '↓' | '@Iv';

OUTER_PRODUCT_OP: '∘.×' | '@o.@x';

现在我想为它创建一个解释器。我正在尝试将clj-antlr与 Clojure 一起使用。我怎么做?

4

1 回答 1

2

正如 Jared314 指出的那样,看看instaparse

这是您创建语法的方式:

(def as-and-bs
(insta/parser
 "S = AB*
  AB = A B
  A = 'a'+
  B = 'b'+"))

这就是你所说的:

(as-and-bs "aaaaabbbaaaabb")

这是默认格式的结果:

[:S
  [:AB [:A "a" "a" "a" "a" "a"] [:B "b" "b" "b"]]
  [:AB [:A "a" "a" "a" "a"] [:B "b" "b"]]]

虽然 ANTLR 确实做得很好,但在 Clojure 世界中,您可以使用 instaparse 删除所有周围的胶水。

于 2013-10-22T03:37:02.320 回答