2009-11-30 93 views
1
import java_cup.runtime.*; 
import java.io.*; 
import java.util.*; 

/* Preliminaries to set up and use the scanner. */ 

parser code {: 
     SMPLLexer lexer; 


     public SMPLParser (SMPLLexer lex) { 
      super(lex); 
      lexer = lex; 
     } 

     public void report_error(String message, Object info) { 
      System.err.println(message + info); 
     } 

     public void syntax_error(Symbol cur_token) { 
      System.err.print("Line " + lexer.getLine() + 
        " near char " + lexer.getChar() + ": "); 
      report_error("Syntax error while reading: ", cur_token); 
      System.err.println ("Last token read is " + 
        lexer.getText()); 
     } 

     public void unrecover_syntax_error(Symbol cur_token) { 
      System.err.println("Line " + lexer.getLine() + 
         "near char " + lexer.getChar() + ": "); 
         syntax_error(cur_token); 
        } 

     :}; 


/* Terminals (tokens returned by the scanner). */ 

// special symbols 
terminal LBRACKET, RBRACKET, LCBRACKET, RCBRACKET, LPAREN, RPAREN, /* LBRACE, RBRACE, */ SEMI, ASSIGN, COLON, COMMA, EMPTYLIST; /*, DOT, AT; */ 

// opeartors: base 
terminal PAIR, CAR, CDR, LIST, SIZE, SUBSTRING, PROC, CALL, LAZY, LET, BE, DEFINE, PRINT, PRINTLN, READ, READINT; 

// operators: equality 
terminal PAIREQ, EQV, EQUAL; 

// commands: commands 
terminal CLEAR, SETBGCOLOR, SETFGCOLOR, PATH, CPATH, PT, CANVAS, RECT, CIRCLE; 

// commands: conditional 
terminal IF, THEN, ELSE, REPEAT; /* , CASE, WHILE, FOR, TRUE, FALSE; */ 

// operators: arithmetic 
terminal PLUS, MINUS, MUL, DIV, MOD, EXPT; 

// operators: relational 
terminal LT, GT, EQ, LTEQ, GTEQ, NOTEQ; 

//operators: logical 
terminal AND, OR, NOT; 

// operators: bitwise 
terminal BITAND, BITOR, INVERT; 

// terminals with values 
terminal Integer INTEGER; 
terminal String STRING; 
terminal String VAR; 
terminal String ID; 

/* Non terminals */ 
// (You're on your own for the IR classes) 
non terminal IRProgram program; 
non terminal IRCmd statement; 
non terminal IRExp expression; 
non terminal IRExp arithExp; 
non terminal IRExp relExp; 
non terminal IRExp logExp; 
non terminal IRExp bitExp; 
non terminal IRExp term; 
non terminal IRExp expt; 
non terminal IRExp factor; 

non terminal ArrayList statementList; 
non terminal IRCmdSeq cmdList; 

non terminal ArrayList varList; 
non terminal ArrayList expList; 
non terminal ArrayList assList; 

// non terminal ArrayList sequence; 
non terminal empty; 


/* Precedence */ 

precedence left OR; 
precedence left AND; 
precedence left NOT; 
precedence left EQ, GT, LT, LTEQ, GTEQ, NOTEQ; 
precedence left BITAND, BITOR; 
precedence left PLUS, MINUS; 
precedence left MUL, DIV, MOD; 
precedence right INVERT; 

/* Grammar rules */ 

start with program; 

program ::= statementList:lst SEMI {: RESULT = new IRProgram(lst); :} | 
         statementList:lst {: RESULT = new IRProgram(lst); :} | 
         STRING:str {: RESULT = new IRCmdSeq(lst); :}       

; 

cmdList ::= statementList:lst {: RESULT = new IRCmdSeq(lst); :}; 

statementList ::= statementList:lst statement:s {:lst.add(s); RESULT = lst; :} | 
        empty {: RESULT = new ArrayList(); :}; 

statement ::= 

    PAIR statement:s1 statement:s2 {: RESULT = new IRPAIR(s1,s2); :} | 

    PAIREQ LPAREN PAIR:p RPAREN {: new IRPAIR(p); :} | 

    CAR varList:s1 {: RESULT = new IRCAR(s1); :} | 

    CDR varList:s1 {: RESULT = new IRCDR(s1); :} | 

    EQV expression:e1 expression:e2 {: RESULT = new IREQV(e1,e2); :} | 

    EQUAL expression:e1 expression:e2 {: RESULT = new IREQUAL(e1,e2); :} | 

    SUBSTRING STRING:v arithExp:e1 arithExp:e2 {: RESULT = new IRSUBSTR(v,e1,e2); :} | 

    SIZE LIST:n {: RESULT = new IRSIZE(n); :} | 

    PROC ID:n cmdList:e {: RESULT = new IRPROC(n,e); :} | 

    CALL expression:e1 cmdList:body {: RESULT = new IRCALL(e1,body); :} | 

    LAZY expression:e1 {: RESULT = new IRLAZY(e1); :} | 

    DEFINE ID:pred expression:e1 {: RESULT = new IRDEFINE(pred,e1); :} | 

    LIST LPAREN varList:s RPAREN {: RESULT = new IRLIST(s); :} | 

    LIST LPAREN LBRACKET varList:s RBRACKET RPAREN {: RESULT = new IRLIST(s); :} | 

    LBRACKET varList:s RBRACKET {: RESULT = new IRLIST(s); :} | 

    LCBRACKET varList:s RCBRACKET {: RESULT = new IRLIST(s); :} | 

    //LBRACKET sequence:s RBRACKET {: RESULT = new IRLIST(s); :} | 

    ID:n ASSIGN expression:n {: RESULT = new IRASSIGN(n); :} | 

    ID:n ASSIGN expList:n {: RESULT = new IRASSIGN(n); :} | 

    LET ID:n BE expression:e {: RESULT = new IRLET(n,e); :} | 


    /** Graphic Components **/ 
    CLEAR {: RESULT = new IRCmdClear(); :} | 

    CANVAS LPAREN arithExp:e1 arithExp:e2 RPAREN {: RESULT = new IRCmdCanvas(e1,e2); :} | 

    PT LPAREN arithExp:e1 arithExp:e2 RPAREN {: RESULT = new IRCmdPT(e1,e2); :} | 

    PATH LPAREN arithExp:e1 arithExp:e2 RPAREN {: RESULT = new IRCmdPath(e1,e2); :} | 

    CIRCLE LPAREN arithExp:e1 arithExp:e2 arithExp:e3 RPAREN {: RESULT = new IRCmdCircle(e1,e2,e3); :} | 

    CPATH LPAREN arithExp:e1 arithExp:e2 RPAREN {: RESULT = new IRCmdCPath(e1,e2); :} | 

    SETFGCOLOR LPAREN arithExp:e1 arithExp:e2 arithExp:e3 RPAREN {: RESULT = new IRCmdSetFG(e1,e2,e3); :} | 

    SETBGCOLOR LPAREN arithExp:e1 arithExp:e2 arithExp:e3 RPAREN {: RESULT = new IRCmdSetBG(e1,e2,e3); :} | 

    RECT LPAREN arithExp:e1 arithExp:e2 arithExp:e3 RPAREN {: RESULT = new IRCmdRect(e1,e2,e3); :} | 


    //conditionals 

    IF expression:pred THEN cmdList:cond ELSE cmdList:alt {: RESULT = new IRCmdIf(pred, cond, alt); :} | 

    // TODO CASE LBRACE expList RBRACE 

    PRINT cmdList:e1 {: RESULT = new IRPRINT(e1); :} | 

    PRINTLN cmdList:e1 {: RESULT = new IRPRINTLN(e1); :} | 

    READ STRING:n {: RESULT = new IRREAD(n); :} | 

    READINT STRING:n {: new IRREADINT(n);:} | 

    //iteration 
    REPEAT arithExp:count cmdList:body {: RESULT = new IRCmdRepeat(count, body); :} | 

    EMPTYLIST {: RESULT = new ArrayList(); :} 

    ; 

varList ::= 
      varList:lst COMMA expression:i COLON PROC:p {: lst.add(new IRVarList(i,p)); RESULT = lst; :} | 
      varList:lst COMMA expression:i {: lst.add(i); RESULT = lst; :} | 
     empty {: RESULT = new ArrayList(); :}; 

// list of expressions 
expList ::= 
      expList:lst COMMA expression:v {: lst.add(v); RESULT = lst; :} | 
      expList:lst expression:v {: lst.add(v); RESULT = lst; :} | 
     empty {: RESULT = new ArrayList(); :}; 

/* 
sequence ::= 
      sequence:s expression:e COMMA {: RESULT = s.add(e); } | 
      sequence:s expression:e {: RESULT = s.add(e); } | 
      empty {: RESULT = new ArrayList(); :}; 
*/   


/* I'm giving you the expression hierarchy already done. (Am I not nice?) */ 
expression ::= 

     arithExp:ae {: RESULT = ae; :} | 
     bitExp:be {: RESULT = be; :} | 
     relExp:re {: RESULT = re; :} | 
     logExp:le {: RESULT = le; :}; 

     //relational expressions 
relExp ::= 

     //relational ops 
     arithExp:e1 EQ arithExp:e2 {: RESULT = new IRExpEq(e1, e2); :} | 
     arithExp:e1 LT arithExp:e2 {: RESULT = new IRExpLt(e1, e2); :} | 
     arithExp:e1 GT arithExp:e2 {: RESULT = new IRExpGt(e1, e2); :} | 
     arithExp:e1 LTEQ arithExp:e2 {: RESULT = new IRExpLtEq(e1, e2); :} | 
     arithExp:e1 GTEQ arithExp:e2 {: RESULT = new IRExpGtEq(e1, e2); :} | 
     arithExp:e1 NOTEQ arithExp:e2 {: RESULT = new IRExpNotEq(e1, e2); :} 
     ; 

logExp ::= 

     //logical ops 
     arithExp:e1 AND arithExp:e2 {: RESULT = new IRExpAnd(e1, e2); :} | 
     arithExp:e1 OR arithExp:e2 {: RESULT = new IRExpOr(e1, e2); :} | 
     arithExp:e1 NOT arithExp:e2 {: RESULT = new IRExpNot(e1, e2); :} 
     ; 

bitExp ::= 

     //bitwise ops 
     arithExp:e1 BITAND arithExp:e2 {: RESULT = new IRExpBitAnd(e1, e2); :} | 
     arithExp:e1 BITOR arithExp:e2 {: RESULT = new IRExpBitOr(e1, e2); :} | 
     arithExp:e1 INVERT arithExp:e2 {: RESULT = new IRExpIvert(e1, e2); :} 
     ; 

     //arithmetic expressions 
arithExp ::= 

     arithExp:e PLUS term:t {: RESULT = new IRExpAdd(e, t); :} | 
     arithExp:e MINUS term:t {: RESULT = new IRExpSub(e, t); :} | 
     term:t {: RESULT = t; :} 

     ; 

term ::= 

    term:t MUL expt:x {: RESULT = new IRExpMul(t, x); :} | 
    term:t MOD expt:x {: RESULT = new IRExpMod(t, x); :} | 
    term:t DIV expt:x {: RESULT = new IRExpDiv(t, x); :} | 
    expt:x {: RESULT = x; :} 

    ; 

expt ::= 
    expt:x EXPT factor:f {: RESULT = new IRExpExpt(x, f); :} | 
    factor:f {: RESULT = f; :} 

    ; 

factor ::= 
    INTEGER:n {: RESULT = new IRExpConst(n.intValue()); :} | 
    VAR:var {: RESULT = new IRExpVar(var); :} | 
    STRING:n {: RESULT = new IRExpString(n); :} | 
    LPAREN arithExp:e RPAREN {: RESULT = e; :} 
    // LBRACE arithExp:e RBRACE {: RESULT = e :} 
     ; 

empty ::=; 

获取一些移进/归约试图理清这个语法的简单语言,我想建立:-(时发生冲突。任何人都可以指导我在合适的光线PLZ?移位减少冲突

回答

2

“有些转变/减少冲突”?我得到38个S/R冲突,然后将过许多的警告错误。

也许我应该只是分析的第一个。

> Warning : *** Shift/Reduce conflict 
> found in state #106 between cmdList 
> ::= statementList (*) and  
> statement ::= (*) LBRACKET varList 
> RBRACKET under symbol LBRACKET 
> Resolved in favor of shifting. 

所以,它看起来像一个声明可能是然后是[something],所以解析器不知道是否继续解析(移位)或减少它已有的语句(如它发生的部分)。

这是LALR(1)解析器中的转换/减少冲突如何不一定是错误的一个很好的例子。通常情况下,你想要做这个转变,所以默认行为是完全合理的,冲突只是一个明显而毫无意义的纯技术含糊。

如果你问一个更像“我的语法不解析......这个......”的问题,为什么不呢?“

+0

嘿感谢洞察力:)。你能否阐述并帮助我解决这个问题。 – ferronrsmith 2009-11-30 05:57:23

+0

修复什么?我们不知道这些冲突是否一定是错误的。杯可能有一种方式告诉它期望一定数量的S/R冲突。阅读文档,给它一个大数字,然后运行语法。看看它能做什么,不能做什么。如果存在真正的问题,请提出具体问题。玩的开心! – DigitalRoss 2009-11-30 06:02:24

+0

在这种特殊情况下,问题是由PROC语句引起的。最终,当遇到(例如)PROC ID 时,解析器必须在PROC主体中包括之间进行选择,或将其视为独立语句。你在这里有一个模棱两可的语法,而解决方法是改变你的语言,以便你可以指定一个明确的语法。 – 2009-11-30 06:05:43