Website Summary Files Commits Branches @commit @diff @stats
diff options
context:
space:
mode:
Commit5729bc0ea96fc0b944c243230910c537d692bcad (patch)
Author
 Radoslav Georgiev <rgeorgiev583@gmail.com>
2018-11-17 19:11:03 +0200
Committer
 dtrendafilov <trendafilov.dn@gmail.com>
2018-11-17 19:11:02 +0200
Files43db75a7acf93c6c2c8e07c3a87590fe14fb4e4f
IPL-5729bc0ea96fc0b944c243230910c537d692bcad.tar
IPL-5729bc0ea96fc0b944c243230910c537d692bcad.tar.gz
IPL-5729bc0ea96fc0b944c243230910c537d692bcad.zip
Parent9420791a9335fc174627bea5f2a25f434bbe7ae5 (diff)
implement the second homework assignment (#39)
* Rust syntax highlighter: fix some issues with the implementation of the first homework assignment * Rust syntax highlighter: pretty-printer: implement the second homework assignment
diff --git a/homework/81030/.gitignore b/homework/81030/.gitignore
deleted file mode 100644
index b2ee661..0000000
--- a/homework/81030/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-lex.yy.c
-a.out
-
-/test/
diff --git a/homework/81030/1,2-rust2html/.gitignore b/homework/81030/1,2-rust2html/.gitignore
new file mode 100644
index 0000000..691e40c
--- /dev/null
+++ b/homework/81030/1,2-rust2html/.gitignore
@@ -0,0 +1,5 @@
+a.out
+lex.yy.c
+
+/rust2html
+/example.html
diff --git a/homework/81030/1,2-rust2html/Makefile b/homework/81030/1,2-rust2html/Makefile
new file mode 100644
index 0000000..b6f2dde
--- /dev/null
+++ b/homework/81030/1,2-rust2html/Makefile
@@ -0,0 +1,21 @@
+PROGRAM_NAMES := rust2html rust2html-prettyprint
+PROGRAM_SOURCE_FILENAMES := $(patsubst %,%.lex.yy.c,PROGRAM_NAMES)
+
+LEX := flex
+
+ifdef DEBUG
+LEX_FLAGS := -d
+endif
+
+.PHONY: all clean
+
+all: $(PROGRAM_NAMES)
+
+%: %.lex.yy.c
+ $(CC) $(CFLAGS) -o $@ $<
+
+%.lex.yy.c: %.l
+ $(LEX) $(LEX_FLAGS) -o $@ $<
+
+clean:
+ $(RM) $(PROGRAM_NAMES) $(PROGRAM_SOURCE_FILENAMES) lex.yy.c example.html
diff --git a/homework/81030/1,2-rust2html/README.md b/homework/81030/1,2-rust2html/README.md
new file mode 100644
index 0000000..577a3d0
--- /dev/null
+++ b/homework/81030/1,2-rust2html/README.md
@@ -0,0 +1,50 @@
+# Rust syntax highlighter
+
+This is an implementation of a syntax highlighter for the Rust programming language. It takes a Rust program as input (or a Rust source file as an argument) and outputs a HTML page with a colorized version of the program. The C source for the highlighter is generated from a Flex-based scanner template (`rust2html.l`). (This is a solution to the first homework assignment.)
+
+There is also an extended and improved version of the highlighter which implements pretty-printing (`rust2html-prettyprint.l`). (This is a solution to the second homework assignment.)
+
+## Generating and building
+
+On Unix-like OS:
+
+* the regular highlighter:
+
+ flex rust2html.l
+ cc -o rust2html lex.yy.c
+
+* the extended (pretty-printing) highlighter:
+
+ flex rust2html-prettyprint.l
+ cc -o rust2html-prettyprint lex.yy.c
+
+Using the provided `Makefile`:
+
+* the regular highlighter:
+
+ make rust2html
+
+* the extended (pretty-printing) highlighter:
+
+ make rust2html-prettyprint
+
+## Usage
+
+This will generate a HTML document named `example.html` with a colorized version of the `example.rs` Rust program:
+
+ ./rust2html example.rs > example.html
+
+This will generate a HTML document named `example.html` with a colorized and pretty-printed version of the `example.rs` Rust program:
+
+ ./rust2html-prettyprint example.rs > example.html
+
+## Debugging
+
+If you want to be able to debug the `RUST2HTML` scanner (i.e. `rust2html` or `rust2html-prettyprint`), generate its code using the `-d` flag with Flex:
+
+ flex -d RUST2HTML.l
+ cc -o RUST2HTML lex.yy.c
+
+The following invocation of `RUST2HTML` will also write its standard error output to the `example.log` file (which is the main thing to look at when trying to debug the program):
+
+ ./RUST2HTML example.rs > example.html 2> example.log \ No newline at end of file
diff --git a/homework/81030/1,2-rust2html/example-chains.rs b/homework/81030/1,2-rust2html/example-chains.rs
new file mode 100644
index 0000000..be38300
--- /dev/null
+++ b/homework/81030/1,2-rust2html/example-chains.rs
@@ -0,0 +1,871 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Formatting of chained expressions, i.e. expressions which are chained by
+//! dots: struct and enum field access, method calls, and try shorthand (?).
+//!
+//! Instead of walking these subexpressions one-by-one, as is our usual strategy
+//! for expression formatting, we collect maximal sequences of these expressions
+//! and handle them simultaneously.
+//!
+//! Whenever possible, the entire chain is put on a single line. If that fails,
+//! we put each subexpression on a separate, much like the (default) function
+//! argument function argument strategy.
+//!
+//! Depends on config options: `chain_indent` is the indent to use for
+//! blocks in the parent/root/base of the chain (and the rest of the chain's
+//! alignment).
+//! E.g., `let foo = { aaaa; bbb; ccc }.bar.baz();`, we would layout for the
+//! following values of `chain_indent`:
+//! Block:
+//!
+//! ```ignore
+//! let foo = {
+//! aaaa;
+//! bbb;
+//! ccc
+//! }.bar
+//! .baz();
+//! ```
+//!
+//! Visual:
+//!
+//! ```ignore
+//! let foo = {
+//! aaaa;
+//! bbb;
+//! ccc
+//! }
+//! .bar
+//! .baz();
+//! ```
+//!
+//! If the first item in the chain is a block expression, we align the dots with
+//! the braces.
+//! Block:
+//!
+//! ```ignore
+//! let a = foo.bar
+//! .baz()
+//! .qux
+//! ```
+//!
+//! Visual:
+//!
+//! ```ignore
+//! let a = foo.bar
+//! .baz()
+//! .qux
+//! ```
+
+use comment::{rewrite_comment, CharClasses, FullCodeCharKind, RichChar};
+use config::IndentStyle;
+use expr::rewrite_call;
+use lists::extract_pre_comment;
+use macros::convert_try_mac;
+use rewrite::{Rewrite, RewriteContext};
+use shape::Shape;
+use source_map::SpanUtils;
+use utils::{
+ self, first_line_width, last_line_extendable, last_line_width, mk_sp, rewrite_ident,
+ trimmed_last_line_width, wrap_str,
+};
+
+use std::borrow::Cow;
+use std::cmp::min;
+
+use syntax::source_map::{BytePos, Span};
+use syntax::{ast, ptr};
+
+pub fn rewrite_chain(expr: &ast::Expr, context: &RewriteContext, shape: Shape) -> Option<String> {
+ let chain = Chain::from_ast(expr, context);
+ debug!("rewrite_chain {:?} {:?}", chain, shape);
+
+ // If this is just an expression with some `?`s, then format it trivially and
+ // return early.
+ if chain.children.is_empty() {
+ return chain.parent.rewrite(context, shape);
+ }
+
+ chain.rewrite(context, shape)
+}
+
+#[derive(Debug)]
+enum CommentPosition {
+ Back,
+ Top,
+}
+
+// An expression plus trailing `?`s to be formatted together.
+#[derive(Debug)]
+struct ChainItem {
+ kind: ChainItemKind,
+ tries: usize,
+ span: Span,
+}
+
+// FIXME: we can't use a reference here because to convert `try!` to `?` we
+// synthesise the AST node. However, I think we could use `Cow` and that
+// would remove a lot of cloning.
+#[derive(Debug)]
+enum ChainItemKind {
+ Parent(ast::Expr),
+ MethodCall(
+ ast::PathSegment,
+ Vec<ast::GenericArg>,
+ Vec<ptr::P<ast::Expr>>,
+ ),
+ StructField(ast::Ident),
+ TupleField(ast::Ident, bool),
+ Comment(String, CommentPosition),
+}
+
+impl ChainItemKind {
+ fn is_block_like(&self, context: &RewriteContext, reps: &str) -> bool {
+ match self {
+ ChainItemKind::Parent(ref expr) => utils::is_block_expr(context, expr, reps),
+ ChainItemKind::MethodCall(..)
+ | ChainItemKind::StructField(..)
+ | ChainItemKind::TupleField(..)
+ | ChainItemKind::Comment(..) => false,
+ }
+ }
+
+ fn is_tup_field_access(expr: &ast::Expr) -> bool {
+ match expr.node {
+ ast::ExprKind::Field(_, ref field) => {
+ field.name.to_string().chars().all(|c| c.is_digit(10))
+ }
+ _ => false,
+ }
+ }
+
+ fn from_ast(context: &RewriteContext, expr: &ast::Expr) -> (ChainItemKind, Span) {
+ let (kind, span) = match expr.node {
+ ast::ExprKind::MethodCall(ref segment, ref expressions) => {
+ let types = if let Some(ref generic_args) = segment.args {
+ if let ast::GenericArgs::AngleBracketed(ref data) = **generic_args {
+ data.args.clone()
+ } else {
+ vec![]
+ }
+ } else {
+ vec![]
+ };
+ let span = mk_sp(expressions[0].span.hi(), expr.span.hi());
+ let kind = ChainItemKind::MethodCall(segment.clone(), types, expressions.clone());
+ (kind, span)
+ }
+ ast::ExprKind::Field(ref nested, field) => {
+ let kind = if Self::is_tup_field_access(expr) {
+ ChainItemKind::TupleField(field, Self::is_tup_field_access(nested))
+ } else {
+ ChainItemKind::StructField(field)
+ };
+ let span = mk_sp(nested.span.hi(), field.span.hi());
+ (kind, span)
+ }
+ _ => return (ChainItemKind::Parent(expr.clone()), expr.span),
+ };
+
+ // Remove comments from the span.
+ let lo = context.snippet_provider.span_before(span, ".");
+ (kind, mk_sp(lo, span.hi()))
+ }
+}
+
+impl Rewrite for ChainItem {
+ fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
+ let shape = shape.sub_width(self.tries)?;
+ let rewrite = match self.kind {
+ ChainItemKind::Parent(ref expr) => expr.rewrite(context, shape)?,
+ ChainItemKind::MethodCall(ref segment, ref types, ref exprs) => {
+ Self::rewrite_method_call(segment.ident, types, exprs, self.span, context, shape)?
+ }
+ ChainItemKind::StructField(ident) => format!(".{}", rewrite_ident(context, ident)),
+ ChainItemKind::TupleField(ident, nested) => format!(
+ "{}.{}",
+ if nested { " " } else { "" },
+ rewrite_ident(context, ident)
+ ),
+ ChainItemKind::Comment(ref comment, _) => {
+ rewrite_comment(comment, false, shape, context.config)?
+ }
+ };
+ Some(format!("{}{}", rewrite, "?".repeat(self.tries)))
+ }
+}
+
+impl ChainItem {
+ fn new(context: &RewriteContext, expr: &ast::Expr, tries: usize) -> ChainItem {
+ let (kind, span) = ChainItemKind::from_ast(context, expr);
+ ChainItem { kind, tries, span }
+ }
+
+ fn comment(span: Span, comment: String, pos: CommentPosition) -> ChainItem {
+ ChainItem {
+ kind: ChainItemKind::Comment(comment, pos),
+ tries: 0,
+ span,
+ }
+ }
+
+ fn is_comment(&self) -> bool {
+ match self.kind {
+ ChainItemKind::Comment(..) => true,
+ _ => false,
+ }
+ }
+
+ fn rewrite_method_call(
+ method_name: ast::Ident,
+ types: &[ast::GenericArg],
+ args: &[ptr::P<ast::Expr>],
+ span: Span,
+ context: &RewriteContext,
+ shape: Shape,
+ ) -> Option<String> {
+ let type_str = if types.is_empty() {
+ String::new()
+ } else {
+ let type_list = types
+ .iter()
+ .map(|ty| ty.rewrite(context, shape))
+ .collect::<Option<Vec<_>>>()?;
+
+ format!("::<{}>", type_list.join(", "))
+ };
+ let callee_str = format!(".{}{}", rewrite_ident(context, method_name), type_str);
+ rewrite_call(context, &callee_str, &args[1..], span, shape)
+ }
+}
+
+#[derive(Debug)]
+struct Chain {
+ parent: ChainItem,
+ children: Vec<ChainItem>,
+}
+
+impl Chain {
+ fn from_ast(expr: &ast::Expr, context: &RewriteContext) -> Chain {
+ let subexpr_list = Self::make_subexpr_list(expr, context);
+
+ // Un-parse the expression tree into ChainItems
+ let mut rev_children = vec![];
+ let mut sub_tries = 0;
+ for subexpr in &subexpr_list {
+ match subexpr.node {
+ ast::ExprKind::Try(_) => sub_tries += 1,
+ _ => {
+ rev_children.push(ChainItem::new(context, subexpr, sub_tries));
+ sub_tries = 0;
+ }
+ }
+ }
+
+ fn is_tries(s: &str) -> bool {
+ s.chars().all(|c| c == '?')
+ }
+
+ fn is_post_comment(s: &str) -> bool {
+ let comment_start_index = s.chars().position(|c| c == '/');
+ if comment_start_index.is_none() {
+ return false;
+ }
+
+ let newline_index = s.chars().position(|c| c == '\n');
+ if newline_index.is_none() {
+ return true;
+ }
+
+ comment_start_index.unwrap() < newline_index.unwrap()
+ }
+
+ fn handle_post_comment(
+ post_comment_span: Span,
+ post_comment_snippet: &str,
+ prev_span_end: &mut BytePos,
+ children: &mut Vec<ChainItem>,
+ ) {
+ let white_spaces: &[_] = &[' ', '\t'];
+ if post_comment_snippet
+ .trim_matches(white_spaces)
+ .starts_with('\n')
+ {
+ // No post comment.
+ return;
+ }
+ let trimmed_snippet = trim_tries(post_comment_snippet);
+ if is_post_comment(&trimmed_snippet) {
+ children.push(ChainItem::comment(
+ post_comment_span,
+ trimmed_snippet.trim().to_owned(),
+ CommentPosition::Back,
+ ));
+ *prev_span_end = post_comment_span.hi();
+ }
+ }
+
+ let parent = rev_children.pop().unwrap();
+ let mut children = vec![];
+ let mut prev_span_end = parent.span.hi();
+ let mut iter = rev_children.into_iter().rev().peekable();
+ if let Some(first_chain_item) = iter.peek() {
+ let comment_span = mk_sp(prev_span_end, first_chain_item.span.lo());
+ let comment_snippet = context.snippet(comment_span);
+ if !is_tries(comment_snippet.trim()) {
+ handle_post_comment(
+ comment_span,
+ comment_snippet,
+ &mut prev_span_end,
+ &mut children,
+ );
+ }
+ }
+ while let Some(chain_item) = iter.next() {
+ let comment_snippet = context.snippet(chain_item.span);
+ // FIXME: Figure out the way to get a correct span when converting `try!` to `?`.
+ let handle_comment =
+ !(context.config.use_try_shorthand() || is_tries(comment_snippet.trim()));
+
+ // Pre-comment
+ if handle_comment {
+ let pre_comment_span = mk_sp(prev_span_end, chain_item.span.lo());
+ let pre_comment_snippet = trim_tries(context.snippet(pre_comment_span));
+ let (pre_comment, _) = extract_pre_comment(&pre_comment_snippet);
+ match pre_comment {
+ Some(ref comment) if !comment.is_empty() => {
+ children.push(ChainItem::comment(
+ pre_comment_span,
+ comment.to_owned(),
+ CommentPosition::Top,
+ ));
+ }
+ _ => (),
+ }
+ }
+
+ prev_span_end = chain_item.span.hi();
+ children.push(chain_item);
+
+ // Post-comment
+ if !handle_comment || iter.peek().is_none() {
+ continue;
+ }
+
+ let next_lo = iter.peek().unwrap().span.lo();
+ let post_comment_span = mk_sp(prev_span_end, next_lo);
+ let post_comment_snippet = context.snippet(post_comment_span);
+ handle_post_comment(
+ post_comment_span,
+ post_comment_snippet,
+ &mut prev_span_end,
+ &mut children,
+ );
+ }
+
+ Chain { parent, children }
+ }
+
+ // Returns a Vec of the prefixes of the chain.
+ // E.g., for input `a.b.c` we return [`a.b.c`, `a.b`, 'a']
+ fn make_subexpr_list(expr: &ast::Expr, context: &RewriteContext) -> Vec<ast::Expr> {
+ let mut subexpr_list = vec![expr.clone()];
+
+ while let Some(subexpr) = Self::pop_expr_chain(subexpr_list.last().unwrap(), context) {
+ subexpr_list.push(subexpr.clone());
+ }
+
+ subexpr_list
+ }
+
+ // Returns the expression's subexpression, if it exists. When the subexpr
+ // is a try! macro, we'll convert it to shorthand when the option is set.
+ fn pop_expr_chain(expr: &ast::Expr, context: &RewriteContext) -> Option<ast::Expr> {
+ match expr.node {
+ ast::ExprKind::MethodCall(_, ref expressions) => {
+ Some(Self::convert_try(&expressions[0], context))
+ }
+ ast::ExprKind::Field(ref subexpr, _) | ast::ExprKind::Try(ref subexpr) => {
+ Some(Self::convert_try(subexpr, context))
+ }
+ _ => None,
+ }
+ }
+
+ fn convert_try(expr: &ast::Expr, context: &RewriteContext) -> ast::Expr {
+ match expr.node {
+ ast::ExprKind::Mac(ref mac) if context.config.use_try_shorthand() => {
+ if let Some(subexpr) = convert_try_mac(mac, context) {
+ subexpr
+ } else {
+ expr.clone()
+ }
+ }
+ _ => expr.clone(),
+ }
+ }
+}
+
+impl Rewrite for Chain {
+ fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
+ debug!("rewrite chain {:?} {:?}", self, shape);
+
+ let mut formatter = match context.config.indent_style() {
+ IndentStyle::Block => Box::new(ChainFormatterBlock::new(self)) as Box<ChainFormatter>,
+ IndentStyle::Visual => Box::new(ChainFormatterVisual::new(self)) as Box<ChainFormatter>,
+ };
+
+ formatter.format_root(&self.parent, context, shape)?;
+ if let Some(result) = formatter.pure_root() {
+ return wrap_str(result, context.config.max_width(), shape);
+ }
+
+ // Decide how to layout the rest of the chain.
+ let child_shape = formatter.child_shape(context, shape)?;
+
+ formatter.format_children(context, child_shape)?;
+ formatter.format_last_child(context, shape, child_shape)?;
+
+ let result = formatter.join_rewrites(context, child_shape)?;
+ wrap_str(result, context.config.max_width(), shape)
+ }
+}
+
+// There are a few types for formatting chains. This is because there is a lot
+// in common between formatting with block vs visual indent, but they are
+// different enough that branching on the indent all over the place gets ugly.
+// Anything that can format a chain is a ChainFormatter.
+trait ChainFormatter {
+ // Parent is the first item in the chain, e.g., `foo` in `foo.bar.baz()`.
+ // Root is the parent plus any other chain items placed on the first line to
+ // avoid an orphan. E.g.,
+ // ```ignore
+ // foo.bar
+ // .baz()
+ // ```
+ // If `bar` were not part of the root, then foo would be orphaned and 'float'.
+ fn format_root(
+ &mut self,
+ parent: &ChainItem,
+ context: &RewriteContext,
+ shape: Shape,
+ ) -> Option<()>;
+ fn child_shape(&self, context: &RewriteContext, shape: Shape) -> Option<Shape>;
+ fn format_children(&mut self, context: &RewriteContext, child_shape: Shape) -> Option<()>;
+ fn format_last_child(
+ &mut self,
+ context: &RewriteContext,
+ shape: Shape,
+ child_shape: Shape,
+ ) -> Option<()>;
+ fn join_rewrites(&self, context: &RewriteContext, child_shape: Shape) -> Option<String>;
+ // Returns `Some` if the chain is only a root, None otherwise.
+ fn pure_root(&mut self) -> Option<String>;
+}
+
+// Data and behaviour that is shared by both chain formatters. The concrete
+// formatters can delegate much behaviour to `ChainFormatterShared`.
+struct ChainFormatterShared<'a> {
+ // The current working set of child items.
+ children: &'a [ChainItem],
+ // The current rewrites of items (includes trailing `?`s, but not any way to
+ // connect the rewrites together).
+ rewrites: Vec<String>,
+ // Whether the chain can fit on one line.
+ fits_single_line: bool,
+ // The number of children in the chain. This is not equal to `self.children.len()`
+ // because `self.children` will change size as we process the chain.
+ child_count: usize,
+}
+
+impl<'a> ChainFormatterShared<'a> {
+ fn new(chain: &'a Chain) -> ChainFormatterShared<'a> {
+ ChainFormatterShared {
+ children: &chain.children,
+ rewrites: Vec::with_capacity(chain.children.len() + 1),
+ fits_single_line: false,
+ child_count: chain.children.len(),
+ }
+ }
+
+ fn pure_root(&mut self) -> Option<String> {
+ if self.children.is_empty() {
+ assert_eq!(self.rewrites.len(), 1);
+ Some(self.rewrites.pop().unwrap())
+ } else {
+ None
+ }
+ }
+
+ // Rewrite the last child. The last child of a chain requires special treatment. We need to
+ // know whether 'overflowing' the last child make a better formatting:
+ //
+ // A chain with overflowing the last child:
+ // ```ignore
+ // parent.child1.child2.last_child(
+ // a,
+ // b,
+ // c,
+ // )
+ // ```
+ //
+ // A chain without overflowing the last child (in vertical layout):
+ // ```ignore
+ // parent
+ // .child1
+ // .child2
+ // .last_child(a, b, c)
+ // ```
+ //
+ // In particular, overflowing is effective when the last child is a method with a multi-lined
+ // block-like argument (e.g. closure):
+ // ```ignore
+ // parent.child1.child2.last_child(|a, b, c| {
+ // let x = foo(a, b, c);
+ // let y = bar(a, b, c);
+ //
+ // // ...
+ //
+ // result
+ // })
+ // ```
+ fn format_last_child(
+ &mut self,
+ may_extend: bool,
+ context: &RewriteContext,
+ shape: Shape,
+ child_shape: Shape,
+ ) -> Option<()> {
+ let last = self.children.last()?;
+ let extendable = may_extend && last_line_extendable(&self.rewrites[0]);
+ let prev_last_line_width = last_line_width(&self.rewrites[0]);
+
+ // Total of all items excluding the last.
+ let almost_total = if extendable {
+ prev_last_line_width
+ } else {
+ self.rewrites.iter().fold(0, |a, b| a + b.len())
+ } + last.tries;
+ let one_line_budget = if self.child_count == 1 {
+ shape.width
+ } else {
+ min(shape.width, context.config.width_heuristics().chain_width)
+ }
+ .saturating_sub(almost_total);
+
+ let all_in_one_line = !self.children.iter().any(ChainItem::is_comment)
+ && self.rewrites.iter().all(|s| !s.contains('\n'))
+ && one_line_budget > 0;
+ let last_shape = if all_in_one_line {
+ shape.sub_width(last.tries)?
+ } else if extendable {
+ child_shape.sub_width(last.tries)?
+ } else {
+ child_shape.sub_width(shape.rhs_overhead(context.config) + last.tries)?
+ };
+
+ let mut last_subexpr_str = None;
+ if all_in_one_line || extendable {
+ // First we try to 'overflow' the last child and see if it looks better than using
+ // vertical layout.
+ let one_line_shape = if context.use_block_indent() {
+ last_shape.offset_left(almost_total)
+ } else {
+ last_shape
+ .visual_indent(almost_total)
+ .sub_width(almost_total)
+ };
+
+ if let Some(one_line_shape) = one_line_shape {
+ if let Some(rw) = last.rewrite(context, one_line_shape) {
+ // We allow overflowing here only if both of the following conditions match:
+ // 1. The entire chain fits in a single line except the last child.
+ // 2. `last_child_str.lines().count() >= 5`.
+ let line_count = rw.lines().count();
+ let could_fit_single_line = first_line_width(&rw) <= one_line_budget;
+ if could_fit_single_line && line_count >= 5 {
+ last_subexpr_str = Some(rw);
+ self.fits_single_line = all_in_one_line;
+ } else {
+ // We could not know whether overflowing is better than using vertical
+ // layout, just by looking at the overflowed rewrite. Now we rewrite the
+ // last child on its own line, and compare two rewrites to choose which is
+ // better.
+ let last_shape = child_shape
+ .sub_width(shape.rhs_overhead(context.config) + last.tries)?;
+ match last.rewrite(context, last_shape) {
+ Some(ref new_rw) if !could_fit_single_line => {
+ last_subexpr_str = Some(new_rw.clone());
+ }
+ Some(ref new_rw) if new_rw.lines().count() >= line_count => {
+ last_subexpr_str = Some(rw);
+ self.fits_single_line = could_fit_single_line && all_in_one_line;
+ }
+ new_rw @ Some(..) => {
+ last_subexpr_str = new_rw;
+ }
+ _ => {
+ last_subexpr_str = Some(rw);
+ self.fits_single_line = could_fit_single_line && all_in_one_line;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ let last_shape = if context.use_block_indent() {
+ last_shape
+ } else {
+ child_shape.sub_width(shape.rhs_overhead(context.config) + last.tries)?
+ };
+
+ last_subexpr_str = last_subexpr_str.or_else(|| last.rewrite(context, last_shape));
+ self.rewrites.push(last_subexpr_str?);
+ Some(())
+ }
+
+ fn join_rewrites(&self, context: &RewriteContext, child_shape: Shape) -> Option<String> {
+ let connector = if self.fits_single_line {
+ // Yay, we can put everything on one line.
+ Cow::from("")
+ } else {
+ // Use new lines.
+ if *context.force_one_line_chain.borrow() {
+ return None;
+ }
+ child_shape.to_string_with_newline(context.config)
+ };
+
+ let mut rewrite_iter = self.rewrites.iter();
+ let mut result = rewrite_iter.next().unwrap().clone();
+ let children_iter = self.children.iter();
+ let iter = rewrite_iter.zip(children_iter);
+
+ for (rewrite, chain_item) in iter {
+ match chain_item.kind {
+ ChainItemKind::Comment(_, CommentPosition::Back) => result.push(' '),
+ ChainItemKind::Comment(_, CommentPosition::Top) => result.push_str(&connector),
+ _ => result.push_str(&connector),
+ }
+ result.push_str(&rewrite);
+ }
+
+ Some(result)
+ }
+}
+
+// Formats a chain using block indent.
+struct ChainFormatterBlock<'a> {
+ shared: ChainFormatterShared<'a>,
+ root_ends_with_block: bool,
+}
+
+impl<'a> ChainFormatterBlock<'a> {
+ fn new(chain: &'a Chain) -> ChainFormatterBlock<'a> {
+ ChainFormatterBlock {
+ shared: ChainFormatterShared::new(chain),
+ root_ends_with_block: false,
+ }
+ }
+}
+
+impl<'a> ChainFormatter for ChainFormatterBlock<'a> {
+ fn format_root(
+ &mut self,
+ parent: &ChainItem,
+ context: &RewriteContext,
+ shape: Shape,
+ ) -> Option<()> {
+ let mut root_rewrite: String = parent.rewrite(context, shape)?;
+
+ let mut root_ends_with_block = parent.kind.is_block_like(context, &root_rewrite);
+ let tab_width = context.config.tab_spaces().saturating_sub(shape.offset);
+
+ while root_rewrite.len() <= tab_width && !root_rewrite.contains('\n') {
+ let item = &self.shared.children[0];
+ if let ChainItemKind::Comment(..) = item.kind {
+ break;
+ }
+ let shape = shape.offset_left(root_rewrite.len())?;
+ match &item.rewrite(context, shape) {
+ Some(rewrite) => root_rewrite.push_str(rewrite),
+ None => break,
+ }
+
+ root_ends_with_block = last_line_extendable(&root_rewrite);
+
+ self.shared.children = &self.shared.children[1..];
+ if self.shared.children.is_empty() {
+ break;
+ }
+ }
+ self.shared.rewrites.push(root_rewrite);
+ self.root_ends_with_block = root_ends_with_block;
+ Some(())
+ }
+
+ fn child_shape(&self, context: &RewriteContext, shape: Shape) -> Option<Shape> {
+ Some(
+ if self.root_ends_with_block {
+ shape.block_indent(0)
+ } else {
+ shape.block_indent(context.config.tab_spaces())
+ }
+ .with_max_width(context.config),
+ )
+ }
+
+ fn format_children(&mut self, context: &RewriteContext, child_shape: Shape) -> Option<()> {
+ for item in &self.shared.children[..self.shared.children.len() - 1] {
+ let rewrite = item.rewrite(context, child_shape)?;
+ self.shared.rewrites.push(rewrite);
+ }
+ Some(())
+ }
+
+ fn format_last_child(
+ &mut self,
+ context: &RewriteContext,
+ shape: Shape,
+ child_shape: Shape,
+ ) -> Option<()> {
+ self.shared
+ .format_last_child(true, context, shape, child_shape)
+ }
+
+ fn join_rewrites(&self, context: &RewriteContext, child_shape: Shape) -> Option<String> {
+ self.shared.join_rewrites(context, child_shape)
+ }
+
+ fn pure_root(&mut self) -> Option<String> {
+ self.shared.pure_root()
+ }
+}
+
+// Format a chain using visual indent.
+struct ChainFormatterVisual<'a> {
+ shared: ChainFormatterShared<'a>,
+ // The extra offset from the chain's shape to the position of the `.`
+ offset: usize,
+}
+
+impl<'a> ChainFormatterVisual<'a> {
+ fn new(chain: &'a Chain) -> ChainFormatterVisual<'a> {
+ ChainFormatterVisual {
+ shared: ChainFormatterShared::new(chain),
+ offset: 0,
+ }
+ }
+}
+
+impl<'a> ChainFormatter for ChainFormatterVisual<'a> {
+ fn format_root(
+ &mut self,
+ parent: &ChainItem,
+ context: &RewriteContext,
+ shape: Shape,
+ ) -> Option<()> {
+ let parent_shape = shape.visual_indent(0);
+ let mut root_rewrite = parent.rewrite(context, parent_shape)?;
+ let multiline = root_rewrite.contains('\n');
+ self.offset = if multiline {
+ last_line_width(&root_rewrite).saturating_sub(shape.used_width())
+ } else {
+ trimmed_last_line_width(&root_rewrite)
+ };
+
+ if !multiline || parent.kind.is_block_like(context, &root_rewrite) {
+ let item = &self.shared.children[0];
+ if let ChainItemKind::Comment(..) = item.kind {
+ self.shared.rewrites.push(root_rewrite);
+ return Some(());
+ }
+ let child_shape = parent_shape
+ .visual_indent(self.offset)
+ .sub_width(self.offset)?;
+ let rewrite = item.rewrite(context, child_shape)?;
+ match wrap_str(rewrite, context.config.max_width(), shape) {
+ Some(rewrite) => root_rewrite.push_str(&rewrite),
+ None => {
+ // We couldn't fit in at the visual indent, try the last
+ // indent.
+ let rewrite = item.rewrite(context, parent_shape)?;
+ root_rewrite.push_str(&rewrite);
+ self.offset = 0;
+ }
+ }
+
+ self.shared.children = &self.shared.children[1..];
+ }
+
+ self.shared.rewrites.push(root_rewrite);
+ Some(())
+ }
+
+ fn child_shape(&self, context: &RewriteContext, shape: Shape) -> Option<Shape> {
+ shape
+ .with_max_width(context.config)
+ .offset_left(self.offset)
+ .map(|s| s.visual_indent(0))
+ }
+
+ fn format_children(&mut self, context: &RewriteContext, child_shape: Shape) -> Option<()> {
+ for item in &self.shared.children[..self.shared.children.len() - 1] {
+ let rewrite = item.rewrite(context, child_shape)?;
+ self.shared.rewrites.push(rewrite);
+ }
+ Some(())
+ }
+
+ fn format_last_child(
+ &mut self,
+ context: &RewriteContext,
+ shape: Shape,
+ child_shape: Shape,
+ ) -> Option<()> {
+ self.shared
+ .format_last_child(false, context, shape, child_shape)
+ }
+
+ fn join_rewrites(&self, context: &RewriteContext, child_shape: Shape) -> Option<String> {
+ self.shared.join_rewrites(context, child_shape)
+ }
+
+ fn pure_root(&mut self) -> Option<String> {
+ self.shared.pure_root()
+ }
+}
+
+/// Remove try operators (`?`s) that appear in the given string. If removing
+/// them leaves an empty line, remove that line as well unless it is the first
+/// line (we need the first newline for detecting pre/post comment).
+fn trim_tries(s: &str) -> String {
+ let mut result = String::with_capacity(s.len());
+ let mut line_buffer = String::with_capacity(s.len());
+ for (kind, rich_char) in CharClasses::new(s.chars()) {
+ match rich_char.get_char() {
+ '\n' => {
+ if result.is_empty() || !line_buffer.trim().is_empty() {
+ result.push_str(&line_buffer);
+ result.push('\n')
+ }
+ line_buffer.clear();
+ }
+ '?' if kind == FullCodeCharKind::Normal => continue,
+ c => line_buffer.push(c),
+ }
+ }
+ if !line_buffer.trim().is_empty() {
+ result.push_str(&line_buffer);
+ }
+ result
+}
diff --git a/homework/81030/1,2-rust2html/example-ugly.rs b/homework/81030/1,2-rust2html/example-ugly.rs
new file mode 100644
index 0000000..2b17e2f
--- /dev/null
+++ b/homework/81030/1,2-rust2html/example-ugly.rs
@@ -0,0 +1,29 @@
+/*
+ * The following function returns the first answer.
+ * It takes no arguments and returns an unsigned integer.
+ */
+fn answer1 () -> usize {
+ return 42; // answer to the Ultimate Question of Life, the Universe, and Everything
+}
+/*
+ * The following function returns the second answer.
+ * It takes no arguments and returns a floating-point number.
+ */
+fn answer2( ) -> f64
+{
+ return -4.2;
+}
+
+/*
+ * The following function returns the third answer.
+ * It takes no arguments and returns a single character.
+ */
+fn answer3() -> char {
+ return 'E' ; }
+
+
+fn main( ) {
+ println! ("The \"First Answer\" is: '{}'", answer1( ) );
+ println!("The \"Second Answer\" is: '{}'" , answer2()) ;
+ println!( "The \"Third Answer\" is: '{}'" , answer3 () );
+}
diff --git a/homework/81030/1,2-rust2html/example.rs b/homework/81030/1,2-rust2html/example.rs
new file mode 100644
index 0000000..396aa0c
--- /dev/null
+++ b/homework/81030/1,2-rust2html/example.rs
@@ -0,0 +1,29 @@
+/*
+ * The following function returns the first answer.
+ * It takes no arguments and returns an unsigned integer.
+ */
+fn answer1() -> usize {
+ return 42; // answer to the Ultimate Question of Life, the Universe, and Everything
+}
+
+/*
+ * The following function returns the second answer.
+ * It takes no arguments and returns a floating-point number.
+ */
+fn answer2() -> f64 {
+ return -4.2;
+}
+
+/*
+ * The following function returns the third answer.
+ * It takes no arguments and returns a single character.
+ */
+fn answer3() -> char {
+ return 'E';
+}
+
+fn main() {
+ println!("The \"First Answer\" is: '{}'", answer1());
+ println!("The \"Second Answer\" is: '{}'", answer2());
+ println!("The \"Third Answer\" is: '{}'", answer3());
+}
diff --git a/homework/81030/1,2-rust2html/rust2html-prettyprint.l b/homework/81030/1,2-rust2html/rust2html-prettyprint.l
new file mode 100644
index 0000000..2d90931
--- /dev/null
+++ b/homework/81030/1,2-rust2html/rust2html-prettyprint.l
@@ -0,0 +1,344 @@
+%option nounistd
+%option noyywrap
+%option stack
+
+%{
+#include <stdbool.h>
+
+#define INDENTATION " "
+#define SPACE " "
+#define HIGHLIGHT_TERMINATOR "</span>"
+
+#define PRINT_HIGHLIGHTED_TOKEN_INITIATOR(type) \
+ printf("<span class=\"" #type "\">%s", yytext)
+
+#define PRINT_HIGHLIGHTED_TOKEN_TERMINATOR \
+ printf("%s" HIGHLIGHT_TERMINATOR, yytext)
+
+#define PRINT_HIGHLIGHTED_TOKEN(type) \
+ printf("<span class=\"" #type "\">%s</span>", yytext)
+
+#define PRINT_TOKEN \
+ printf("%s", yytext)
+
+#define PRINT_INDENTED_NEWLINE \
+ printf("\n"); \
+ for (int i = 0; i < indentation_level; i++) \
+ printf(INDENTATION)
+
+#define CLEAR_MODES \
+ require_space_mode = false; \
+ adjacent_parenthesis_mode = false
+
+#define HANDLE_COMMENT_INITIATOR(type) \
+ PRINT_HIGHLIGHTED_TOKEN_INITIATOR(comment); \
+ yy_push_state(type); \
+ CLEAR_MODES
+
+#define HANDLE_LITERAL(type) \
+ if (require_space_mode) \
+ printf(SPACE); \
+ PRINT_HIGHLIGHTED_TOKEN(type); \
+ require_space_mode = true; \
+ adjacent_parenthesis_mode = false
+
+#define HANDLE_IDENTIFIER \
+ if (require_space_mode) \
+ printf(SPACE); \
+ PRINT_HIGHLIGHTED_TOKEN(identifier); \
+ require_space_mode = true; \
+ adjacent_parenthesis_mode = true
+
+#define HANDLE_EOL \
+ yy_pop_state(); \
+ adjacent_parenthesis_mode = true; \
+ yyless(0)
+
+static int indentation_level = 0;
+static bool require_space_mode = false;
+static bool adjacent_parenthesis_mode = false;
+%}
+
+%s multiline_list
+%s path
+%s directive
+
+%x line_comment
+%x block_comment
+%x eol
+
+NONEOL_CHAR .
+DEC_DIGIT 0|{NONZERO_DEC_DIGIT}
+NONZERO_DEC_DIGIT [1-9]
+OCT_DIGIT [0-7]
+HEX_DIGIT {DEC_DIGIT}|[a-fA-F]
+
+IDENTIFIER {IDENTIFIER_FIRST_CHAR}({DEC_DIGIT}|{IDENTIFIER_FIRST_CHAR})*
+IDENTIFIER_FIRST_CHAR [A-Za-z_]
+
+LINE_COMMENT_BEGIN "//"
+BLOCK_COMMENT_INITIATOR "/*"
+BLOCK_COMMENT_TERMINATOR "*/"
+
+KEYWORD _|abstract|alignof|as|become|box|break|const|continue|crate|do|else|enum|extern|false|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|offsetof|override|priv|proc|pub|pure|ref|return|Self|self|sizeof|static|struct|super|trait|true|type|typeof|unsafe|unsized|use|virtual|where|while|yield
+
+ESCAPE {COMMON_ESCAPE}|{UNICODE_ESCAPE}
+COMMON_ESCAPE \\|n|r|t|0|x{HEX_DIGIT}{2}
+UNICODE_ESCAPE "u{"{HEX_DIGIT}{6}"}"
+
+CHAR_LITERAL '{CHAR_BODY}'
+CHAR_BODY [^']|(\\('|{ESCAPE}))
+STRING_LITERAL \"{STRING_BODY}*\"
+STRING_BODY [^\"]|(\\(\"|{ESCAPE}))
+BYTE_CHAR_LITERAL b'{BYTE_CHAR_BODY}'
+BYTE_CHAR_BODY [^']|(\\('|{COMMON_ESCAPE}))
+BYTE_STRING_LITERAL b\"{BYTE_STRING_BODY}*\"
+BYTE_STRING_BODY [^\"]|(\\(\"|{ESCAPE}))
+
+NUMBER_LITERAL {NONZERO_DEC_DIGIT}{DEC_DIGIT}*{FLOAT_SUFFIX}?|(0{DEC_DIGIT_LITERAL}*{FLOAT_SUFFIX}?|b[10_]+|o{OCT_DIGIT_LITERAL}+|x{HEX_DIGIT_LITERAL}+)
+FLOAT_SUFFIX {EXPONENT}|"."{DEC_DIGIT_LITERAL}+{EXPONENT}?
+EXPONENT [Ee][-+]?{DEC_DIGIT_LITERAL}+
+DEC_DIGIT_LITERAL {DEC_DIGIT}|_
+HEX_DIGIT_LITERAL {HEX_DIGIT}|_
+OCT_DIGIT_LITERAL {OCT_DIGIT}|_
+
+%%
+
+<eol>[[:space:]]+
+
+<eol>";"|"}" {
+ HANDLE_EOL;
+}
+
+<eol>"else" {
+ HANDLE_EOL;
+ printf(SPACE);
+}
+
+<eol>. {
+ HANDLE_EOL;
+ PRINT_INDENTED_NEWLINE;
+}
+
+<line_comment>[[:blank:]]*\n {
+ yy_pop_state();
+ printf(HIGHLIGHT_TERMINATOR);
+ yy_push_state(eol);
+}
+
+<block_comment>{BLOCK_COMMENT_TERMINATOR} {
+ yy_pop_state();
+ PRINT_HIGHLIGHTED_TOKEN_TERMINATOR;
+ yy_push_state(eol);
+}
+
+<line_comment>. {
+ PRINT_TOKEN;
+}
+
+<block_comment>(.|\n) {
+ PRINT_TOKEN;
+}
+
+[[:space:]]+
+
+"use" {
+ HANDLE_LITERAL(keyword);
+ yy_push_state(path);
+}
+
+{KEYWORD} {
+ HANDLE_LITERAL(keyword);
+}
+
+{IDENTIFIER} {
+ HANDLE_IDENTIFIER;
+}
+
+{NUMBER_LITERAL} {
+ HANDLE_LITERAL(number);
+}
+
+{CHAR_LITERAL}|{STRING_LITERAL}|{BYTE_CHAR_LITERAL}|{BYTE_STRING_LITERAL} {
+ HANDLE_LITERAL(string);
+}
+
+{LINE_COMMENT_BEGIN} {
+ HANDLE_COMMENT_INITIATOR(line_comment);
+}
+
+{BLOCK_COMMENT_INITIATOR} {
+ HANDLE_COMMENT_INITIATOR(block_comment);
+}
+
+<multiline_list>"," {
+ PRINT_HIGHLIGHTED_TOKEN(symbol);
+ CLEAR_MODES;
+ yy_push_state(eol);
+}
+
+","|":" {
+ PRINT_HIGHLIGHTED_TOKEN(symbol);
+ require_space_mode = true;
+ adjacent_parenthesis_mode = false;
+}
+
+<path>";" {
+ yy_pop_state();
+ PRINT_HIGHLIGHTED_TOKEN(symbol);
+ CLEAR_MODES;
+ yy_push_state(eol);
+}
+
+";" {
+ PRINT_HIGHLIGHTED_TOKEN(symbol);
+ CLEAR_MODES;
+ yy_push_state(eol);
+}
+
+"#" {
+ PRINT_HIGHLIGHTED_TOKEN(symbol);
+ CLEAR_MODES;
+ yy_push_state(directive);
+}
+
+"?" {
+ PRINT_HIGHLIGHTED_TOKEN(symbol);
+ require_space_mode = true;
+ adjacent_parenthesis_mode = false;
+}
+
+"!" {
+ PRINT_HIGHLIGHTED_TOKEN(symbol);
+ require_space_mode = false;
+ adjacent_parenthesis_mode = true;
+}
+
+"."|"::"|"'"|"$"|"@"|"~" {
+ PRINT_HIGHLIGHTED_TOKEN(symbol);
+ CLEAR_MODES;
+}
+
+"=="|"=>"|"="|"!="|"<="|"<<"|"<<="|"<"|">="|">>"|">>="|">"|"<-"|"->"|"-"|"-="|"&&"|"&"|"&="|"||"|"|"|"|="|"+"|"+="|"*"|"*="|"/"|"/="|"^"|"^="|"%"|"%="|".."|"..." {
+ printf(SPACE);
+ PRINT_HIGHLIGHTED_TOKEN(symbol);
+ require_space_mode = true;
+ adjacent_parenthesis_mode = false;
+}
+
+"(" {
+ if (!adjacent_parenthesis_mode)
+ printf(SPACE);
+ PRINT_HIGHLIGHTED_TOKEN(symbol);
+ CLEAR_MODES;
+ yy_push_state(INITIAL);
+}
+
+<directive>"[" {
+ PRINT_HIGHLIGHTED_TOKEN(symbol);
+ CLEAR_MODES;
+}
+
+"[" {
+ PRINT_HIGHLIGHTED_TOKEN(symbol);
+ CLEAR_MODES;
+ yy_push_state(INITIAL);
+}
+
+<directive>"]" {
+ yy_pop_state();
+ PRINT_HIGHLIGHTED_TOKEN(symbol);
+ CLEAR_MODES;
+ yy_push_state(eol);
+}
+
+")"|"]" {
+ yy_pop_state();
+ PRINT_HIGHLIGHTED_TOKEN(symbol);
+ require_space_mode = true;
+ adjacent_parenthesis_mode = false;
+}
+
+<path>"{" {
+ PRINT_HIGHLIGHTED_TOKEN(symbol);
+ CLEAR_MODES;
+}
+
+"{" {
+ if (require_space_mode)
+ printf(SPACE);
+ indentation_level++;
+ PRINT_HIGHLIGHTED_TOKEN(symbol);
+ CLEAR_MODES;
+ yy_push_state(multiline_list);
+ yy_push_state(eol);
+}
+
+<path>"}" {
+ yy_pop_state();
+ PRINT_HIGHLIGHTED_TOKEN(symbol);
+ CLEAR_MODES;
+}
+
+"}" {
+ yy_pop_state();
+ indentation_level--;
+ PRINT_INDENTED_NEWLINE;
+ PRINT_HIGHLIGHTED_TOKEN(symbol);
+ if (0 == indentation_level)
+ printf("\n");
+ CLEAR_MODES;
+ yy_push_state(eol);
+}
+
+. {
+ PRINT_TOKEN; /* echo the rest */
+}
+
+%%
+
+int main(int argc, const char* const argv[]) {
+ yyin = argc > 1 ? fopen(argv[1], "r") : stdin;
+
+ printf(
+ "<!DOCTYPE html>\n"
+ "<html>\n"
+ "\n"
+ "<head>\n"
+ " <style>\n"
+ " .comment {\n"
+ " color: gray;\n"
+ " }\n"
+ "\n"
+ " .keyword {\n"
+ " color: red;\n"
+ " }\n"
+ "\n"
+ " .string {\n"
+ " color: green;\n"
+ " }\n"
+ "\n"
+ " .number {\n"
+ " color: blue;\n"
+ " }\n"
+ "\n"
+ " .symbol {\n"
+ " font-weight: bold;\n"
+ " }\n"
+ " </style>\n"
+ "</head>\n"
+ "\n"
+ "<body>\n"
+ " <pre class=\"code\">\n"
+ );
+ yylex();
+ printf(
+ "\n"
+ " </pre>\n"
+ "</body>\n"
+ "\n"
+ "</html>"
+ );
+
+ return 0;
+}
diff --git a/homework/81030/1,2-rust2html/rust2html.l b/homework/81030/1,2-rust2html/rust2html.l
new file mode 100644
index 0000000..de49285
--- /dev/null
+++ b/homework/81030/1,2-rust2html/rust2html.l
@@ -0,0 +1,130 @@
+%option nounistd
+%option noyywrap
+
+%{
+#define PRINT_HIGHLIGHTED_TOKEN(type) \
+ printf("<span class=\"" #type "\">%s</span>", yytext)
+%}
+
+NONEOL_CHAR .
+DEC_DIGIT 0|{NONZERO_DEC_DIGIT}
+NONZERO_DEC_DIGIT [1-9]
+OCT_DIGIT [0-7]
+HEX_DIGIT {DEC_DIGIT}|[a-fA-F]
+
+IDENTIFIER {IDENTIFIER_FIRST_CHAR}({DEC_DIGIT}|{IDENTIFIER_FIRST_CHAR})*
+IDENTIFIER_FIRST_CHAR [A-Za-z_]
+
+LINE_COMMENT "//"{NONEOL_CHAR}*
+BLOCK_COMMENT_INITIATOR "/*"
+BLOCK_COMMENT_TERMINATOR "*/"
+
+KEYWORD _|abstract|alignof|as|become|box|break|const|continue|crate|do|else|enum|extern|false|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|offsetof|override|priv|proc|pub|pure|ref|return|Self|self|sizeof|static|struct|super|trait|true|type|typeof|unsafe|unsized|use|virtual|where|while|yield
+
+ESCAPE {COMMON_ESCAPE}|{UNICODE_ESCAPE}
+COMMON_ESCAPE \\|n|r|t|0|x{HEX_DIGIT}{2}
+UNICODE_ESCAPE "u{"{HEX_DIGIT}{6}"}"
+
+CHAR_LITERAL '{CHAR_BODY}'
+CHAR_BODY [^']|(\\('|{ESCAPE}))
+STRING_LITERAL \"{STRING_BODY}*\"
+STRING_BODY [^\"]|(\\(\"|{ESCAPE}))
+BYTE_CHAR_LITERAL b'{BYTE_CHAR_BODY}'
+BYTE_CHAR_BODY [^']|(\\('|{COMMON_ESCAPE}))
+BYTE_STRING_LITERAL b\"{BYTE_STRING_BODY}*\"
+BYTE_STRING_BODY [^\"]|(\\(\"|{ESCAPE}))
+
+NUMBER_LITERAL {NONZERO_DEC_DIGIT}{DEC_DIGIT}*{FLOAT_SUFFIX}?|(0{DEC_DIGIT_LITERAL}*{FLOAT_SUFFIX}?|b[10_]+|o{OCT_DIGIT_LITERAL}+|x{HEX_DIGIT_LITERAL}+)
+FLOAT_SUFFIX {EXPONENT}|"."{DEC_DIGIT_LITERAL}+{EXPONENT}?
+EXPONENT [Ee][-+]?{DEC_DIGIT_LITERAL}+
+DEC_DIGIT_LITERAL {DEC_DIGIT}|_
+HEX_DIGIT_LITERAL {HEX_DIGIT}|_
+OCT_DIGIT_LITERAL {OCT_DIGIT}|_
+
+SYMBOL "::"|"->"|"#"|"["|"]"|"("|")"|"{"|"}"|","|";"|":"|"?"|"!"|"."|"'"|"$"|"@"|"~"|"=="|"=>"|"="|"!="|"<="|"<<"|"<<="|"<"|">="|">>"|">>="|">"|"<-"|"-"|"-="|"&&"|"&"|"&="|"||"|"|"|"|="|"+"|"+="|"*"|"*="|"/"|"/="|"^"|"^="|"%"|"%="|".."|"..."
+
+%%
+
+{SYMBOL} {
+ PRINT_HIGHLIGHTED_TOKEN(symbol);
+}
+
+{KEYWORD} {
+ PRINT_HIGHLIGHTED_TOKEN(keyword);
+}
+
+{IDENTIFIER} {
+ PRINT_HIGHLIGHTED_TOKEN(identifier);
+}
+
+{NUMBER_LITERAL} {
+ PRINT_HIGHLIGHTED_TOKEN(number);
+}
+
+{CHAR_LITERAL}|{STRING_LITERAL}|{BYTE_CHAR_LITERAL}|{BYTE_STRING_LITERAL} {
+ PRINT_HIGHLIGHTED_TOKEN(string);
+}
+
+{LINE_COMMENT} {
+ PRINT_HIGHLIGHTED_TOKEN(comment);
+}
+
+{BLOCK_COMMENT_INITIATOR} {
+ printf("<span class=\"comment\">%s", yytext);
+}
+
+{BLOCK_COMMENT_TERMINATOR} {
+ printf("%s</span>", yytext);
+}
+
+. {
+ printf("%s", yytext); /* echo the rest */
+}
+
+%%
+
+int main(int argc, const char* const argv[]) {
+ yyin = argc > 1 ? fopen(argv[1], "r") : stdin;
+
+ printf(
+ "<!DOCTYPE html>\n"
+ "<html>\n"
+ "\n"
+ "<head>\n"
+ " <style>\n"
+ " .comment {\n"
+ " color: gray;\n"
+ " }\n"
+ "\n"
+ " .keyword {\n"
+ " color: red;\n"
+ " }\n"
+ "\n"
+ " .string {\n"
+ " color: green;\n"
+ " }\n"
+ "\n"
+ " .number {\n"
+ " color: blue;\n"
+ " }\n"
+ "\n"
+ " .symbol {\n"
+ " font-weight: bold;\n"
+ " }\n"
+ " </style>\n"
+ "</head>\n"
+ "\n"
+ "<body>\n"
+ " <pre class=\"code\">\n"
+ );
+ yylex();
+ printf(
+ "\n"
+ " </pre>\n"
+ "</body>\n"
+ "\n"
+ "</html>"
+ );
+
+ return 0;
+}
diff --git a/homework/81030/example.rs b/homework/81030/example.rs
deleted file mode 100644
index e76448d..0000000
--- a/homework/81030/example.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-fn answer() -> usize {
- return 42;
-}
-
-fn main() {
- println!("The \"Answer\" is: '{}'", answer());
-} \ No newline at end of file
diff --git a/homework/81030/rust2html.c b/homework/81030/rust2html.c
deleted file mode 100644
index 17c5a9d..0000000
--- a/homework/81030/rust2html.c
+++ /dev/null
@@ -1,2090 +0,0 @@
-#line 1 "rust2html.c"
-
-#line 3 "rust2html.c"
-
-#define YY_INT_ALIGNED short int
-
-/* A lexical scanner generated by flex */
-
-#define FLEX_SCANNER
-#define YY_FLEX_MAJOR_VERSION 2
-#define YY_FLEX_MINOR_VERSION 6
-#define YY_FLEX_SUBMINOR_VERSION 4
-#if YY_FLEX_SUBMINOR_VERSION > 0
-#define FLEX_BETA
-#endif
-
-/* First, we deal with platform-specific or compiler-specific issues. */
-
-/* begin standard C headers. */
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-
-/* end standard C headers. */
-
-/* flex integer type definitions */
-
-#ifndef FLEXINT_H
-#define FLEXINT_H
-
-/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
-
-#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-
-/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
- * if you want the limit (max/min) macros for int types.
- */
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS 1
-#endif
-
-#include <inttypes.h>
-typedef int8_t flex_int8_t;
-typedef uint8_t flex_uint8_t;
-typedef int16_t flex_int16_t;
-typedef uint16_t flex_uint16_t;
-typedef int32_t flex_int32_t;
-typedef uint32_t flex_uint32_t;
-#else
-typedef signed char flex_int8_t;
-typedef short int flex_int16_t;
-typedef int flex_int32_t;
-typedef unsigned char flex_uint8_t;
-typedef unsigned short int flex_uint16_t;
-typedef unsigned int flex_uint32_t;
-
-/* Limits of integral types. */
-#ifndef INT8_MIN
-#define INT8_MIN (-128)
-#endif
-#ifndef INT16_MIN
-#define INT16_MIN (-32767-1)
-#endif
-#ifndef INT32_MIN
-#define INT32_MIN (-2147483647-1)
-#endif
-#ifndef INT8_MAX
-#define INT8_MAX (127)
-#endif
-#ifndef INT16_MAX
-#define INT16_MAX (32767)
-#endif
-#ifndef INT32_MAX
-#define INT32_MAX (2147483647)
-#endif
-#ifndef UINT8_MAX
-#define UINT8_MAX (255U)
-#endif
-#ifndef UINT16_MAX
-#define UINT16_MAX (65535U)
-#endif
-#ifndef UINT32_MAX
-#define UINT32_MAX (4294967295U)
-#endif
-
-#ifndef SIZE_MAX
-#define SIZE_MAX (~(size_t)0)
-#endif
-
-#endif /* ! C99 */
-
-#endif /* ! FLEXINT_H */
-
-/* begin standard C++ headers. */
-
-/* TODO: this is always defined, so inline it */
-#define yyconst const
-
-#if defined(__GNUC__) && __GNUC__ >= 3
-#define yynoreturn __attribute__((__noreturn__))
-#else
-#define yynoreturn
-#endif
-
-/* Returned upon end-of-file. */
-#define YY_NULL 0
-
-/* Promotes a possibly negative, possibly signed char to an
- * integer in range [0..255] for use as an array index.
- */
-#define YY_SC_TO_UI(c) ((YY_CHAR) (c))
-
-/* Enter a start condition. This macro really ought to take a parameter,
- * but we do it the disgusting crufty way forced on us by the ()-less
- * definition of BEGIN.
- */
-#define BEGIN (yy_start) = 1 + 2 *
-/* Translate the current start state into a value that can be later handed
- * to BEGIN to return to the state. The YYSTATE alias is for lex
- * compatibility.
- */
-#define YY_START (((yy_start) - 1) / 2)
-#define YYSTATE YY_START
-/* Action number for EOF rule of a given start state. */
-#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
-/* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE yyrestart( yyin )
-#define YY_END_OF_BUFFER_CHAR 0
-
-/* Size of default input buffer. */
-#ifndef YY_BUF_SIZE
-#ifdef __ia64__
-/* On IA-64, the buffer size is 16k, not 8k.
- * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
- * Ditto for the __ia64__ case accordingly.
- */
-#define YY_BUF_SIZE 32768
-#else
-#define YY_BUF_SIZE 16384
-#endif /* __ia64__ */
-#endif
-
-/* The state buf must be large enough to hold one state per character in the main buffer.
- */
-#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
-
-#ifndef YY_TYPEDEF_YY_BUFFER_STATE
-#define YY_TYPEDEF_YY_BUFFER_STATE
-typedef struct yy_buffer_state *YY_BUFFER_STATE;
-#endif
-
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef size_t yy_size_t;
-#endif
-
-extern int yyleng;
-
-extern FILE *yyin, *yyout;
-
-#define EOB_ACT_CONTINUE_SCAN 0
-#define EOB_ACT_END_OF_FILE 1
-#define EOB_ACT_LAST_MATCH 2
-
- #define YY_LESS_LINENO(n)
- #define YY_LINENO_REWIND_TO(ptr)
-
-/* Return all but the first "n" matched characters back to the input stream. */
-#define yyless(n) \
- do \
- { \
- /* Undo effects of setting up yytext. */ \
- int yyless_macro_arg = (n); \
- YY_LESS_LINENO(yyless_macro_arg);\
- *yy_cp = (yy_hold_char); \
- YY_RESTORE_YY_MORE_OFFSET \
- (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
- YY_DO_BEFORE_ACTION; /* set up yytext again */ \
- } \
- while ( 0 )
-#define unput(c) yyunput( c, (yytext_ptr) )
-
-#ifndef YY_STRUCT_YY_BUFFER_STATE
-#define YY_STRUCT_YY_BUFFER_STATE
-struct yy_buffer_state
- {
- FILE *yy_input_file;
-
- char *yy_ch_buf; /* input buffer */
- char *yy_buf_pos; /* current position in input buffer */
-
- /* Size of input buffer in bytes, not including room for EOB
- * characters.
- */
- int yy_buf_size;
-
- /* Number of characters read into yy_ch_buf, not including EOB
- * characters.
- */
- int yy_n_chars;
-
- /* Whether we "own" the buffer - i.e., we know we created it,
- * and can realloc() it to grow it, and should free() it to
- * delete it.
- */
- int yy_is_our_buffer;
-
- /* Whether this is an "interactive" input source; if so, and
- * if we're using stdio for input, then we want to use getc()
- * instead of fread(), to make sure we stop fetching input after
- * each newline.
- */
- int yy_is_interactive;
-
- /* Whether we're considered to be at the beginning of a line.
- * If so, '^' rules will be active on the next match, otherwise
- * not.
- */
- int yy_at_bol;
-
- int yy_bs_lineno; /**< The line count. */
- int yy_bs_column; /**< The column count. */
-
- /* Whether to try to fill the input buffer when we reach the
- * end of it.
- */
- int yy_fill_buffer;
-
- int yy_buffer_status;
-
-#define YY_BUFFER_NEW 0
-#define YY_BUFFER_NORMAL 1
- /* When an EOF's been seen but there's still some text to process
- * then we mark the buffer as YY_EOF_PENDING, to indicate that we
- * shouldn't try reading from the input source any more. We might
- * still have a bunch of tokens to match, though, because of
- * possible backing-up.
- *
- * When we actually see the EOF, we change the status to "new"
- * (via yyrestart()), so that the user can continue scanning by
- * just pointing yyin at a new input file.
- */
-#define YY_BUFFER_EOF_PENDING 2
-
- };
-#endif /* !YY_STRUCT_YY_BUFFER_STATE */
-
-/* Stack of input buffers. */
-static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
-static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
-static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */
-
-/* We provide macros for accessing buffer states in case in the
- * future we want to put the buffer states in a more general
- * "scanner state".
- *
- * Returns the top of the stack, or NULL.
- */
-#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
- ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
- : NULL)
-/* Same as previous macro, but useful when we know that the buffer stack is not
- * NULL or when we need an lvalue. For internal use only.
- */
-#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
-
-/* yy_hold_char holds the character lost when yytext is formed. */
-static char yy_hold_char;
-static int yy_n_chars; /* number of characters read into yy_ch_buf */
-int yyleng;
-
-/* Points to current character in buffer. */
-static char *yy_c_buf_p = NULL;
-static int yy_init = 0; /* whether we need to initialize */
-static int yy_start = 0; /* start state number */
-
-/* Flag which is used to allow yywrap()'s to do buffer switches
- * instead of setting up a fresh yyin. A bit of a hack ...
- */
-static int yy_did_buffer_switch_on_eof;
-
-void yyrestart ( FILE *input_file );
-void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer );
-YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size );
-void yy_delete_buffer ( YY_BUFFER_STATE b );
-void yy_flush_buffer ( YY_BUFFER_STATE b );
-void yypush_buffer_state ( YY_BUFFER_STATE new_buffer );
-void yypop_buffer_state ( void );
-
-static void yyensure_buffer_stack ( void );
-static void yy_load_buffer_state ( void );
-static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file );
-#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER )
-
-YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size );
-YY_BUFFER_STATE yy_scan_string ( const char *yy_str );
-YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len );
-
-void *yyalloc ( yy_size_t );
-void *yyrealloc ( void *, yy_size_t );
-void yyfree ( void * );
-
-#define yy_new_buffer yy_create_buffer
-#define yy_set_interactive(is_interactive) \
- { \
- if ( ! YY_CURRENT_BUFFER ){ \
- yyensure_buffer_stack (); \
- YY_CURRENT_BUFFER_LVALUE = \
- yy_create_buffer( yyin, YY_BUF_SIZE ); \
- } \
- YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
- }
-#define yy_set_bol(at_bol) \
- { \
- if ( ! YY_CURRENT_BUFFER ){\
- yyensure_buffer_stack (); \
- YY_CURRENT_BUFFER_LVALUE = \
- yy_create_buffer( yyin, YY_BUF_SIZE ); \
- } \
- YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
- }
-#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
-
-/* Begin user sect3 */
-typedef flex_uint8_t YY_CHAR;
-
-FILE *yyin = NULL, *yyout = NULL;
-
-typedef int yy_state_type;
-
-extern int yylineno;
-int yylineno = 1;
-
-extern char *yytext;
-#ifdef yytext_ptr
-#undef yytext_ptr
-#endif
-#define yytext_ptr yytext
-
-static yy_state_type yy_get_previous_state ( void );
-static yy_state_type yy_try_NUL_trans ( yy_state_type current_state );
-static int yy_get_next_buffer ( void );
-static void yynoreturn yy_fatal_error ( const char* msg );
-
-/* Done after the current pattern has been matched and before the
- * corresponding action - sets up yytext.
- */
-#define YY_DO_BEFORE_ACTION \
- (yytext_ptr) = yy_bp; \
- yyleng = (int) (yy_cp - yy_bp); \
- (yy_hold_char) = *yy_cp; \
- *yy_cp = '\0'; \
- (yy_c_buf_p) = yy_cp;
-#define YY_NUM_RULES 8
-#define YY_END_OF_BUFFER 9
-/* This struct is not used in this scanner,
- but its presence is necessary. */
-struct yy_trans_info
- {
- flex_int32_t yy_verify;
- flex_int32_t yy_nxt;
- };
-static const flex_int16_t yy_accept[247] =
- { 0,
- 0, 0, 9, 7, 8, 7, 1, 7, 7, 7,
- 3, 3, 7, 4, 4, 2, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 0, 5, 0, 0, 0,
- 1, 0, 6, 0, 3, 0, 0, 3, 0, 4,
- 4, 4, 4, 2, 0, 0, 3, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 3, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 3, 4, 5, 0, 0, 0, 0, 5, 0, 0,
-
- 0, 0, 6, 3, 0, 3, 3, 0, 3, 4,
- 4, 4, 0, 0, 0, 0, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 0,
- 0, 0, 0, 6, 0, 0, 4, 4, 5, 0,
- 0, 0, 0, 5, 0, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 2, 4, 4, 4, 4, 4, 4,
- 0, 0, 0, 0, 0, 3, 0, 3, 4, 4,
-
- 0, 0, 0, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 0, 0, 4, 4,
- 0, 0, 0, 4, 4, 4, 4, 4, 0, 0,
- 4, 0, 4, 4, 4, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0
- } ;
-
-static const YY_CHAR yy_ec[256] =
- { 0,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 3, 4, 1, 1, 1, 5, 6,
- 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
- 16, 16, 16, 16, 16, 17, 17, 18, 19, 1,
- 1, 20, 1, 1, 21, 21, 21, 21, 22, 21,
- 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
- 23, 23, 24, 23, 23, 23, 23, 23, 23, 23,
- 25, 26, 27, 1, 28, 1, 29, 30, 31, 32,
-
- 33, 34, 35, 36, 37, 23, 38, 39, 40, 41,
- 42, 43, 23, 44, 45, 46, 47, 48, 49, 50,
- 51, 52, 53, 1, 54, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1
- } ;
-
-static const YY_CHAR yy_meta[55] =
- { 0,
- 1, 2, 1, 1, 3, 1, 1, 1, 1, 1,
- 1, 1, 1, 4, 4, 4, 4, 1, 1, 1,
- 4, 4, 5, 5, 1, 1, 1, 5, 4, 4,
- 4, 4, 4, 4, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 1, 1
- } ;
-
-static const flex_int16_t yy_base[264] =
- { 0,
- 0, 0, 632, 759, 759, 52, 759, 605, 608, 48,
- 48, 57, 609, 0, 593, 0, 38, 77, 15, 573,
- 45, 56, 60, 25, 60, 97, 52, 581, 71, 65,
- 79, 576, 576, 132, 574, 100, 759, 126, 605, 145,
- 759, 599, 0, 127, 165, 185, 189, 204, 213, 0,
- 567, 560, 557, 0, 111, 567, 108, 561, 541, 557,
- 548, 557, 540, 537, 527, 533, 530, 526, 526, 522,
- 523, 84, 103, 518, 169, 529, 519, 90, 144, 41,
- 512, 498, 146, 506, 59, 505, 502, 511, 499, 101,
- 0, 509, 130, 205, 209, 207, 258, 526, 477, 0,
-
- 521, 201, 0, 229, 249, 253, 279, 283, 288, 494,
- 481, 491, 208, 303, 518, 310, 480, 492, 112, 464,
- 476, 468, 474, 461, 476, 463, 458, 456, 458, 455,
- 442, 442, 437, 453, 448, 433, 445, 435, 421, 418,
- 431, 426, 427, 426, 178, 407, 408, 412, 411, 347,
- 368, 0, 0, 441, 311, 377, 404, 400, 222, 282,
- 392, 306, 440, 432, 0, 395, 396, 386, 394, 397,
- 380, 390, 383, 378, 383, 384, 372, 371, 362, 366,
- 365, 343, 329, 331, 338, 319, 320, 333, 332, 326,
- 461, 307, 0, 352, 393, 397, 412, 430, 326, 310,
-
- 482, 503, 0, 315, 304, 302, 295, 303, 297, 301,
- 303, 285, 296, 288, 285, 284, 524, 0, 255, 249,
- 545, 311, 277, 231, 234, 239, 226, 215, 566, 0,
- 206, 587, 216, 213, 209, 608, 0, 629, 650, 0,
- 671, 316, 186, 692, 320, 759, 726, 731, 733, 738,
- 743, 748, 753, 235, 234, 232, 228, 174, 165, 164,
- 135, 124, 62
- } ;
-
-static const flex_int16_t yy_def[264] =
- { 0,
- 246, 1, 246, 246, 246, 247, 246, 248, 246, 246,
- 246, 246, 246, 249, 249, 249, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 247, 246, 247, 246, 246,
- 246, 250, 251, 246, 246, 246, 246, 246, 246, 249,
- 249, 249, 249, 249, 252, 253, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
- 34, 249, 247, 247, 247, 247, 247, 246, 246, 254,
-
- 250, 250, 251, 246, 246, 246, 246, 246, 246, 249,
- 249, 249, 252, 252, 246, 246, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 249, 249, 249, 249, 97,
- 97, 255, 256, 250, 246, 246, 249, 249, 252, 252,
- 252, 252, 252, 246, 257, 249, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
- 97, 247, 258, 246, 246, 246, 246, 246, 249, 249,
-
- 163, 163, 259, 249, 249, 249, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 249, 97, 260, 249, 249,
- 163, 252, 246, 249, 249, 249, 249, 249, 97, 261,
- 249, 163, 249, 249, 249, 97, 262, 163, 97, 263,
- 163, 247, 246, 163, 252, 0, 246, 246, 246, 246,
- 246, 246, 246, 246, 246, 246, 246, 246, 246, 246,
- 246, 246, 246
- } ;
-
-static const flex_int16_t yy_nxt[814] =
- { 0,
- 4, 5, 6, 7, 8, 7, 7, 4, 4, 7,
- 9, 4, 10, 11, 12, 12, 12, 13, 7, 4,
- 14, 14, 14, 15, 7, 4, 7, 16, 17, 18,
- 19, 20, 21, 22, 14, 14, 23, 14, 24, 25,
- 14, 26, 27, 28, 29, 30, 31, 32, 33, 34,
- 35, 14, 7, 7, 37, 42, 61, 70, 62, 44,
- 43, 45, 45, 45, 45, 243, 71, 52, 47, 46,
- 48, 48, 48, 48, 54, 45, 53, 38, 49, 55,
- 46, 56, 54, 63, 66, 64, 136, 142, 72, 49,
- 57, 57, 67, 54, 65, 78, 54, 68, 79, 69,
-
- 54, 73, 37, 81, 57, 143, 74, 82, 85, 58,
- 75, 75, 75, 37, 128, 86, 83, 84, 59, 87,
- 60, 57, 57, 88, 75, 38, 133, 240, 93, 129,
- 76, 134, 37, 147, 54, 57, 114, 148, 237, 94,
- 104, 104, 104, 104, 77, 91, 91, 91, 91, 98,
- 130, 95, 91, 91, 104, 38, 168, 169, 39, 91,
- 91, 91, 91, 91, 91, 91, 94, 230, 223, 94,
- 39, 94, 96, 54, 139, 97, 44, 218, 45, 45,
- 45, 45, 75, 75, 75, 39, 46, 135, 39, 140,
- 39, 99, 45, 105, 100, 105, 75, 46, 106, 106,
-
- 106, 106, 107, 107, 107, 107, 185, 37, 102, 37,
- 37, 93, 106, 154, 186, 47, 107, 48, 48, 48,
- 48, 108, 94, 108, 37, 49, 109, 109, 109, 109,
- 38, 203, 38, 114, 95, 194, 49, 193, 153, 39,
- 109, 54, 104, 104, 104, 104, 54, 114, 54, 94,
- 155, 54, 94, 54, 94, 96, 104, 54, 97, 150,
- 37, 155, 106, 106, 106, 106, 106, 106, 106, 106,
- 235, 151, 151, 151, 151, 234, 106, 233, 151, 151,
- 106, 37, 54, 38, 37, 231, 151, 151, 151, 151,
- 151, 151, 107, 107, 107, 107, 109, 109, 109, 109,
-
- 156, 109, 109, 109, 109, 159, 107, 114, 37, 37,
- 109, 156, 228, 37, 164, 109, 160, 227, 37, 195,
- 54, 195, 37, 115, 196, 196, 196, 196, 161, 54,
- 54, 114, 38, 54, 54, 115, 114, 54, 196, 226,
- 225, 38, 54, 160, 224, 114, 160, 54, 160, 162,
- 115, 220, 163, 115, 219, 115, 37, 54, 201, 165,
- 191, 191, 191, 191, 54, 54, 216, 191, 191, 94,
- 215, 214, 213, 160, 54, 191, 191, 191, 191, 191,
- 191, 192, 192, 192, 192, 197, 54, 197, 192, 192,
- 198, 198, 198, 198, 159, 212, 192, 192, 192, 192,
-
- 192, 192, 211, 210, 198, 160, 196, 196, 196, 196,
- 196, 196, 196, 196, 209, 208, 207, 161, 54, 54,
- 196, 54, 54, 206, 196, 198, 198, 198, 198, 54,
- 205, 54, 160, 54, 204, 160, 37, 160, 162, 198,
- 200, 163, 37, 198, 198, 198, 198, 199, 102, 190,
- 189, 188, 187, 202, 202, 202, 202, 198, 184, 54,
- 202, 202, 183, 182, 181, 114, 180, 179, 202, 202,
- 202, 202, 202, 202, 217, 217, 217, 217, 54, 178,
- 54, 217, 217, 54, 54, 177, 176, 54, 175, 217,
- 217, 217, 217, 217, 217, 221, 221, 221, 221, 174,
-
- 54, 54, 221, 221, 173, 172, 171, 54, 54, 170,
- 221, 221, 221, 221, 221, 221, 222, 222, 222, 222,
- 167, 166, 37, 222, 222, 158, 157, 54, 102, 152,
- 37, 222, 222, 222, 222, 222, 222, 229, 229, 229,
- 229, 149, 146, 54, 229, 229, 145, 144, 141, 138,
- 137, 132, 229, 229, 229, 229, 229, 229, 232, 232,
- 232, 232, 131, 54, 127, 232, 232, 54, 126, 54,
- 125, 124, 123, 232, 232, 232, 232, 232, 232, 236,
- 236, 236, 236, 122, 121, 120, 236, 236, 119, 118,
- 54, 117, 116, 112, 236, 236, 236, 236, 236, 236,
-
- 238, 238, 238, 238, 111, 110, 102, 238, 238, 37,
- 92, 90, 89, 80, 54, 238, 238, 238, 238, 238,
- 238, 239, 239, 239, 239, 51, 41, 41, 239, 239,
- 40, 246, 246, 246, 246, 246, 239, 239, 239, 239,
- 239, 239, 241, 241, 241, 241, 246, 246, 246, 241,
- 241, 246, 246, 246, 246, 246, 246, 241, 241, 241,
- 241, 241, 241, 242, 242, 242, 242, 246, 246, 246,
- 242, 242, 246, 246, 246, 246, 246, 246, 242, 242,
- 242, 242, 242, 242, 244, 244, 244, 244, 246, 246,
- 246, 244, 244, 246, 246, 246, 246, 246, 246, 244,
-
- 244, 244, 244, 244, 244, 245, 245, 245, 245, 246,
- 246, 246, 245, 245, 246, 246, 246, 246, 246, 246,
- 245, 245, 245, 245, 245, 245, 36, 36, 36, 36,
- 36, 39, 39, 246, 39, 39, 50, 50, 101, 246,
- 101, 101, 101, 103, 246, 103, 103, 103, 113, 113,
- 113, 113, 113, 115, 115, 246, 115, 115, 3, 246,
- 246, 246, 246, 246, 246, 246, 246, 246, 246, 246,
- 246, 246, 246, 246, 246, 246, 246, 246, 246, 246,
- 246, 246, 246, 246, 246, 246, 246, 246, 246, 246,
- 246, 246, 246, 246, 246, 246, 246, 246, 246, 246,
-
- 246, 246, 246, 246, 246, 246, 246, 246, 246, 246,
- 246, 246, 246
- } ;
-
-static const flex_int16_t yy_chk[814] =
- { 0,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 6, 10, 19, 24, 19, 11,
- 10, 11, 11, 11, 11, 263, 24, 17, 12, 11,
- 12, 12, 12, 12, 80, 11, 17, 6, 12, 18,
- 11, 18, 17, 21, 22, 21, 80, 85, 25, 12,
- 18, 18, 22, 23, 21, 27, 22, 22, 27, 23,
-
- 23, 25, 36, 29, 18, 85, 25, 29, 30, 18,
- 26, 26, 26, 55, 72, 30, 29, 29, 18, 31,
- 18, 57, 57, 31, 26, 36, 78, 262, 38, 72,
- 26, 78, 93, 90, 73, 57, 55, 90, 261, 38,
- 44, 44, 44, 44, 26, 34, 34, 34, 34, 40,
- 73, 38, 34, 34, 44, 93, 119, 119, 40, 34,
- 34, 34, 34, 34, 34, 34, 38, 260, 259, 38,
- 40, 38, 38, 79, 83, 38, 45, 258, 45, 45,
- 45, 45, 75, 75, 75, 40, 45, 79, 40, 83,
- 40, 40, 45, 46, 40, 46, 75, 45, 46, 46,
-
- 46, 46, 47, 47, 47, 47, 145, 94, 102, 96,
- 113, 95, 46, 102, 145, 48, 47, 48, 48, 48,
- 48, 49, 95, 49, 159, 48, 49, 49, 49, 49,
- 94, 257, 96, 113, 95, 256, 48, 255, 254, 243,
- 49, 235, 104, 104, 104, 104, 234, 159, 233, 95,
- 104, 231, 95, 228, 95, 95, 104, 227, 95, 96,
- 97, 104, 105, 105, 105, 105, 106, 106, 106, 106,
- 226, 97, 97, 97, 97, 225, 105, 224, 97, 97,
- 106, 223, 220, 97, 160, 219, 97, 97, 97, 97,
- 97, 97, 107, 107, 107, 107, 108, 108, 108, 108,
-
- 107, 109, 109, 109, 109, 114, 107, 160, 162, 192,
- 108, 107, 216, 222, 116, 109, 114, 215, 242, 155,
- 214, 155, 245, 116, 155, 155, 155, 155, 114, 213,
- 212, 162, 192, 211, 210, 116, 222, 209, 155, 208,
- 207, 242, 206, 114, 205, 245, 114, 204, 114, 114,
- 116, 200, 114, 116, 199, 116, 194, 190, 162, 116,
- 150, 150, 150, 150, 189, 188, 187, 150, 150, 242,
- 186, 185, 184, 245, 183, 150, 150, 150, 150, 150,
- 150, 151, 151, 151, 151, 156, 182, 156, 151, 151,
- 156, 156, 156, 156, 161, 181, 151, 151, 151, 151,
-
- 151, 151, 180, 179, 156, 161, 195, 195, 195, 195,
- 196, 196, 196, 196, 178, 177, 176, 161, 175, 174,
- 195, 173, 172, 171, 196, 197, 197, 197, 197, 170,
- 169, 168, 161, 167, 166, 161, 164, 161, 161, 197,
- 158, 161, 163, 198, 198, 198, 198, 157, 154, 149,
- 148, 147, 146, 163, 163, 163, 163, 198, 144, 143,
- 163, 163, 142, 141, 140, 163, 139, 138, 163, 163,
- 163, 163, 163, 163, 191, 191, 191, 191, 137, 136,
- 135, 191, 191, 134, 133, 132, 131, 130, 129, 191,
- 191, 191, 191, 191, 191, 201, 201, 201, 201, 128,
-
- 127, 126, 201, 201, 125, 124, 123, 122, 121, 120,
- 201, 201, 201, 201, 201, 201, 202, 202, 202, 202,
- 118, 117, 115, 202, 202, 112, 111, 110, 101, 99,
- 98, 202, 202, 202, 202, 202, 202, 217, 217, 217,
- 217, 92, 89, 88, 217, 217, 87, 86, 84, 82,
- 81, 77, 217, 217, 217, 217, 217, 217, 221, 221,
- 221, 221, 76, 74, 71, 221, 221, 70, 69, 68,
- 67, 66, 65, 221, 221, 221, 221, 221, 221, 229,
- 229, 229, 229, 64, 63, 62, 229, 229, 61, 60,
- 59, 58, 56, 53, 229, 229, 229, 229, 229, 229,
-
- 232, 232, 232, 232, 52, 51, 42, 232, 232, 39,
- 35, 33, 32, 28, 20, 232, 232, 232, 232, 232,
- 232, 236, 236, 236, 236, 15, 13, 9, 236, 236,
- 8, 3, 0, 0, 0, 0, 236, 236, 236, 236,
- 236, 236, 238, 238, 238, 238, 0, 0, 0, 238,
- 238, 0, 0, 0, 0, 0, 0, 238, 238, 238,
- 238, 238, 238, 239, 239, 239, 239, 0, 0, 0,
- 239, 239, 0, 0, 0, 0, 0, 0, 239, 239,
- 239, 239, 239, 239, 241, 241, 241, 241, 0, 0,
- 0, 241, 241, 0, 0, 0, 0, 0, 0, 241,
-
- 241, 241, 241, 241, 241, 244, 244, 244, 244, 0,
- 0, 0, 244, 244, 0, 0, 0, 0, 0, 0,
- 244, 244, 244, 244, 244, 244, 247, 247, 247, 247,
- 247, 248, 248, 0, 248, 248, 249, 249, 250, 0,
- 250, 250, 250, 251, 0, 251, 251, 251, 252, 252,
- 252, 252, 252, 253, 253, 0, 253, 253, 246, 246,
- 246, 246, 246, 246, 246, 246, 246, 246, 246, 246,
- 246, 246, 246, 246, 246, 246, 246, 246, 246, 246,
- 246, 246, 246, 246, 246, 246, 246, 246, 246, 246,
- 246, 246, 246, 246, 246, 246, 246, 246, 246, 246,
-
- 246, 246, 246, 246, 246, 246, 246, 246, 246, 246,
- 246, 246, 246
- } ;
-
-static yy_state_type yy_last_accepting_state;
-static char *yy_last_accepting_cpos;
-
-extern int yy_flex_debug;
-int yy_flex_debug = 0;
-
-/* The intent behind this definition is that it'll catch
- * any uses of REJECT which flex missed.
- */
-#define REJECT reject_used_but_not_detected
-#define yymore() yymore_used_but_not_detected
-#define YY_MORE_ADJ 0
-#define YY_RESTORE_YY_MORE_OFFSET
-char *yytext;
-#line 1 "rust2html.flex"
-/* scanner for the Rust programming language */
-#line 4 "rust2html.flex"
-#define YY_NO_UNISTD_H
-#line 709 "rust2html.c"
-#line 710 "rust2html.c"
-
-#define INITIAL 0
-
-#ifndef YY_NO_UNISTD_H
-/* Special case for "unistd.h", since it is non-ANSI. We include it way
- * down here because we want the user's section 1 to have been scanned first.
- * The user has a chance to override it with an option.
- */
-#include <unistd.h>
-#endif
-
-#ifndef YY_EXTRA_TYPE
-#define YY_EXTRA_TYPE void *
-#endif
-
-static int yy_init_globals ( void );
-
-/* Accessor methods to globals.
- These are made visible to non-reentrant scanners for convenience. */
-
-int yylex_destroy ( void );
-
-int yyget_debug ( void );
-
-void yyset_debug ( int debug_flag );
-
-YY_EXTRA_TYPE yyget_extra ( void );
-
-void yyset_extra ( YY_EXTRA_TYPE user_defined );
-
-FILE *yyget_in ( void );
-
-void yyset_in ( FILE * _in_str );
-
-FILE *yyget_out ( void );
-
-void yyset_out ( FILE * _out_str );
-
- int yyget_leng ( void );
-
-char *yyget_text ( void );
-
-int yyget_lineno ( void );
-
-void yyset_lineno ( int _line_number );
-
-/* Macros after this point can all be overridden by user definitions in
- * section 1.
- */
-
-#ifndef YY_SKIP_YYWRAP
-#ifdef __cplusplus
-extern "C" int yywrap ( void );
-#else
-extern int yywrap ( void );
-#endif
-#endif
-
-#ifndef YY_NO_UNPUT
-
- static void yyunput ( int c, char *buf_ptr );
-
-#endif
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy ( char *, const char *, int );
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen ( const char * );
-#endif
-
-#ifndef YY_NO_INPUT
-#ifdef __cplusplus
-static int yyinput ( void );
-#else
-static int input ( void );
-#endif
-
-#endif
-
-/* Amount of stuff to slurp up with each read. */
-#ifndef YY_READ_BUF_SIZE
-#ifdef __ia64__
-/* On IA-64, the buffer size is 16k, not 8k */
-#define YY_READ_BUF_SIZE 16384
-#else
-#define YY_READ_BUF_SIZE 8192
-#endif /* __ia64__ */
-#endif
-
-/* Copy whatever the last rule matched to the standard output. */
-#ifndef ECHO
-/* This used to be an fputs(), but since the string might contain NUL's,
- * we now use fwrite().
- */
-#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0)
-#endif
-
-/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
- * is returned in "result".
- */
-#ifndef YY_INPUT
-#define YY_INPUT(buf,result,max_size) \
- if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
- { \
- int c = '*'; \
- int n; \
- for ( n = 0; n < max_size && \
- (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
- buf[n] = (char) c; \
- if ( c == '\n' ) \
- buf[n++] = (char) c; \
- if ( c == EOF && ferror( yyin ) ) \
- YY_FATAL_ERROR( "input in flex scanner failed" ); \
- result = n; \
- } \
- else \
- { \
- errno=0; \
- while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \
- { \
- if( errno != EINTR) \
- { \
- YY_FATAL_ERROR( "input in flex scanner failed" ); \
- break; \
- } \
- errno=0; \
- clearerr(yyin); \
- } \
- }\
-\
-
-#endif
-
-/* No semi-colon after return; correct usage is to write "yyterminate();" -
- * we don't want an extra ';' after the "return" because that will cause
- * some compilers to complain about unreachable statements.
- */
-#ifndef yyterminate
-#define yyterminate() return YY_NULL
-#endif
-
-/* Number of entries by which start-condition stack grows. */
-#ifndef YY_START_STACK_INCR
-#define YY_START_STACK_INCR 25
-#endif
-
-/* Report a fatal error. */
-#ifndef YY_FATAL_ERROR
-#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
-#endif
-
-/* end tables serialization structures and prototypes */
-
-/* Default declaration of generated scanner - a define so the user can
- * easily add parameters.
- */
-#ifndef YY_DECL
-#define YY_DECL_IS_OURS 1
-
-extern int yylex (void);
-
-#define YY_DECL int yylex (void)
-#endif /* !YY_DECL */
-
-/* Code executed at the beginning of each rule, after yytext and yyleng
- * have been set up.
- */
-#ifndef YY_USER_ACTION
-#define YY_USER_ACTION
-#endif
-
-/* Code executed at the end of each rule. */
-#ifndef YY_BREAK
-#define YY_BREAK /*LINTED*/break;
-#endif
-
-#define YY_RULE_SETUP \
- YY_USER_ACTION
-
-/** The main scanner function which does all the work.
- */
-YY_DECL
-{
- yy_state_type yy_current_state;
- char *yy_cp, *yy_bp;
- int yy_act;
-
- if ( !(yy_init) )
- {
- (yy_init) = 1;
-
-#ifdef YY_USER_INIT
- YY_USER_INIT;
-#endif
-
- if ( ! (yy_start) )
- (yy_start) = 1; /* first start state */
-
- if ( ! yyin )
- yyin = stdin;
-
- if ( ! yyout )
- yyout = stdout;
-
- if ( ! YY_CURRENT_BUFFER ) {
- yyensure_buffer_stack ();
- YY_CURRENT_BUFFER_LVALUE =
- yy_create_buffer( yyin, YY_BUF_SIZE );
- }
-
- yy_load_buffer_state( );
- }
-
- {
-#line 44 "rust2html.flex"
-
-
-#line 930 "rust2html.c"
-
- while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
- {
- yy_cp = (yy_c_buf_p);
-
- /* Support of yytext. */
- *yy_cp = (yy_hold_char);
-
- /* yy_bp points to the position in yy_ch_buf of the start of
- * the current run.
- */
- yy_bp = yy_cp;
-
- yy_current_state = (yy_start);
-yy_match:
- do
- {
- YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
- if ( yy_accept[yy_current_state] )
- {
- (yy_last_accepting_state) = yy_current_state;
- (yy_last_accepting_cpos) = yy_cp;
- }
- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
- {
- yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 247 )
- yy_c = yy_meta[yy_c];
- }
- yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
- ++yy_cp;
- }
- while ( yy_base[yy_current_state] != 759 );
-
-yy_find_action:
- yy_act = yy_accept[yy_current_state];
- if ( yy_act == 0 )
- { /* have to back up */
- yy_cp = (yy_last_accepting_cpos);
- yy_current_state = (yy_last_accepting_state);
- yy_act = yy_accept[yy_current_state];
- }
-
- YY_DO_BEFORE_ACTION;
-
-do_action: /* This label is used only to access EOF actions. */
-
- switch ( yy_act )
- { /* beginning of action switch */
- case 0: /* must back up */
- /* undo the effects of YY_DO_BEFORE_ACTION */
- *yy_cp = (yy_hold_char);
- yy_cp = (yy_last_accepting_cpos);
- yy_current_state = (yy_last_accepting_state);
- goto yy_find_action;
-
-case 1:
-YY_RULE_SETUP
-#line 46 "rust2html.flex"
-{
- printf("<span class=\"symbol\">%s</span>", yytext);
-}
- YY_BREAK
-case 2:
-YY_RULE_SETUP
-#line 50 "rust2html.flex"
-{
- printf("<span class=\"keyword\">%s</span>", yytext);
-}
- YY_BREAK
-case 3:
-YY_RULE_SETUP
-#line 54 "rust2html.flex"
-{
- printf("<span class=\"number\">%s</span>", yytext);
-}
- YY_BREAK
-case 4:
-YY_RULE_SETUP
-#line 58 "rust2html.flex"
-{
- printf("<span class=\"identifier\">%s</span>", yytext);
-}
- YY_BREAK
-case 5:
-/* rule 5 can match eol */
-YY_RULE_SETUP
-#line 62 "rust2html.flex"
-{
- printf("<span class=\"string\">%s</span>", yytext);
-}
- YY_BREAK
-case 6:
-YY_RULE_SETUP
-#line 66 "rust2html.flex"
-{
- printf("<span class=\"comment\">%s</span>", yytext);
-}
- YY_BREAK
-case 7:
-YY_RULE_SETUP
-#line 70 "rust2html.flex"
-{
- printf("%s", yytext); /* echo the rest */
-}
- YY_BREAK
-case 8:
-YY_RULE_SETUP
-#line 74 "rust2html.flex"
-ECHO;
- YY_BREAK
-#line 1042 "rust2html.c"
-case YY_STATE_EOF(INITIAL):
- yyterminate();
-
- case YY_END_OF_BUFFER:
- {
- /* Amount of text matched not including the EOB char. */
- int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
-
- /* Undo the effects of YY_DO_BEFORE_ACTION. */
- *yy_cp = (yy_hold_char);
- YY_RESTORE_YY_MORE_OFFSET
-
- if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
- {
- /* We're scanning a new file or input source. It's
- * possible that this happened because the user
- * just pointed yyin at a new source and called
- * yylex(). If so, then we have to assure
- * consistency between YY_CURRENT_BUFFER and our
- * globals. Here is the right place to do so, because
- * this is the first action (other than possibly a
- * back-up) that will match for the new input source.
- */
- (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
- YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
- YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
- }
-
- /* Note that here we test for yy_c_buf_p "<=" to the position
- * of the first EOB in the buffer, since yy_c_buf_p will
- * already have been incremented past the NUL character
- * (since all states make transitions on EOB to the
- * end-of-buffer state). Contrast this with the test
- * in input().
- */
- if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
- { /* This was really a NUL. */
- yy_state_type yy_next_state;
-
- (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
-
- yy_current_state = yy_get_previous_state( );
-
- /* Okay, we're now positioned to make the NUL
- * transition. We couldn't have
- * yy_get_previous_state() go ahead and do it
- * for us because it doesn't know how to deal
- * with the possibility of jamming (and we don't
- * want to build jamming into it because then it
- * will run more slowly).
- */
-
- yy_next_state = yy_try_NUL_trans( yy_current_state );
-
- yy_bp = (yytext_ptr) + YY_MORE_ADJ;
-
- if ( yy_next_state )
- {
- /* Consume the NUL. */
- yy_cp = ++(yy_c_buf_p);
- yy_current_state = yy_next_state;
- goto yy_match;
- }
-
- else
- {
- yy_cp = (yy_c_buf_p);
- goto yy_find_action;
- }
- }
-
- else switch ( yy_get_next_buffer( ) )
- {
- case EOB_ACT_END_OF_FILE:
- {
- (yy_did_buffer_switch_on_eof) = 0;
-
- if ( yywrap( ) )
- {
- /* Note: because we've taken care in
- * yy_get_next_buffer() to have set up
- * yytext, we can now set up
- * yy_c_buf_p so that if some total
- * hoser (like flex itself) wants to
- * call the scanner after we return the
- * YY_NULL, it'll still work - another
- * YY_NULL will get returned.
- */
- (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
-
- yy_act = YY_STATE_EOF(YY_START);
- goto do_action;
- }
-
- else
- {
- if ( ! (yy_did_buffer_switch_on_eof) )
- YY_NEW_FILE;
- }
- break;
- }
-
- case EOB_ACT_CONTINUE_SCAN:
- (yy_c_buf_p) =
- (yytext_ptr) + yy_amount_of_matched_text;
-
- yy_current_state = yy_get_previous_state( );
-
- yy_cp = (yy_c_buf_p);
- yy_bp = (yytext_ptr) + YY_MORE_ADJ;
- goto yy_match;
-
- case EOB_ACT_LAST_MATCH:
- (yy_c_buf_p) =
- &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
-
- yy_current_state = yy_get_previous_state( );
-
- yy_cp = (yy_c_buf_p);
- yy_bp = (yytext_ptr) + YY_MORE_ADJ;
- goto yy_find_action;
- }
- break;
- }
-
- default:
- YY_FATAL_ERROR(
- "fatal flex scanner internal error--no action found" );
- } /* end of action switch */
- } /* end of scanning one token */
- } /* end of user's declarations */
-} /* end of yylex */
-
-/* yy_get_next_buffer - try to read in a new buffer
- *
- * Returns a code representing an action:
- * EOB_ACT_LAST_MATCH -
- * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
- * EOB_ACT_END_OF_FILE - end of file
- */
-static int yy_get_next_buffer (void)
-{
- char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
- char *source = (yytext_ptr);
- int number_to_move, i;
- int ret_val;
-
- if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
- YY_FATAL_ERROR(
- "fatal flex scanner internal error--end of buffer missed" );
-
- if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
- { /* Don't try to fill the buffer, so this is an EOF. */
- if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
- {
- /* We matched a single character, the EOB, so
- * treat this as a final EOF.
- */
- return EOB_ACT_END_OF_FILE;
- }
-
- else
- {
- /* We matched some text prior to the EOB, first
- * process it.
- */
- return EOB_ACT_LAST_MATCH;
- }
- }
-
- /* Try to read more data. */
-
- /* First move last chars to start of buffer. */
- number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1);
-
- for ( i = 0; i < number_to_move; ++i )
- *(dest++) = *(source++);
-
- if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
- /* don't do the read, it's not guaranteed to return an EOF,
- * just force an EOF
- */
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
-
- else
- {
- int num_to_read =
- YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
-
- while ( num_to_read <= 0 )
- { /* Not enough room in the buffer - grow it. */
-
- /* just a shorter name for the current buffer */
- YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
-
- int yy_c_buf_p_offset =
- (int) ((yy_c_buf_p) - b->yy_ch_buf);
-
- if ( b->yy_is_our_buffer )
- {
- int new_size = b->yy_buf_size * 2;
-
- if ( new_size <= 0 )
- b->yy_buf_size += b->yy_buf_size / 8;
- else
- b->yy_buf_size *= 2;
-
- b->yy_ch_buf = (char *)
- /* Include room in for 2 EOB chars. */
- yyrealloc( (void *) b->yy_ch_buf,
- (yy_size_t) (b->yy_buf_size + 2) );
- }
- else
- /* Can't grow it, we don't own it. */
- b->yy_ch_buf = NULL;
-
- if ( ! b->yy_ch_buf )
- YY_FATAL_ERROR(
- "fatal error - scanner input buffer overflow" );
-
- (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
-
- num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
- number_to_move - 1;
-
- }
-
- if ( num_to_read > YY_READ_BUF_SIZE )
- num_to_read = YY_READ_BUF_SIZE;
-
- /* Read in more data. */
- YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
- (yy_n_chars), num_to_read );
-
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
- }
-
- if ( (yy_n_chars) == 0 )
- {
- if ( number_to_move == YY_MORE_ADJ )
- {
- ret_val = EOB_ACT_END_OF_FILE;
- yyrestart( yyin );
- }
-
- else
- {
- ret_val = EOB_ACT_LAST_MATCH;
- YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
- YY_BUFFER_EOF_PENDING;
- }
- }
-
- else
- ret_val = EOB_ACT_CONTINUE_SCAN;
-
- if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
- /* Extend the array by 50%, plus the number we really need. */
- int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc(
- (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size );
- if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
- YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
- /* "- 2" to take care of EOB's */
- YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2);
- }
-
- (yy_n_chars) += number_to_move;
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
-
- (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
-
- return ret_val;
-}
-
-/* yy_get_previous_state - get the state just before the EOB char was reached */
-
- static yy_state_type yy_get_previous_state (void)
-{
- yy_state_type yy_current_state;
- char *yy_cp;
-
- yy_current_state = (yy_start);
-
- for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
- {
- YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
- if ( yy_accept[yy_current_state] )
- {
- (yy_last_accepting_state) = yy_current_state;
- (yy_last_accepting_cpos) = yy_cp;
- }
- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
- {
- yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 247 )
- yy_c = yy_meta[yy_c];
- }
- yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
- }
-
- return yy_current_state;
-}
-
-/* yy_try_NUL_trans - try to make a transition on the NUL character
- *
- * synopsis
- * next_state = yy_try_NUL_trans( current_state );
- */
- static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
-{
- int yy_is_jam;
- char *yy_cp = (yy_c_buf_p);
-
- YY_CHAR yy_c = 1;
- if ( yy_accept[yy_current_state] )
- {
- (yy_last_accepting_state) = yy_current_state;
- (yy_last_accepting_cpos) = yy_cp;
- }
- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
- {
- yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 247 )
- yy_c = yy_meta[yy_c];
- }
- yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
- yy_is_jam = (yy_current_state == 246);
-
- return yy_is_jam ? 0 : yy_current_state;
-}
-
-#ifndef YY_NO_UNPUT
-
- static void yyunput (int c, char * yy_bp )
-{
- char *yy_cp;
-
- yy_cp = (yy_c_buf_p);
-
- /* undo effects of setting up yytext */
- *yy_cp = (yy_hold_char);
-
- if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
- { /* need to shift things up to make room */
- /* +2 for EOB chars. */
- int number_to_move = (yy_n_chars) + 2;
- char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
- YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
- char *source =
- &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
-
- while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
- *--dest = *--source;
-
- yy_cp += (int) (dest - source);
- yy_bp += (int) (dest - source);
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
- (yy_n_chars) = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
-
- if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
- YY_FATAL_ERROR( "flex scanner push-back overflow" );
- }
-
- *--yy_cp = (char) c;
-
- (yytext_ptr) = yy_bp;
- (yy_hold_char) = *yy_cp;
- (yy_c_buf_p) = yy_cp;
-}
-
-#endif
-
-#ifndef YY_NO_INPUT
-#ifdef __cplusplus
- static int yyinput (void)
-#else
- static int input (void)
-#endif
-
-{
- int c;
-
- *(yy_c_buf_p) = (yy_hold_char);
-
- if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
- {
- /* yy_c_buf_p now points to the character we want to return.
- * If this occurs *before* the EOB characters, then it's a
- * valid NUL; if not, then we've hit the end of the buffer.
- */
- if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
- /* This was really a NUL. */
- *(yy_c_buf_p) = '\0';
-
- else
- { /* need more input */
- int offset = (int) ((yy_c_buf_p) - (yytext_ptr));
- ++(yy_c_buf_p);
-
- switch ( yy_get_next_buffer( ) )
- {
- case EOB_ACT_LAST_MATCH:
- /* This happens because yy_g_n_b()
- * sees that we've accumulated a
- * token and flags that we need to
- * try matching the token before
- * proceeding. But for input(),
- * there's no matching to consider.
- * So convert the EOB_ACT_LAST_MATCH
- * to EOB_ACT_END_OF_FILE.
- */
-
- /* Reset buffer status. */
- yyrestart( yyin );
-
- /*FALLTHROUGH*/
-
- case EOB_ACT_END_OF_FILE:
- {
- if ( yywrap( ) )
- return 0;
-
- if ( ! (yy_did_buffer_switch_on_eof) )
- YY_NEW_FILE;
-#ifdef __cplusplus
- return yyinput();
-#else
- return input();
-#endif
- }
-
- case EOB_ACT_CONTINUE_SCAN:
- (yy_c_buf_p) = (yytext_ptr) + offset;
- break;
- }
- }
- }
-
- c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
- *(yy_c_buf_p) = '\0'; /* preserve yytext */
- (yy_hold_char) = *++(yy_c_buf_p);
-
- return c;
-}
-#endif /* ifndef YY_NO_INPUT */
-
-/** Immediately switch to a different input stream.
- * @param input_file A readable stream.
- *
- * @note This function does not reset the start condition to @c INITIAL .
- */
- void yyrestart (FILE * input_file )
-{
-
- if ( ! YY_CURRENT_BUFFER ){
- yyensure_buffer_stack ();
- YY_CURRENT_BUFFER_LVALUE =
- yy_create_buffer( yyin, YY_BUF_SIZE );
- }
-
- yy_init_buffer( YY_CURRENT_BUFFER, input_file );
- yy_load_buffer_state( );
-}
-
-/** Switch to a different input buffer.
- * @param new_buffer The new input buffer.
- *
- */
- void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer )
-{
-
- /* TODO. We should be able to replace this entire function body
- * with
- * yypop_buffer_state();
- * yypush_buffer_state(new_buffer);
- */
- yyensure_buffer_stack ();
- if ( YY_CURRENT_BUFFER == new_buffer )
- return;
-
- if ( YY_CURRENT_BUFFER )
- {
- /* Flush out information for old buffer. */
- *(yy_c_buf_p) = (yy_hold_char);
- YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
- }
-
- YY_CURRENT_BUFFER_LVALUE = new_buffer;
- yy_load_buffer_state( );
-
- /* We don't actually know whether we did this switch during
- * EOF (yywrap()) processing, but the only time this flag
- * is looked at is after yywrap() is called, so it's safe
- * to go ahead and always set it.
- */
- (yy_did_buffer_switch_on_eof) = 1;
-}
-
-static void yy_load_buffer_state (void)
-{
- (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
- (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
- yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
- (yy_hold_char) = *(yy_c_buf_p);
-}
-
-/** Allocate and initialize an input buffer state.
- * @param file A readable stream.
- * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
- *
- * @return the allocated buffer state.
- */
- YY_BUFFER_STATE yy_create_buffer (FILE * file, int size )
-{
- YY_BUFFER_STATE b;
-
- b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) );
- if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
-
- b->yy_buf_size = size;
-
- /* yy_ch_buf has to be 2 characters longer than the size given because
- * we need to put in 2 end-of-buffer characters.
- */
- b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) );
- if ( ! b->yy_ch_buf )
- YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
-
- b->yy_is_our_buffer = 1;
-
- yy_init_buffer( b, file );
-
- return b;
-}
-
-/** Destroy the buffer.
- * @param b a buffer created with yy_create_buffer()
- *
- */
- void yy_delete_buffer (YY_BUFFER_STATE b )
-{
-
- if ( ! b )
- return;
-
- if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
- YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
-
- if ( b->yy_is_our_buffer )
- yyfree( (void *) b->yy_ch_buf );
-
- yyfree( (void *) b );
-}
-
-/* Initializes or reinitializes a buffer.
- * This function is sometimes called more than once on the same buffer,
- * such as during a yyrestart() or at EOF.
- */
- static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file )
-
-{
- int oerrno = errno;
-
- yy_flush_buffer( b );
-
- b->yy_input_file = file;
- b->yy_fill_buffer = 1;
-
- /* If b is the current buffer, then yy_init_buffer was _probably_
- * called from yyrestart() or through yy_get_next_buffer.
- * In that case, we don't want to reset the lineno or column.
- */
- if (b != YY_CURRENT_BUFFER){
- b->yy_bs_lineno = 1;
- b->yy_bs_column = 0;
- }
-
- b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
-
- errno = oerrno;
-}
-
-/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
- * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
- *
- */
- void yy_flush_buffer (YY_BUFFER_STATE b )
-{
- if ( ! b )
- return;
-
- b->yy_n_chars = 0;
-
- /* We always need two end-of-buffer characters. The first causes
- * a transition to the end-of-buffer state. The second causes
- * a jam in that state.
- */
- b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
- b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
-
- b->yy_buf_pos = &b->yy_ch_buf[0];
-
- b->yy_at_bol = 1;
- b->yy_buffer_status = YY_BUFFER_NEW;
-
- if ( b == YY_CURRENT_BUFFER )
- yy_load_buffer_state( );
-}
-
-/** Pushes the new state onto the stack. The new state becomes
- * the current state. This function will allocate the stack
- * if necessary.
- * @param new_buffer The new state.
- *
- */
-void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
-{
- if (new_buffer == NULL)
- return;
-
- yyensure_buffer_stack();
-
- /* This block is copied from yy_switch_to_buffer. */
- if ( YY_CURRENT_BUFFER )
- {
- /* Flush out information for old buffer. */
- *(yy_c_buf_p) = (yy_hold_char);
- YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
- }
-
- /* Only push if top exists. Otherwise, replace top. */
- if (YY_CURRENT_BUFFER)
- (yy_buffer_stack_top)++;
- YY_CURRENT_BUFFER_LVALUE = new_buffer;
-
- /* copied from yy_switch_to_buffer. */
- yy_load_buffer_state( );
- (yy_did_buffer_switch_on_eof) = 1;
-}
-
-/** Removes and deletes the top of the stack, if present.
- * The next element becomes the new top.
- *
- */
-void yypop_buffer_state (void)
-{
- if (!YY_CURRENT_BUFFER)
- return;
-
- yy_delete_buffer(YY_CURRENT_BUFFER );
- YY_CURRENT_BUFFER_LVALUE = NULL;
- if ((yy_buffer_stack_top) > 0)
- --(yy_buffer_stack_top);
-
- if (YY_CURRENT_BUFFER) {
- yy_load_buffer_state( );
- (yy_did_buffer_switch_on_eof) = 1;
- }
-}
-
-/* Allocates the stack if it does not exist.
- * Guarantees space for at least one push.
- */
-static void yyensure_buffer_stack (void)
-{
- yy_size_t num_to_alloc;
-
- if (!(yy_buffer_stack)) {
-
- /* First allocation is just for 2 elements, since we don't know if this
- * scanner will even need a stack. We use 2 instead of 1 to avoid an
- * immediate realloc on the next call.
- */
- num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
- (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
- (num_to_alloc * sizeof(struct yy_buffer_state*)
- );
- if ( ! (yy_buffer_stack) )
- YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
-
- memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-
- (yy_buffer_stack_max) = num_to_alloc;
- (yy_buffer_stack_top) = 0;
- return;
- }
-
- if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
-
- /* Increase the buffer to prepare for a possible push. */
- yy_size_t grow_size = 8 /* arbitrary grow size */;
-
- num_to_alloc = (yy_buffer_stack_max) + grow_size;
- (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
- ((yy_buffer_stack),
- num_to_alloc * sizeof(struct yy_buffer_state*)
- );
- if ( ! (yy_buffer_stack) )
- YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
-
- /* zero only the new slots.*/
- memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
- (yy_buffer_stack_max) = num_to_alloc;
- }
-}
-
-/** Setup the input buffer state to scan directly from a user-specified character buffer.
- * @param base the character buffer
- * @param size the size in bytes of the character buffer
- *
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
-{
- YY_BUFFER_STATE b;
-
- if ( size < 2 ||
- base[size-2] != YY_END_OF_BUFFER_CHAR ||
- base[size-1] != YY_END_OF_BUFFER_CHAR )
- /* They forgot to leave room for the EOB's. */
- return NULL;
-
- b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) );
- if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
-
- b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */
- b->yy_buf_pos = b->yy_ch_buf = base;
- b->yy_is_our_buffer = 0;
- b->yy_input_file = NULL;
- b->yy_n_chars = b->yy_buf_size;
- b->yy_is_interactive = 0;
- b->yy_at_bol = 1;
- b->yy_fill_buffer = 0;
- b->yy_buffer_status = YY_BUFFER_NEW;
-
- yy_switch_to_buffer( b );
-
- return b;
-}
-
-/** Setup the input buffer state to scan a string. The next call to yylex() will
- * scan from a @e copy of @a str.
- * @param yystr a NUL-terminated string to scan
- *
- * @return the newly allocated buffer state object.
- * @note If you want to scan bytes that may contain NUL values, then use
- * yy_scan_bytes() instead.
- */
-YY_BUFFER_STATE yy_scan_string (const char * yystr )
-{
-
- return yy_scan_bytes( yystr, (int) strlen(yystr) );
-}
-
-/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
- * scan from a @e copy of @a bytes.
- * @param yybytes the byte buffer to scan
- * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
- *
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len )
-{
- YY_BUFFER_STATE b;
- char *buf;
- yy_size_t n;
- int i;
-
- /* Get memory for full buffer, including space for trailing EOB's. */
- n = (yy_size_t) (_yybytes_len + 2);
- buf = (char *) yyalloc( n );
- if ( ! buf )
- YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
-
- for ( i = 0; i < _yybytes_len; ++i )
- buf[i] = yybytes[i];
-
- buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
-
- b = yy_scan_buffer( buf, n );
- if ( ! b )
- YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
-
- /* It's okay to grow etc. this buffer, and we should throw it
- * away when we're done.
- */
- b->yy_is_our_buffer = 1;
-
- return b;
-}
-
-#ifndef YY_EXIT_FAILURE
-#define YY_EXIT_FAILURE 2
-#endif
-
-static void yynoreturn yy_fatal_error (const char* msg )
-{
- fprintf( stderr, "%s\n", msg );
- exit( YY_EXIT_FAILURE );
-}
-
-/* Redefine yyless() so it works in section 3 code. */
-
-#undef yyless
-#define yyless(n) \
- do \
- { \
- /* Undo effects of setting up yytext. */ \
- int yyless_macro_arg = (n); \
- YY_LESS_LINENO(yyless_macro_arg);\
- yytext[yyleng] = (yy_hold_char); \
- (yy_c_buf_p) = yytext + yyless_macro_arg; \
- (yy_hold_char) = *(yy_c_buf_p); \
- *(yy_c_buf_p) = '\0'; \
- yyleng = yyless_macro_arg; \
- } \
- while ( 0 )
-
-/* Accessor methods (get/set functions) to struct members. */
-
-/** Get the current line number.
- *
- */
-int yyget_lineno (void)
-{
-
- return yylineno;
-}
-
-/** Get the input stream.
- *
- */
-FILE *yyget_in (void)
-{
- return yyin;
-}
-
-/** Get the output stream.
- *
- */
-FILE *yyget_out (void)
-{
- return yyout;
-}
-
-/** Get the length of the current token.
- *
- */
-int yyget_leng (void)
-{
- return yyleng;
-}
-
-/** Get the current token.
- *
- */
-
-char *yyget_text (void)
-{
- return yytext;
-}
-
-/** Set the current line number.
- * @param _line_number line number
- *
- */
-void yyset_lineno (int _line_number )
-{
-
- yylineno = _line_number;
-}
-
-/** Set the input stream. This does not discard the current
- * input buffer.
- * @param _in_str A readable stream.
- *
- * @see yy_switch_to_buffer
- */
-void yyset_in (FILE * _in_str )
-{
- yyin = _in_str ;
-}
-
-void yyset_out (FILE * _out_str )
-{
- yyout = _out_str ;
-}
-
-int yyget_debug (void)
-{
- return yy_flex_debug;
-}
-
-void yyset_debug (int _bdebug )
-{
- yy_flex_debug = _bdebug ;
-}
-
-static int yy_init_globals (void)
-{
- /* Initialization is the same as for the non-reentrant scanner.
- * This function is called from yylex_destroy(), so don't allocate here.
- */
-
- (yy_buffer_stack) = NULL;
- (yy_buffer_stack_top) = 0;
- (yy_buffer_stack_max) = 0;
- (yy_c_buf_p) = NULL;
- (yy_init) = 0;
- (yy_start) = 0;
-
-/* Defined in main.c */
-#ifdef YY_STDINIT
- yyin = stdin;
- yyout = stdout;
-#else
- yyin = NULL;
- yyout = NULL;
-#endif
-
- /* For future reference: Set errno on error, since we are called by
- * yylex_init()
- */
- return 0;
-}
-
-/* yylex_destroy is for both reentrant and non-reentrant scanners. */
-int yylex_destroy (void)
-{
-
- /* Pop the buffer stack, destroying each element. */
- while(YY_CURRENT_BUFFER){
- yy_delete_buffer( YY_CURRENT_BUFFER );
- YY_CURRENT_BUFFER_LVALUE = NULL;
- yypop_buffer_state();
- }
-
- /* Destroy the stack itself. */
- yyfree((yy_buffer_stack) );
- (yy_buffer_stack) = NULL;
-
- /* Reset the globals. This is important in a non-reentrant scanner so the next time
- * yylex() is called, initialization will occur. */
- yy_init_globals( );
-
- return 0;
-}
-
-/*
- * Internal utility routines.
- */
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char* s1, const char * s2, int n )
-{
-
- int i;
- for ( i = 0; i < n; ++i )
- s1[i] = s2[i];
-}
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (const char * s )
-{
- int n;
- for ( n = 0; s[n]; ++n )
- ;
-
- return n;
-}
-#endif
-
-void *yyalloc (yy_size_t size )
-{
- return malloc(size);
-}
-
-void *yyrealloc (void * ptr, yy_size_t size )
-{
-
- /* The cast to (char *) in the following accommodates both
- * implementations that use char* generic pointers, and those
- * that use void* generic pointers. It works with the latter
- * because both ANSI C and C++ allow castless assignment from
- * any pointer type to void*, and deal with argument conversions
- * as though doing an assignment.
- */
- return realloc(ptr, size);
-}
-
-void yyfree (void * ptr )
-{
- free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
-}
-
-#define YYTABLES_NAME "yytables"
-
-#line 74 "rust2html.flex"
-
-
-int yywrap() {
- return 1;
-}
-
-int main(int argc, const char* argv[]) {
- yyin = argc > 1 ? fopen(argv[1], "r") : stdin;
-
- puts(
- "<!DOCTYPE html>"
- "<html>"
- "<head>"
- " <style>"
- " .comment {"
- " color: gray;"
- " }"
- " .keyword {"
- " color: red;"
- " }"
- " .string {"
- " color: green;"
- " }"
- " .number {"
- " color: blue;"
- " }"
- " .symbol {"
- " font-weight: bold;"
- " }"
- " </style>"
- "</head>"
- "<body>"
- " <pre class=\"code\">"
- );
- yylex();
- puts(
- " </pre>"
- "</body>"
- "</html>");
-
- return 0;
-}
-
diff --git a/homework/81030/rust2html.flex b/homework/81030/rust2html.flex
deleted file mode 100644
index 6684d82..0000000
--- a/homework/81030/rust2html.flex
+++ /dev/null
@@ -1,115 +0,0 @@
-/* scanner for the Rust programming language */
-
-%{
-#define YY_NO_UNISTD_H
-%}
-
-NONEOL_CHAR [^\n]
-DEC_DIGIT 0|{NONZERO_DEC_DIGIT}
-NONZERO_DEC_DIGIT [1-9]
-OCT_DIGIT [0-7]
-HEX_DIGIT {DEC_DIGIT}|[a-fA-F]
-
-IDENTIFIER {IDENTIFIER_FIRST_CHAR}({DEC_DIGIT}|{IDENTIFIER_FIRST_CHAR})*
-IDENTIFIER_FIRST_CHAR [A-Za-z_]
-
-COMMENT {BLOCK_COMMENT}|{LINE_COMMENT}
-BLOCK_COMMENT "/*".*"*/"
-LINE_COMMENT "//"{NONEOL_CHAR}*
-
-KEYWORD _|abstract|alignof|as|become|box|break|const|continue|crate|do|else|enum|extern|false|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|offsetof|override|priv|proc|pub|pure|ref|return|Self|self|sizeof|static|struct|super|trait|true|type|typeof|unsafe|unsized|use|virtual|where|while|yield
-
-ESCAPE {COMMON_ESCAPE}|{UNICODE_ESCAPE}
-COMMON_ESCAPE \\|n|r|t|0|x{HEX_DIGIT}{2}
-UNICODE_ESCAPE "u{"{HEX_DIGIT}{6}"}"
-
-CHAR_LITERAL '{CHAR_BODY}'
-CHAR_BODY [^']|(\\('|{ESCAPE}))
-STRING_LITERAL \"{STRING_BODY}*\"
-STRING_BODY [^\"]|(\\(\"|{ESCAPE}))
-BYTE_CHAR_LITERAL b'{BYTE_CHAR_BODY}'
-BYTE_CHAR_BODY [^']|(\\('|{COMMON_ESCAPE}))
-BYTE_STRING_LITERAL b\"{BYTE_STRING_BODY}*\"
-BYTE_STRING_BODY [^\"]|(\\(\"|{ESCAPE}))
-
-NUMBER_LITERAL {NONZERO_DEC_DIGIT}{DEC_DIGIT}*{FLOAT_SUFFIX}?|(0{DEC_DIGIT_LITERAL}*{FLOAT_SUFFIX}?|b[10_]+|o{OCT_DIGIT_LITERAL}+|x{HEX_DIGIT_LITERAL}+)
-FLOAT_SUFFIX {EXPONENT}|"."{DEC_DIGIT_LITERAL}+{EXPONENT}?
-EXPONENT [Ee][-+]?{DEC_DIGIT_LITERAL}+
-DEC_DIGIT_LITERAL {DEC_DIGIT}|_
-HEX_DIGIT_LITERAL {HEX_DIGIT}|_
-OCT_DIGIT_LITERAL {OCT_DIGIT}|_
-
-SYMBOL "::"|"->"|"#"|"["|"]"|"("|")"|"{"|"}"|","|";"
-
-%%
-
-{SYMBOL} {
- printf("<span class=\"symbol\">%s</span>", yytext);
-}
-
-{KEYWORD} {
- printf("<span class=\"keyword\">%s</span>", yytext);
-}
-
-{NUMBER_LITERAL} {
- printf("<span class=\"number\">%s</span>", yytext);
-}
-
-{IDENTIFIER} {
- printf("<span class=\"identifier\">%s</span>", yytext);
-}
-
-{CHAR_LITERAL}|{STRING_LITERAL}|{BYTE_CHAR_LITERAL}|{BYTE_STRING_LITERAL} {
- printf("<span class=\"string\">%s</span>", yytext);
-}
-
-{COMMENT} {
- printf("<span class=\"comment\">%s</span>", yytext);
-}
-
-. {
- printf("%s", yytext); /* echo the rest */
-}
-
-%%
-
-int yywrap() {
- return 1;
-}
-
-int main(int argc, const char* argv[]) {
- yyin = argc > 1 ? fopen(argv[1], "r") : stdin;
-
- puts(
- "<!DOCTYPE html>"
- "<html>"
- "<head>"
- " <style>"
- " .comment {"
- " color: gray;"
- " }"
- " .keyword {"
- " color: red;"
- " }"
- " .string {"
- " color: green;"
- " }"
- " .number {"
- " color: blue;"
- " }"
- " .symbol {"
- " font-weight: bold;"
- " }"
- " </style>"
- "</head>"
- "<body>"
- " <pre class=\"code\">"
- );
- yylex();
- puts(
- " </pre>"
- "</body>"
- "</html>");
-
- return 0;
-}