Note: Users running Windows should replace the colon (:) with a semicolon (;) in the classpath argument for all commands listed below.
Run the following command to generate and compile your parser, and then run all the provided tests:
mvn clean package
java -cp "chocopy-ref.jar:target/assignment.jar" chocopy.ChocoPy --pass=s --test --dir src/test/data/pa1/sample/In the starter code, only one test should pass. Your objective is to build a parser that passes all the provided tests and meets the assignment specifications.
To manually observe the output of your parser when run on a given input ChocoPy program, run the following command (replace the last argument to change the input file):
java -cp "chocopy-ref.jar:target/assignment.jar" chocopy.ChocoPy --pass=s src/test/data/pa1/sample/expr_plus.pyYou can check the output produced by the staff-provided reference implementation on the same input file, as follows:
java -cp "chocopy-ref.jar:target/assignment.jar" chocopy.ChocoPy --pass=r src/test/data/pa1/sample/expr_plus.pyTry this with another input file as well, such as src/test/data/pa1/sample/coverage.py, to see what happens when the results disagree.
See the PA1 specification on the course website for a detailed specification of the assignment.
Refer to the ChocoPy Specification on the CS164 web site for the specification of the ChocoPy language.
Add the upstream repository remote (you only need to do this once in your local clone):
git remote add upstream https://github.com/cs164berkeley/pa1-chocopy-parser.gitTo sync with updates upstream:
git pull upstream masterTeam members:
- Membro 1:
<Seu Nome Aqui> - Membro 2:
<Seu Nome Aqui>
Acknowledgements: Agradecemos ao Professor X e aos colegas do grupo de estudo pela revisão do design do parser e pelas discussões sobre estratégias de recuperação de erro.
Horas de desenvolvimento: O projeto levou aproximadamente 15 horas de desenvolvimento colaborativo.
Para reconhecer corretamente os níveis de indentação, utilizamos uma pilha de inteiros em src/main/jflex/chocopy/pa1/ChocoPy.jflex. Nas linhas 150–180, construímos um contador do número de espaços no início de cada linha, então:
- Se o novo nível de indentação for maior que o topo da pilha, geramos um token
INDENTe empilhamos o nível. - Se for menor, geramos repetidos tokens
DEDENTe desempilhamos até que o topo corresponda ao nível atual. - Se for igual, não emitimos token de indentação.
Esse algoritmo segue a lógica descrita no manual de referência da linguagem (arquivo chocopy_language_reference.pdf).
A seção 3.1 do chocopy_language_reference.pdf define as regras de indentação de ChocoPy: mover para um novo nível gera INDENT, retornar a níveis anteriores gera DEDENT, e linhas em branco ou comentários não afetam a pilha. Nossa implementação em ChocoPy.jflex (linhas 150–180) reproduz exatamente esse comportamento, incluindo a simplificação de ignorar linhas vazias antes da lógica de indent.
A parte mais desafiadora não foi a indentação, mas sim lidar com a expressão condicional ternária (x if cond else y) devido à precedência e associatividade direita. No arquivo src/main/cup/chocopy/pa1/ChocoPy.cup (linhas 300–320) usamos:
precedence right IF, ELSE;
...
expr ::= expr:e1 IF expr:e2 ELSE expr:e3 {: RESULT = new IfExpr(...); :}
Isso garantiu que a gramática não se ambiguisse em casos como a if b else c if d else e, produzindo a árvore correta (a if b else (c if d else e)).