Slide 1

Slide 1 text

Meerkat Parsers Anastasia Izmaylova @IAnastassija & Ali Afroozeh @afruze

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

An expression language sealed trait E case class Add(l: E, r: E) extends E case class Mul(l: E, r: E) extends E case class Sub(l: E, r: E) extends E case class Div(l: E, r: E) extends E case class Neg(l: E) extends E case class Pow(l: E, r: E) extends E case class Num(n: Int) extends E

Slide 4

Slide 4 text

An expression language 1*2+3-(1+7+-8)^3

Slide 5

Slide 5 text

An expression language 1*2+3-(1+7+-8)^3 ((1*2)+3)-(((1+7)+(-8))^3)

Slide 6

Slide 6 text

An expression language 1*2+3-(1+7+-8)^3 ((1*2)+3)-(((1+7)+(-8))^3) Sub(Add(Mul(Num(1),Num(2)),Num(3)),Pow(Add(Add(Num(1),Num(7)),Neg(Num(8))),Num(3)))

Slide 7

Slide 7 text

An expression language E ::= E '+' E | E '*' E | E '-' E | E '/' E | '-' E | E '^' E | Num val E: Parser = E ~ '+' ~ E | E ~ '*' ~ E | E ~ '-' ~ E | E ~ '/' ~ E | '-' ~ E | E ~ '^' ~ E | Num BNF-like notation Combinators

Slide 8

Slide 8 text

Parsing as a search problem

Slide 9

Slide 9 text

Left recursion def E(i: Int)(implicit input: String): Result[Tree] = { // E ::= E + E E(i) flatMap { j => . . . // E * E . . . }

Slide 10

Slide 10 text

Left recursion def E(i: Int)(implicit input: String): Result[Tree] = { // E ::= E + E E(i) flatMap { j => . . . // E * E . . . } Left recursion in top-down parsing can lead to non-termination

Slide 11

Slide 11 text

E ::= '-' E | E '*' E | E '+' E | Num '*' > '+' Natural grammars

Slide 12

Slide 12 text

E ::= '-' E | E '*' E | E '+' E | Num E ::= E '+' T | T T ::= T '*' F | F F ::= '-' F | Num '*' > '+' Natural grammars

Slide 13

Slide 13 text

E ::= '-' E | E '*' E | E '+' E | Num E ::= E '+' T | T T ::= T '*' F | F F ::= '-' F | Num E ::= T E1 E1 ::= '+' T E1 | ε T ::= F T1 T1 ::= '*' F | ε F ::= '-' F | Num '*' > '+' Natural grammars

Slide 14

Slide 14 text

E ::= '-' E | E '*' E | E '+' E | Num E ::= E '+' T | T T ::= T '*' F | F F ::= '-' F | Num E ::= T E1 E1 ::= '+' T E1 | ε T ::= F T1 T1 ::= '*' F | ε F ::= '-' F | Num '*' > '+' Natural grammars

Slide 15

Slide 15 text

E ::= '-' E | E '*' E | E '+' E | Num E ::= E '+' T | T T ::= T '*' F | F F ::= '-' F | Num E ::= T E1 E1 ::= '+' T E1 | ε T ::= F T1 T1 ::= '*' F | ε F ::= '-' F | Num '*' > '+' Natural grammars

Slide 16

Slide 16 text

E ::= '-' E | E '*' E | E '+' E | Num E ::= E '+' T | T T ::= T '*' F | F F ::= '-' F | Num E ::= T E1 E1 ::= '+' T E1 | ε T ::= F T1 T1 ::= '*' F | ε F ::= '-' F | Num '*' > '+' Natural grammars

Slide 17

Slide 17 text

Backtracking schemes 1 2 3 2 3 4 3 4 5 5 6 A ::= a b | a c "ac"

Slide 18

Slide 18 text

Backtracking schemes Deterministic (LL(k)) 1 2 3 2 3 4 3 4 5 5 6 A ::= a b | a c "ac"

Slide 19

Slide 19 text

Backtracking schemes Deterministic (LL(k)) 1 2 3 2 3 4 3 4 5 5 6 A ::= a b | a c "ac"

Slide 20

Slide 20 text

Backtracking schemes Deterministic (LL(k)) 1 2 3 2 3 4 3 4 5 5 6 A ::= a b | a c "ac"

Slide 21

Slide 21 text

"abd" Backtracking schemes Local backtracking (PEG) 1 2 3 2 3 4 3 4 5 5 6 A ::= B d B ::= a | ab

Slide 22

Slide 22 text

"abd" Backtracking schemes Local backtracking (PEG) 1 2 3 2 3 4 3 4 5 5 6 A ::= B d B ::= a | ab

Slide 23

Slide 23 text

"abd" Backtracking schemes Local backtracking (PEG) 1 2 3 2 3 4 3 4 5 5 6 A ::= B d B ::= a | ab

Slide 24

Slide 24 text

"abd" Backtracking schemes Local backtracking (PEG) 1 2 3 2 3 4 3 4 5 5 6 A ::= B d B ::= a | ab

Slide 25

Slide 25 text

"abd" Backtracking schemes Local backtracking (PEG) 1 2 3 2 3 4 3 4 5 5 6 A ::= B d B ::= a | ab

Slide 26

Slide 26 text

Nondeterminism and Ambiguity 1*2+3 E E + E E * E 1 2 3

Slide 27

Slide 27 text

Nondeterminism and Ambiguity 1*2+3 E E + E E * E 1 2 3 E E * E E + E 1 2 3 1*(2+3) (1*2)+3

Slide 28

Slide 28 text

Expressivity Deterministic Local Full Left recursion Only LR No combinator ? ✓

Slide 29

Slide 29 text

Deterministic General vs. Adrian Johnstone

Slide 30

Slide 30 text

But general parsing alone is not enough

Slide 31

Slide 31 text

No content

Slide 32

Slide 32 text

• Natural grammar

Slide 33

Slide 33 text

• Natural grammar • Near-linear on near-deterministic grammars

Slide 34

Slide 34 text

Operator Precedence

Slide 35

Slide 35 text

Expression = AssignmentExpression AssignmentExpression = ConditionalExpression | Assignment ConditionalExpression = ConditionalOrExpression | ConditionalOrExpression "?" Expression ":" ConditionalExpression ConditionalOrExpression = ConditionalAndExpression | ConditionalOrExpression "||" ConditionalAndExpression ConditionalAndExpression = InclusiveOrExpression | ConditionalAndExpression "&&" InclusiveOrExpression InclusiveOrExpression = ExclusiveOrExpression | InclusiveOrExpression "|" ExclusiveOrExpression ExclusiveOrExpression = AndExpression | ExclusiveOrExpression "^" AndExpression . . .

Slide 36

Slide 36 text

if (x > 10) { println(x) } Lexing and Parsing

Slide 37

Slide 37 text

if (x > 10) { println(x) } Lexer Lexing and Parsing

Slide 38

Slide 38 text

if (x > 10) { println(x) } Lexer IF ( ID > 10 ) { ID ( ID ) } Lexing and Parsing

Slide 39

Slide 39 text

if (x > 10) { println(x) } Lexer IF ( ID > 10 ) { ID ( ID ) } Lexing and Parsing Whitespace/ Comment

Slide 40

Slide 40 text

if (x > 10) { println(x) } Lexer IF ( ID > 10 ) { ID ( ID ) } Lexing and Parsing Whitespace/ Comment Longest Match

Slide 41

Slide 41 text

if (x > 10) { println(x) } Lexer IF ( ID > 10 ) { ID ( ID ) } Lexing and Parsing Whitespace/ Comment Longest Match Keyword Reservation

Slide 42

Slide 42 text

if (x > 10) { println(x) } Lexer IF ( ID > 10 ) { ID ( ID ) } Lexing and Parsing Whitespace/ Comment Longest Match Keyword Reservation Scannerless Parsing

Slide 43

Slide 43 text

Context-sensitivity • Indentation-sensitive languages • Data protocols

Slide 44

Slide 44 text

Context-sensitivity • Indentation-sensitive languages • Data protocols Data-dependent parsing

Slide 45

Slide 45 text

Meet the Meerkats! Disambiguation Filters General Parsing Combinator-style Parsing

Slide 46

Slide 46 text

Best of both worlds Parser Generators Parser Combinators Flexibility, extensibility Left recursion Cubic bound Operator precedence Scannerless parsing

Slide 47

Slide 47 text

No content

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

A. Afroozeh and A. Izmaylova, Faster, Practical GLL Parsing, CC’15

Slide 50

Slide 50 text

Shared Packed Parse Forest (SPPF) S ::= 'a' S 'b' | 'a' S | 's' "aasb" S, 0, 4 a, 0, 1 S, 1, 3 b, 3, 4 a, 1, 2 S, 2, 3 s, 2, 3 S, 1, 4 S, 0, 4 a, 0, 1 S, 2, 3 s, 2, 3 a, 1, 2 b, 3, 4

Slide 51

Slide 51 text

Shared Packed Parse Forest (SPPF) S ::= 'a' S 'b' | 'a' S | 's' "aasb" S, 0, 4 a, 0, 1 S, 1, 3 b, 3, 4 a, 1, 2 S, 2, 3 s, 2, 3 S, 1, 4 S, 0, 4 a, 0, 1 S, 2, 3 s, 2, 3 a, 1, 2 b, 3, 4 s, 2, 3 s, 2, 3 Figure 1: Two parse trees (left) and their corresponding SPPF (r To enable general context-free parsing in O(n3) without manu ing the grammar, Scott and Johnstone [18] introduced the notio SPPFs, which use additional intermediate nodes. Intermediate the form (L, i, j) where L is a grammar position and i and j are extents. Grammar positions for intermediate nodes are of the fo where |↵| >= 2. For example, S ::= aS · b for the rule S ::= aSb. version of SPPF in Figure 1 is shown in Figure 2. Intermediate similar to nonterminal nodes, can be ambiguous, in which case h one packed nodes as children. S, 0, 4 a, 0, 1 S, 1, 3 b, 3, 4 a, 1, 2 S, 2, 3 s, 2, 3 S, 1, 4 S ::= aS · b, 0, 3 S ::= aS · b, 1, 3 Figure 2: Binarized SPPF Packed nodes in a binarized SPPF are of the form (L, k), where L

Slide 52

Slide 52 text

Parse forest representation sealed trait Tree case class Appl(r: Rule, ts: Seq[Tree]) extends Tree case class Amb(ts: Set[Tree]) extends Tree case class Terminal(name: String) extends Tree ASF+SDF Rascal Spoofax

Slide 53

Slide 53 text

Parse forest representation Amb S ::= a S b S ::= a S "a" S ::= a S "b" "a" S ::= s "s" "a" S ::= a S b "a" S ::= s "b" "s" S ::= 'a' S 'b' | 'a' S | 's' "aasb"

Slide 54

Slide 54 text

Basic Parsers type Parser = (Input,Int,SPPFLookup) => Result[SPPFNode] trait Result[+T] extends ((T => Unit) => Unit) { def map[U](f: T => U): Result[U] def flatMap[U](f: T => Result[U]): Result[U] def orElse[U >: T](r: Result[U]): Result[U] }

Slide 55

Slide 55 text

val E: Nonterminal = syn ( E ~ '*' ~ E | E ~ '+' ~ E | Num ) Basic Parsers

Slide 56

Slide 56 text

val E: Nonterminal = syn ( E ~ '*' ~ E | E ~ '+' ~ E | Num ) Basic Parsers Tony Sloane, dsinfo library

Slide 57

Slide 57 text

val E: Nonterminal = syn ( E ~ '*' ~ E | E ~ '+' ~ E | Num ) 1+2*3 Basic Parsers Tony Sloane, dsinfo library

Slide 58

Slide 58 text

val E: Nonterminal = syn ( E ~ '*' ~ E | E ~ '+' ~ E | Num ) Amb E ::= E * E E ::= E + E E ::= E + E "*" E ::= Num E ::= Num "+" E ::= Num Num ::= [0-9] "1" Num ::= [0-9] "2" Num ::= [0-9] "3" E ::= Num "+" E ::= E * E Num ::= [0-9] "1" E ::= Num "*" E ::= Num Num ::= [0-9] "2" Num ::= [0-9] "3" 1+2*3 Basic Parsers Tony Sloane, dsinfo library

Slide 59

Slide 59 text

Operator parsers val E: Nonterminal = syn ( E ~ '*' ~ E | E ~ '+' ~ E | Num )

Slide 60

Slide 60 text

Operator parsers val E: OperatorNonterminal = syn ( E ~ '*' ~ E | E ~ '+' ~ E | Num )

Slide 61

Slide 61 text

Operator parsers val E: OperatorNonterminal = syn ( left { E ~ '*' ~ E } |> left { E ~ '+' ~ E } | Num )

Slide 62

Slide 62 text

Operator parsers val E: OperatorNonterminal = syn ( left { E ~ '*' ~ E } |> left { E ~ '+' ~ E } | Num )

Slide 63

Slide 63 text

Operator parsers val E: OperatorNonterminal = syn ( left { E ~ '*' ~ E } |> left { E ~ '+' ~ E } | Num )

Slide 64

Slide 64 text

Operator parsers type OperatorNonterminal = (Int,Int) => Nonterminal val E: OperatorNonterminal = syn ( left { E ~ '*' ~ E } |> left { E ~ '+' ~ E } | Num )

Slide 65

Slide 65 text

Operator parsers E(l,r) = [2>=l,2>=r] E(2,2) '*' E(3,3) // 2 | [1>=l,1>=r] E(0,0) '+' E(2,2) // 1 | Num type OperatorNonterminal = (Int,Int) => Nonterminal val E: OperatorNonterminal = syn ( left { E ~ '*' ~ E } |> left { E ~ '+' ~ E } | Num )

Slide 66

Slide 66 text

Operator parsers val E: OperatorNonterminal = syn ( left { E ~ '*' ~ E } |> left { E ~ '+' ~ E } | Num ) E(0,0) ::= E(1,1) + E(2,2) E(1,1) ::= Num "+" E(2,2) ::= E(2,2) * E(3,3) Num ::= [0-9] "1" E(2,2) ::= Num "*" E(3,3) ::= Num Num ::= [0-9] "2" Num ::= [0-9] "3"

Slide 67

Slide 67 text

Semantic actions val E: OperatorNonterminal & Int = syn ( '-' ~ E & { x => -x } |> left { E ~ '*' ~ E } & { case x~y => x*y } |> left { E ~ '+' ~ E } & { case x~y => x+y } | Num ^ { toInt(_) } )

Slide 68

Slide 68 text

Semantic actions val E: OperatorNonterminal & Int = syn ( '-' ~ E & { x => -x } |> left { E ~ '*' ~ E } & { case x~y => x*y } |> left { E ~ '+' ~ E } & { case x~y => x+y } | Num ^ { toInt(_) } )

Slide 69

Slide 69 text

Semantic actions val E: OperatorNonterminal & Int = syn ( '-' ~ E & { x => -x } |> left { E ~ '*' ~ E } & { case x~y => x*y } |> left { E ~ '+' ~ E } & { case x~y => x+y } | Num ^ { toInt(_) } )

Slide 70

Slide 70 text

Semantic actions val E: OperatorNonterminal & Int = syn ( '-' ~ E & { x => -x } |> left { E ~ '*' ~ E } & { case x~y => x*y } |> left { E ~ '+' ~ E } & { case x~y => x+y } | Num ^ { toInt(_) } )

Slide 71

Slide 71 text

Semantic actions val E: OperatorNonterminal & Int = syn ( '-' ~ E & { x => -x } |> left { E ~ '*' ~ E } & { case x~y => x*y } |> left { E ~ '+' ~ E } & { case x~y => x+y } | Num ^ { toInt(_) } )

Slide 72

Slide 72 text

Semantic actions val E: OperatorNonterminal & Int = syn ( '-' ~ E & { x => -x } |> left { E ~ '*' ~ E } & { case x~y => x*y } |> left { E ~ '+' ~ E } & { case x~y => x+y } | Num ^ { toInt(_) } ) Executed post-parse!

Slide 73

Slide 73 text

Whitespace/Comment if (x > 10 ) { println(x) }

Slide 74

Slide 74 text

Whitespace/Comment if (x > 10 ) { println(x) }

Slide 75

Slide 75 text

Whitespace/Comment def ~ (p: Symbol)(implicit layout: Layout): Sequence if (x > 10 ) { println(x) }

Slide 76

Slide 76 text

Whitespace/Comment def ~ (p: Symbol)(implicit layout: Layout): Sequence def ~~ (p: Symbol): Sequence if (x > 10 ) { println(x) }

Slide 77

Slide 77 text

Character-level disambiguation filters val Id = syn ( ('a' -- 'z').+ ) if (x > 10 ) { println(x) }

Slide 78

Slide 78 text

Character-level disambiguation filters val Id = syn ( ('a'--'z').+ \ ("if") ) if (x > 10 ) { println(x) }

Slide 79

Slide 79 text

Character-level disambiguation filters val Id = syn ( ('a'--'z').+ \ ("if") .!>> ("[a-z]".r) ) if (x > 10 ) { println(x) }

Slide 80

Slide 80 text

type DDParser[T] = (Input,Int,SPPFLookup) => Result[(SPPFNode,T)] Data-dependent parsers

Slide 81

Slide 81 text

type DDParser[T] = (Input,Int,SPPFLookup) => Result[(SPPFNode,T)] Data-dependent parsers

Slide 82

Slide 82 text

type DDParser[T] = (Input,Int,SPPFLookup) => Result[(SPPFNode,T)] val L8 = syn ( '~{' ~ Num ~ '+'.? ~ '}' ~ Octet.* ) ~{ 5 } X X X X X Data-dependent parsers

Slide 83

Slide 83 text

type DDParser[T] = (Input,Int,SPPFLookup) => Result[(SPPFNode,T)] val L8 = syn ( '~{' ~ Num ~ '+'.? ~ '}' ~ Octet.* ) def Octets(n: Int, p: Nonterminal) = n match { case 0 => syn ( epsilon ) case 1 => syn ( p ) case _ => syn ( (1 to n-2).foldLeft(p ~ p)((q,_) => q ~ p) ) } ~{ 5 } X X X X X Data-dependent parsers

Slide 84

Slide 84 text

type DDParser[T] = (Input,Int,SPPFLookup) => Result[(SPPFNode,T)] def Octets(n: Int, p: Nonterminal) = n match { case 0 => syn ( epsilon ) case 1 => syn ( p ) case _ => syn ( (1 to n-2).foldLeft(p ~ p)((q,_) => q ~ p) ) } val L8 = syn ( '~{' ~ Num.map(toInt) ~ '+'.? ~ '}' ~ Octet.* ) ~{ 5 } X X X X X Data-dependent parsers

Slide 85

Slide 85 text

type DDParser[T] = (Input,Int,SPPFLookup) => Result[(SPPFNode,T)] def Octets(n: Int, p: Nonterminal) = n match { case 0 => syn ( epsilon ) case 1 => syn ( p ) case _ => syn ( (1 to n-2).foldLeft(p ~ p)((q,_) => q ~ p) ) } val L8 = syn ( '~{' ~ Num.map(toInt) ~ '+'.? ~ '}' ~>> {Octets(_,Octet)} ) ~{ 5 } X X X X X Data-dependent parsers

Slide 86

Slide 86 text

Case study: expression language val E: OperatorNonterminal & E = syn ( right { E ~ "^" ~ E } & { case x~y => Pow(x, y) } |> "-" ~ E & { Neg(_) } |> left ( E ~ "*" ~ E & { case x~y => Mul(x, y) } | E ~ "/" ~ E & { case x~y => Div(x, y) } ) |> left ( E ~ "+" ~ E & { case x~y => Add(x, y) } | E ~ "-" ~ E & { case x~y => Sub(x, y) } ) | "(" ~ E ~ ")" | "[0-9]".r ^ { s => Num(toInt(s)) } ) sealed trait E case class Add(l: E, r: E) extends E case class Mul(l: E, r: E) extends E case class Sub(l: E, r: E) extends E case class Div(l: E, r: E) extends E case class Neg(l: E) extends E case class Pow(l: E, r: E) extends E case class Num(n: Int) extends E

Slide 87

Slide 87 text

Case study: expression language val E: OperatorNonterminal & E = syn ( right { E ~ "^" ~ E } & { case x~y => Pow(x, y) } |> "-" ~ E & { Neg(_) } |> left ( E ~ "*" ~ E & { case x~y => Mul(x, y) } | E ~ "/" ~ E & { case x~y => Div(x, y) } ) |> left ( E ~ "+" ~ E & { case x~y => Add(x, y) } | E ~ "-" ~ E & { case x~y => Sub(x, y) } ) | "(" ~ E ~ ")" | "[0-9]".r ^ { s => Num(toInt(s)) } ) sealed trait E case class Add(l: E, r: E) extends E case class Mul(l: E, r: E) extends E case class Sub(l: E, r: E) extends E case class Div(l: E, r: E) extends E case class Neg(l: E) extends E case class Pow(l: E, r: E) extends E case class Num(n: Int) extends E

Slide 88

Slide 88 text

Case study: expression language val = syn ( right { E ~ |> |> left ( E ~ | E ~ |> left ( E ~ | E ~ | | ) sealed case case case case case case case Associativity groups

Slide 89

Slide 89 text

Case study: expression language val = syn ( right { E ~ |> |> left ( E ~ | E ~ |> left ( E ~ | E ~ | | ) sealed case case case case case case case Associativity groups Other character-level filters

Slide 90

Slide 90 text

Case study: expression language val = syn ( right { E ~ |> |> left ( E ~ | E ~ |> left ( E ~ | E ~ | | ) sealed case case case case case case case Associativity groups Other character-level filters EBNF constructs

Slide 91

Slide 91 text

val Expression: OperatorNonterminal = syn ( Expression ~ "." ~ Identifier | Expression ~ "." ~ "this" | Expression ~ "." ~ "new" ~ TypeArguments.? ~ Identifier ~ TypeArgumentsOrDiamond.? ~ "(" ~ ArgumentList.? ~ ")" ~ ClassBody.? | Expression ~ "." ~ NonWildTypeArguments ~ ExplicitGenericInvocationSuffix | Expression ~ "." ~ "super" ~ ("." ~ Identifier).!.? ~ Arguments | Type ~ "." ~ "class" | "void" ~ "." ~ "class" | Expression ~ "(" ~ ArgumentList.? ~ ")" | Expression ~ "[" ~ Expression ~ "]" |> Expression ~ "++" | Expression ~ "--" |> "+".!>>("+") ~ Expression | "-".!>>("-") ~ Expression | "++" ~ Expression | "--" ~ Expression | "!" ~ Expression | "~" ~ Expression | "new" ~ ClassInstanceCreationExpression | "new" ~ ArrayCreationExpression | "(" ~ PrimitiveType ~ ")" ~ Expression | "(" ~ ReferenceType ~ ")" ~ Expression |> left ( Expression ~ "*" ~ Expression | Expression ~ "/" ~ Expression | Expression ~ "%" ~ Expression ) |> left ( Expression ~ "+".!>>("+") ~ Expression | Expression ~ "-".!>>("-") ~ Expression ) |> left ( Expression ~ "<<" ~ Expression | Expression ~ ">>".!>>(">") ~ Expression | Expression ~ ">>>" ~ Expression ) |> left ( Expression ~ "<".!>>("[=<]".r) ~ Expression | Expression ~ ">".!>>("[=>]".r) ~ Expression | Expression ~ "<=" ~ Expression | Expression ~ ">=" ~ Expression | Expression ~ "instanceof" ~ Type ) |> left ( Expression ~ "==" ~ Expression | Expression ~ "!=" ~ Expression ) |> Expression ~ "&".!>>("&") ~ Expression |> Expression ~ "^" ~ Expression |> Expression ~ "|".!>>("|") ~ Expression |> Expression ~ "&&" ~ Expression |> Expression ~ "||" ~ Expression |> Expression ~ "?" ~ Expression ~ ":" ~ Expression |> Expression ~ AssignmentOperator ~ Expression | "(" ~ Expression ~ ")" | Primary)

Slide 92

Slide 92 text

val Primary: Nonterminal = syn ( PrimaryNoNewArray | ArrayCreationExpression ) val PrimaryNoNewArray: Nonterminal = syn ( Literal | Type ~ "." ~ "class" | "void" ~ "." ~ "class" | "this" | ClassName ~ "." ~ "this" | "(" ~ Expression ~ ")" | ClassInstanceCreationExpression | FieldAccess | MethodInvocation | ArrayAccess ) val Literal: Nonterminal = syn ( IntegerLiteral | FloatingPointLiteral | BooleanLiteral | CharacterLiteral | StringLiteral | NullLiteral ) val IntegerLiteral: Nonterminal = syn ( DecimalIntegerLiteral.!>>(".") | HexIntegerLiteral.!>>(".") | OctalIntegerLiteral | BinaryIntegerLiteral ) val FloatingPointLiteral: Nonterminal = syn ( DecimalFloatingPointLiteral | HexadecimalFloatingPointLiteral ) val ClassInstanceCreationExpression: Nonterminal = syn ( "new" ~ TypeArguments.? ~ TypeDeclSpecifier ~ TypeArguments | (Primary | QualifiedIdentifier).! ~ "." ~ "new" ~ TypeArgum ) val TypeArgumentsOrDiamond: Nonterminal = syn ( "<" ~ ">" | TypeArguments ) val ArgumentList: Nonterminal = syn (Expression.+(",")) val ArrayCreationExpression: Nonterminal = syn ( "new" ~ (PrimitiveType | ReferenceType).! ~ DimExpr.+ ~ ("[ val Expression: OperatorNonterminal = syn ( Expression ~ "." ~ Identifier | Expression ~ "." ~ "this" | Expression ~ "." ~ "new" ~ TypeArguments.? ~ Identifier ~ TypeArgumentsOrDiamond.? ~ "(" ~ ArgumentList.? ~ ")" ~ ClassBody.? | Expression ~ "." ~ NonWildTypeArguments ~ ExplicitGenericInvocationSuffix | Expression ~ "." ~ "super" ~ ("." ~ Identifier).!.? ~ Arguments | Type ~ "." ~ "class" | "void" ~ "." ~ "class" | Expression ~ "(" ~ ArgumentList.? ~ ")" | Expression ~ "[" ~ Expression ~ "]" |> Expression ~ "++" | Expression ~ "--" |> "+".!>>("+") ~ Expression | "-".!>>("-") ~ Expression | "++" ~ Expression | "--" ~ Expression | "!" ~ Expression | "~" ~ Expression | "new" ~ ClassInstanceCreationExpression | "new" ~ ArrayCreationExpression | "(" ~ PrimitiveType ~ ")" ~ Expression | "(" ~ ReferenceType ~ ")" ~ Expression |> left ( Expression ~ "*" ~ Expression | Expression ~ "/" ~ Expression | Expression ~ "%" ~ Expression ) |> left ( Expression ~ "+".!>>("+") ~ Expression | Expression ~ "-".!>>("-") ~ Expression ) |> left ( Expression ~ "<<" ~ Expression | Expression ~ ">>".!>>(">") ~ Expression | Expression ~ ">>>" ~ Expression ) |> left ( Expression ~ "<".!>>("[=<]".r) ~ Expression | Expression ~ ">".!>>("[=>]".r) ~ Expression | Expression ~ "<=" ~ Expression | Expression ~ ">=" ~ Expression | Expression ~ "instanceof" ~ Type ) |> left ( Expression ~ "==" ~ Expression | Expression ~ "!=" ~ Expression ) |> Expression ~ "&".!>>("&") ~ Expression |> Expression ~ "^" ~ Expression |> Expression ~ "|".!>>("|") ~ Expression |> Expression ~ "&&" ~ Expression |> Expression ~ "||" ~ Expression |> Expression ~ "?" ~ Expression ~ ":" ~ Expression |> Expression ~ AssignmentOperator ~ Expression | "(" ~ Expression ~ ")" | Primary)

Slide 93

Slide 93 text

) val InclusiveOrExpression: Nonterminal = syn ( ExclusiveOrExpression | InclusiveOrExpression ~ "|" ~ ExclusiveOrExpression ) val ConditionalAndExpression: Nonterminal = syn ( InclusiveOrExpression | ConditionalAndExpression ~ "&&" ~ InclusiveOrExpression ) val ConditionalOrExpression: Nonterminal = syn ( ConditionalAndExpression | ConditionalOrExpression ~ "||" ~ ConditionalAndExpression ) val ConditionalExpression: Nonterminal = syn ( ConditionalOrExpression | ConditionalOrExpression ~ "?" ~ Expression ~ ":" ~ Conditio ) val AssignmentExpression: Nonterminal = syn ( ConditionalExpression | Assignment ) val Assignment: Nonterminal = syn ( LeftHandSide ~ AssignmentOperator ~ AssignmentExpression ) val LeftHandSide: Nonterminal = syn ( ExpressionName | "(" ~ LeftHandSide ~ ")" | FieldAccess | ArrayAccess ) val AssignmentOperator: Nonterminal = syn ( "=" | "+=" | "-=" | "*=" | "/=" | "&=" | "|=" | "^=" | "%=" | "<<=" | ">>=" | ">>>=" ) val Expression: Nonterminal = syn ( AssignmentExpression ) val Expression: OperatorNonterminal = syn ( Expression ~ "." ~ Identifier | Expression ~ "." ~ "this" | Expression ~ "." ~ "new" ~ TypeArguments.? ~ Identifier ~ TypeArgumentsOrDiamond.? ~ "(" ~ ArgumentList.? ~ ")" ~ ClassBody.? | Expression ~ "." ~ NonWildTypeArguments ~ ExplicitGenericInvocationSuffix | Expression ~ "." ~ "super" ~ ("." ~ Identifier).!.? ~ Arguments | Type ~ "." ~ "class" | "void" ~ "." ~ "class" | Expression ~ "(" ~ ArgumentList.? ~ ")" | Expression ~ "[" ~ Expression ~ "]" |> Expression ~ "++" | Expression ~ "--" |> "+".!>>("+") ~ Expression | "-".!>>("-") ~ Expression | "++" ~ Expression | "--" ~ Expression | "!" ~ Expression | "~" ~ Expression | "new" ~ ClassInstanceCreationExpression | "new" ~ ArrayCreationExpression | "(" ~ PrimitiveType ~ ")" ~ Expression | "(" ~ ReferenceType ~ ")" ~ Expression |> left ( Expression ~ "*" ~ Expression | Expression ~ "/" ~ Expression | Expression ~ "%" ~ Expression ) |> left ( Expression ~ "+".!>>("+") ~ Expression | Expression ~ "-".!>>("-") ~ Expression ) |> left ( Expression ~ "<<" ~ Expression | Expression ~ ">>".!>>(">") ~ Expression | Expression ~ ">>>" ~ Expression ) |> left ( Expression ~ "<".!>>("[=<]".r) ~ Expression | Expression ~ ">".!>>("[=>]".r) ~ Expression | Expression ~ "<=" ~ Expression | Expression ~ ">=" ~ Expression | Expression ~ "instanceof" ~ Type ) |> left ( Expression ~ "==" ~ Expression | Expression ~ "!=" ~ Expression ) |> Expression ~ "&".!>>("&") ~ Expression |> Expression ~ "^" ~ Expression |> Expression ~ "|".!>>("|") ~ Expression |> Expression ~ "&&" ~ Expression |> Expression ~ "||" ~ Expression |> Expression ~ "?" ~ Expression ~ ":" ~ Expression |> Expression ~ AssignmentOperator ~ Expression | "(" ~ Expression ~ ")" | Primary)

Slide 94

Slide 94 text

Operator precedence Left recursion Parse Forest Semantic actions Data- dependency Meerkat Parsers A @IAnastassija & A @afruze Scannerless Parsing https://github.com/Anastassija/Meerkat