From 62330bd2370d572325a28b06f9b53b838e659371 Mon Sep 17 00:00:00 2001 From: bill Date: Thu, 18 Feb 2021 00:07:18 +0800 Subject: [PATCH] Fixed some typos, added comments. --- .gitignore | 3 + src/main/jflex/chocopy/pa1/ChocoPy.jflex | 79 +++++++++++++++++------- 2 files changed, 60 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index 21cc758..987fe16 100644 --- a/.gitignore +++ b/.gitignore @@ -147,3 +147,6 @@ tramp Session.vim .netrwhist *~ + +# JFlex +src/main/jflex/chocopy/pa1/ChocoPyLexer.java diff --git a/src/main/jflex/chocopy/pa1/ChocoPy.jflex b/src/main/jflex/chocopy/pa1/ChocoPy.jflex index d7640a7..24c0328 100644 --- a/src/main/jflex/chocopy/pa1/ChocoPy.jflex +++ b/src/main/jflex/chocopy/pa1/ChocoPy.jflex @@ -32,9 +32,10 @@ import java.util.ArrayList; /** Producer of token-related values for the parser. */ final ComplexSymbolFactory symbolFactory = new ComplexSymbolFactory(); - private int currIndent = 0; + private int currIndent = 0; //Current Indentation Level private int currString = ""; - private ArrayList stack = new ArrayList(20); + /*A stack that keeps track of the spaces in each Indentation Level*/ + private ArrayList stack = new ArrayList(20); /** Return a terminal symbol of syntactic category TYPE and no * semantic value at the current source location. */ private Symbol symbol(int type) { @@ -57,7 +58,7 @@ import java.util.ArrayList; return stack.remove(stack.size() - 1); } private int top(){ - if(stack.isEmpty) return 0; + if(stack.isEmpty()) return 0; return stack.get(stack.size() - 1); } %} @@ -67,39 +68,74 @@ import java.util.ArrayList; WhiteSpace = [ \t] LineBreak = \r|\n|\r\n -IntegerLiteral = 0|[1-9][0-9]* -StringLiteral = ([^\"\\]|(\\\")|(\\t)|(\\r)|(\\n)|(\\\\))* -Names = (_|[a-z]|[A-Z])(_|[a-z]|[A-Z])* +IntegerLiteral = 0|[1-9][0-9]* // Accroding to the manual, 00+ is illeagal +StringLiteral = ([^\"\\]|(\\\")|(\\t)|(\\r)|(\\n)|(\\\\))* // \n, \r, \t, \\, \" and Anything except \ and " +Identifiers = (_|[a-z]|[A-Z])(_|[a-z]|[A-Z][0-9])* Comments = #[^\r\n]* %% { {WhiteSpace} { - String space = yytext(); - if(space == "\t") - currIndent += 8; + /*Add indentation */ + if(yytext() == "\t") + currIndent += 8; //'\t' = 8 spaces else currIndent ++; } - {LineBreak} +/* +# This python code will test if '\t' is 8 spaces +# It will run and print '1\n2' +# Please tell me if your Python reports an error +# Or you find documentations that says otherwise + +if True: + print(1) # \t + print(2) # 8 spaces +*/ + + {LineBreak} { + /* + If this is a blank line, start over on the next line. + An empty line should just be ignored, therefore we don't + pass a NEWLINE to Cup. + */ currIndent = 0; } - {Comments} { /* ignored */ } - [^ \t\r\n#] + {Comments} { /* ignored */ } //Ignore blank lines + + /*If it's not a blank line (Current character isn't a + Whitespace/linebreak/comment), deal with indentation here and + start accepting whatever is on this line in `AFTER' state*/ + [^ \t\r\n#] { + //rewind the current character. yypushback(1); if(top() > currIndent) - { + { + /* + If the indentation of the line < indents current level should have, + keep dedenting until it reaches the right level. + It's like a loop, because we're not changing the state + and we rewinded the current character. So it will keep + going until top()<= currIndent and it will switch to + AFTER state. + */ pop(); - return symbol(ChocoPyTokens.DEDENT); + return symbol(ChocoPyTokens.DEDENT, currIndent); } + /*Otherwise, we will start dealing with the rest + of the line after indentation in from the next token.*/ yystart(AFTER); if(top()< currIndent) - { + { + /* + If current indentation > indents current level should have, + start a new level which will have `currIndent' spaces. + */ push(currIndent); - return symbol(ChocoPyTokens.INDENT); + return symbol(ChocoPyTokens.INDENT, currIndent); } } } @@ -113,8 +149,7 @@ Comments = #[^\r\n]* /* Literals. */ {IntegerLiteral} { return symbol(ChocoPyTokens.NUMBER, Integer.parseInt(yytext())); } -// {StringLiteral} { return symbol(ChocoPyTokens.STRING, yytext());} - "\"" {yystart(STR); currString = "";} + "\"" {yystart(STR); currString = "";} //Start taking a string when see a " "False" { return symbol(ChocoPyTokens.BOOL, false); } "True" { return symbol(ChocoPyTokens.BOOL, true); } "None" { return symbol(ChocoPyTokens.NONE); } @@ -154,7 +189,7 @@ Comments = #[^\r\n]* "-" { return symbol(ChocoPyTokens.MINUS); } "*" { return symbol(ChocoPyTokens.MUL); } "//" { return symbol(ChocoPyTokens.DIV); } - "/" { return symbol(ChocoPyTokens.DIV); } + "/" { return symbol(ChocoPyTokens.DIV); } //Accroding to manual, chocopy don't have fp division, '/', '//' should be integr division "%" { return symbol(ChocoPyTokens.MOD); } ">" { return symbol(ChocoPyTokens.GT); } "<" { return symbol(ChocoPyTokens.LT); } @@ -176,16 +211,16 @@ Comments = #[^\r\n]* /*Identifiers*/ - {Names} {return symbol(ChocoPyTokens.NAMES, yytext());} + {Identifiers} {return symbol(ChocoPyTokens.ID, yytext());} /* Whitespace. */ {WhiteSpace} { /* ignore */ } /* Comment. */ {Comments} { /* ignore */ } } { - {StringLiteral} {currString+=yytext();} + {StringLiteral} {currString += yytext();} \\$ { /*'\' at the end of line, do nothing.*/ } - "\"" {yybegin(AFTER); return symbol(ChocoPyTokens.STRING, currString);} + "\"" {yybegin(AFTER); return symbol(ChocoPyTokens.STRING, currString);} // accepted a ", return to AFTER state } <> { return symbol(ChocoPyTokens.EOF); }