Last active
August 29, 2015 14:05
-
-
Save steinwaywhw/ccf69275822dfa88abcb to your computer and use it in GitHub Desktop.
Custom Precedence Climbing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
grammar FixityTest; | |
@header { | |
import java.util.*; | |
} | |
@members { | |
Map<String, String> fmap = new HashMap<>(); | |
Map<String, Integer> pmap = new HashMap<>(); | |
public int nextp (String op) { | |
String fix = fmap.get(op); | |
Integer p = pmap.get(op); | |
if (fix.equals("infixr")) return p; | |
if (fix.equals("infixl")) return p+1; | |
if (fix.equals("prefix")) return p; | |
if (fix.equals("postfix")) return p+1; | |
if (fix.equals("infix")) return p+1; | |
return 0; | |
} | |
} | |
/* | |
prefix 6 -; | |
infixr 6 ^; | |
infixl 3 + ; | |
infixl 5 * /; | |
infix 1 =; | |
postfix 7 !; | |
1! ! + -2 * 3 ^ 5 ^ 6 + - -4! = 5 = 6; | |
*/ | |
program | |
: (expr[0] ';'| fixity ';')+ | |
; | |
expr [int p] | |
: aexpr | |
( | |
// infixl infixr infix case | |
{(fmap.get(_input.LT(1).getText()).contains("infix")) && pmap.get(_input.LT(1).getText()) >= $p}? | |
op=OPERATOR | |
expr[nextp($op.text)] | |
// infix case, no assoc, stop trying to match more infix operator | |
{!fmap.get($op.text).equals("infix")}? | |
| | |
// postfix case | |
{(fmap.get(_input.LT(1).getText()).equals("postfix")) && pmap.get(_input.LT(1).getText()) >= $p}? | |
OPERATOR | |
)* | |
; | |
// atom expr | |
aexpr | |
: NUMBER | |
| '(' expr[0] ')' | |
| {fmap.get(_input.LT(1).getText()).equals("prefix")}? op=OPERATOR expr[nextp($op.text)] | |
; | |
fixity | |
: f=FIXITY p=NUMBER (op+=OPERATOR)+ | |
{ | |
for (Token t : $op) { | |
fmap.put(t.getText(), $f.text); | |
pmap.put(t.getText(), $p.int); | |
System.out.println (String.format("Putting %s as %s %d", t.getText(), $f.text, $p.int)); | |
} | |
} | |
; | |
FIXITY: 'infix' | 'infixl' | 'infixr' | 'prefix' | 'postfix'; | |
OPERATOR: [!+\-*/^=]+; | |
NUMBER: [1-9] [0-9]*; | |
WS: [ \n\t\r]+ -> skip; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment