-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add `//cup:cup.bzl` * Import `//third_party/cup` from java-cup-bin-11b-20160615.tar.gz at http://www2.cs.tum.edu/projects/cup/ * Add example `//java/jflex/examples/calculator` (and related javatests) * Add `//third_party/com/google/truth` to make tests more elegant * Update documentation
- Loading branch information
Showing
21 changed files
with
575 additions
and
46 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Copyright 2018 Google LLC. | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
package(default_visibility = ["//visibility:public"]) | ||
|
||
# This rule is license under Apache 2 | ||
licenses(["notice"]) # Apache 2 | ||
|
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# Skylark rule for Java CUP | ||
|
||
|
||
## Attributes | ||
|
||
* **name** (Name; required) | ||
Unique name for this target. | ||
* **src** (Label; required) | ||
The CUP specification. | ||
* **parser** (String; optional) | ||
The class name of the parser to generate. Defaults to `parser`, hence generating `parser.java`. | ||
Note that the lower case is used to behave like the CUP program. | ||
* **symbols** (String; optional) | ||
The class name of the symbols holder. Defaults to `sym`, hence generating `sym.java`. | ||
Note that the lower case is used to behave like the CUP program. | ||
|
||
## Example | ||
|
||
The example **//java/jflex/examples/helloworld** generates a lexer from `helloworld.flex` with: | ||
|
||
cup( | ||
name = "gen_parser", | ||
src = "calculator.cup", | ||
parser = "CalculatorParser", | ||
symbols = "Calc", | ||
) | ||
|
||
See [//java/jflex/examples/helloworld](../java/jflex/examples/calculator). |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
"""Bazel rules for cup. """ | ||
|
||
# CUP can only read from stdin, which Skylark rules don't support. Use a genrule for now. | ||
def cup(name, src, parser = "parser", symbols = "sym", interface = False): | ||
"""Generate a parser with CUP. | ||
Args: | ||
name: name of the rule. | ||
src: the cup specifications. | ||
parser: name of the generated parser class. | ||
symbols: name of the generated symbols class. | ||
interface: whether to generate an interface. | ||
""" | ||
opts = [ | ||
"-parser", | ||
parser, | ||
"-symbols", | ||
symbols, | ||
] | ||
if interface: | ||
opts = opts + ["-interface"] | ||
options = " ".join(opts) | ||
cmd = ("$(location //third_party/cup:cup_bin) -destdir $(@D) " + options + " < $<") | ||
native.genrule( | ||
name = name, | ||
srcs = [src], | ||
tools = ["//third_party/cup:cup_bin"], | ||
outs = [parser + ".java", symbols + ".java"], | ||
cmd = cmd, | ||
) |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# Copyright 2018 Google LLC. | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
package(default_visibility = ["//visibility:public"]) | ||
|
||
load("//jflex:jflex.bzl", "jflex") | ||
load("//cup:cup.bzl", "cup") | ||
|
||
java_library( | ||
name = "calculator", | ||
srcs = ["CalculatorParserException.java",":gen_parser", ":gen_lexer"], | ||
deps =[ | ||
"//third_party/cup", # the runtime would be sufficient | ||
] | ||
) | ||
|
||
cup( | ||
name = "gen_parser", | ||
src = "calculator.cup", | ||
parser = "CalculatorParser", | ||
symbols = "Calc", | ||
) | ||
|
||
jflex( | ||
name = "gen_lexer", | ||
srcs = ["calculator.flex"], | ||
outputs = ["CalculatorLexer.java"], | ||
|
||
) |
11 changes: 11 additions & 0 deletions
11
java/jflex/examples/calculator/CalculatorParserException.java
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
// Copyright 2018 Google LLC. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package jflex.examples.calculator; | ||
|
||
/** An exception from the lexer/parser. */ | ||
public class CalculatorParserException extends RuntimeException { | ||
CalculatorParserException(String message) { | ||
super(message); | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package jflex.examples.calculator; | ||
|
||
import java_cup.runtime.Symbol; | ||
import java.util.Vector; | ||
/* | ||
* Copyright (C) 2018 Google LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
|
||
/** | ||
* Parser for a simple calculator. | ||
* | ||
* <p>The grammar defines a simple arihmetic expressions that supports the addition, | ||
* the multiplication, and parentheses. | ||
* | ||
* @author Régis Décamps | ||
*/ | ||
|
||
parser code {: | ||
:} | ||
|
||
// Terminals: () * + | ||
terminal LPAR, RPAR; | ||
terminal MULTIPLY; | ||
terminal PLUS; | ||
// A number is also a terminal, bit it's of type Integer. | ||
terminal Integer NUMBER; | ||
|
||
non terminal Integer expr; | ||
non terminal Integer multiply_expr; | ||
non terminal Integer term; | ||
|
||
precedence left PLUS; | ||
precedence left MULTIPLY; | ||
|
||
// This is where the grammar starts. | ||
|
||
// An expression is a sum of priority_expr. Because the parser needs to produce priority_expr in | ||
// in order to assemble expr, this effectively makes priority_expr of higher priority than | ||
// than expr in the computation of the result. | ||
// We also implement the actual computation done by the calculator. RESULT is the label that is | ||
// assigned automatically to the rhs, in this case 'expr' because 'expr ::= ...'. | ||
// Since the priority_expr is an object of type Integer, we can call intValue() to retrieve its | ||
// value. | ||
expr ::= | ||
expr:a PLUS multiply_expr:b | ||
{: RESULT = a.intValue() + b.intValue(); :} | ||
| multiply_expr:e | ||
{: RESULT = e; :} | ||
; | ||
multiply_expr ::= | ||
multiply_expr:a MULTIPLY term:b | ||
{: RESULT = a.intValue() * b.intValue(); :} | ||
| term:t | ||
{: RESULT = t; :} | ||
; | ||
// The last term closes the grammar. It's a number, or another expression in parentheses. | ||
// Note that local identifiers don't need to be a single letter. We use "nb" for the terminal | ||
// number. | ||
term ::= | ||
LPAR expr:e RPAR {: RESULT = e; :} | ||
| NUMBER:nb {: RESULT = nb; :} | ||
; |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
/* | ||
* Copyright (C) 2018 Google LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package jflex.examples.calculator; | ||
|
||
import java_cup.runtime.Symbol; | ||
|
||
/** | ||
* A simple lexer/parser for basic arithmetic expressions. | ||
* | ||
* @author Régis Décamps | ||
*/ | ||
|
||
%% | ||
|
||
|
||
%public | ||
%class CalculatorLexer | ||
// Use CUP compatibility mode to interface with a CUP parser. | ||
%cup | ||
|
||
%unicode | ||
|
||
%{ | ||
/** Creates a new {@link Symbol} of the given type. */ | ||
private Symbol symbol(int type) { | ||
return new Symbol(type, yyline, yycolumn); | ||
} | ||
|
||
/** Creates a new {@link Symbol} of the given type and value. */ | ||
private Symbol symbol(int type, Object value) { | ||
return new Symbol(type, yyline, yycolumn, value); | ||
} | ||
%} | ||
|
||
// A (integer) number is a sequence of digits. | ||
Number = [0-9]+ | ||
|
||
// A line terminator is a \r (carriage return), \n (line feed), or \r\n. */ | ||
LineTerminator = \r|\n|\r\n | ||
|
||
/* White space is a line terminator, space, tab, or line feed. */ | ||
WhiteSpace = {LineTerminator} | [ \t\f] | ||
|
||
|
||
%% | ||
|
||
// This section contains regular expressions and actions, i.e. Java code, that will be executed when | ||
// the scanner matches the associated regular expression. | ||
|
||
|
||
// YYINITIAL is the initial state at which the lexer begins scanning. | ||
<YYINITIAL> { | ||
|
||
/* Create a new parser symbol for the lexem. */ | ||
"+" { return symbol(Calc.PLUS); } | ||
"*" { return symbol(Calc.MULTIPLY); } | ||
"(" { return symbol(Calc.LPAR); } | ||
")" { return symbol(Calc.RPAR); } | ||
|
||
// If an integer is found, return the token NUMBER that represents an integer and the value of | ||
// the integer that is held in the string yytext | ||
{Number} { return symbol(Calc.NUMBER, Integer.parseInt(yytext())); } | ||
|
||
/* Don't do anything if whitespace is found */ | ||
{WhiteSpace} { /* do nothing with space */ } | ||
} | ||
|
||
// We have changed the default symbol in the bazel `cup()` rule from "sym" to "Calc", so we need to | ||
// change how JFlex handles the end of file. | ||
// See http://jflex.de/manual.html#custom-symbol-interface | ||
<<EOF>> { return symbol(Calc.EOF); } | ||
|
||
/* Catch-all the rest, i.e. unknow character. */ | ||
[^] { throw new CalculatorParserException("Illegal character <" + yytext() + ">"); } |
Oops, something went wrong.